source: git/factory/int_pp.cc @ a52291

jengelh-datetimespielwiese
Last change on this file since a52291 was a52291, checked in by Martin Lee <martinlee84@…>, 11 years ago
replacing MP_INT by mpz_t Conflicts: factory/cf_factory.h
  • Property mode set to 100644
File size: 9.7 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id$ */
3
4#include "config.h"
5
6#include "cf_assert.h"
7
8#include "cf_defs.h"
9#include "int_pp.h"
10#include "canonicalform.h"
11#include "cf_factory.h"
12#include "imm.h"
13
14mpz_t InternalPrimePower::primepow;
15mpz_t InternalPrimePower::primepowhalf;
16int InternalPrimePower::prime;
17int InternalPrimePower::exp;
18int InternalPrimePower::initialized = InternalPrimePower::initialize();
19
20
21InternalPrimePower::InternalPrimePower()
22{
23    mpz_init( thempi );
24}
25
26InternalPrimePower::InternalPrimePower( const int i )
27{
28    mpz_init_set_si( thempi, i );
29    if ( mpz_cmp_si( thempi, 0 ) < 0 ) {
30        mpz_neg( thempi, thempi );
31        mpz_mod( thempi, thempi, primepow );
32        mpz_sub( thempi, primepow, thempi );
33    }
34    else
35        mpz_mod( thempi, thempi, primepow );
36}
37
38InternalPrimePower::InternalPrimePower( const mpz_ptr mpi) { thempi[0]=*mpi;}
39
40InternalPrimePower::InternalPrimePower( const char * str, const int base )
41{
42    mpz_init_set_str( thempi, str, base );
43    if ( mpz_cmp_si( thempi, 0 ) < 0 ) {
44        mpz_neg( thempi, thempi );
45        mpz_mod( thempi, thempi, primepow );
46        mpz_sub( thempi, primepow, thempi );
47    }
48    else
49        mpz_mod( thempi, thempi, primepow );
50}
51
52InternalPrimePower::~InternalPrimePower()
53{
54    mpz_clear( thempi );
55}
56
57InternalCF* InternalPrimePower::deepCopyObject() const
58{
59    mpz_t dummy;
60    mpz_init_set( dummy, thempi );
61    return new InternalPrimePower( dummy );
62}
63
64InternalCF * InternalPrimePower::normalize_myself()
65{
66    ASSERT( getRefCount() == 1, "illegal operation" );
67    if ( mpz_cmp_si( thempi, 0 ) < 0 ) {
68        mpz_neg( thempi, thempi );
69        mpz_mod( thempi, thempi, primepow );
70        mpz_sub( thempi, primepow, thempi );
71    }
72    else
73        mpz_mod( thempi, thempi, primepow );
74    return this;
75}
76
77int InternalPrimePower::initialize()
78{
79    mpz_init_set_si( primepow, 3 );
80    mpz_init_set_si( primepowhalf, 1 );
81    prime = 3;
82    exp = 1;
83    return 1;
84}
85
86void
87InternalPrimePower::setPrimePower( int p, int k )
88{
89    ASSERT( p > 1 && k > 0, "illegal prime power" );
90    if ( p != prime || k != exp ) {
91        mpz_set_si( primepow, p );
92        mpz_pow_ui( primepow, primepow, (unsigned int)k );
93        mpz_fdiv_q_ui( primepowhalf, primepow, 2 );
94        prime = p;
95        exp = k;
96    }
97}
98
99int
100InternalPrimePower::getp()
101{
102    return prime;
103}
104
105int
106InternalPrimePower::getk()
107{
108    return exp;
109}
110
111#ifndef NOSTREAMIO
112void InternalPrimePower::print( OSTREAM & os, char * c )
113{
114    if ( *c == '*' && mpz_cmp_si( thempi, 1 ) == 0 )
115        os << c+1;
116    else if ( *c == '*' && mpz_cmp_si( thempi, -1 ) == 0 )
117        os << '-' << c+1;
118    else {
119        char * str = new char[mpz_sizeinbase( thempi, 10 ) + 2];
120        str = mpz_get_str( str, 10, thempi );
121        os << str << c;
122        delete [] str;
123    }
124}
125#endif /* NOSTREAMIO */
126
127//{{{ bool InternalPrimePower::isOne, isZero () const
128// docu: see CanonicalForm::isOne(), CanonicalForm::isZero()
129bool
130InternalPrimePower::isOne () const
131{
132    return mpz_cmp_ui( thempi, 1 ) == 0;
133}
134
135bool
136InternalPrimePower::isZero () const
137{
138    return mpz_sgn( thempi ) == 0;
139}
140//}}}
141
142bool InternalPrimePower::is_imm() const
143{
144    return false;
145}
146
147InternalCF* InternalPrimePower::genZero()
148{
149    if ( isZero() )
150        return copyObject();
151    else
152        return new InternalPrimePower();
153}
154
155InternalCF* InternalPrimePower::genOne()
156{
157    if ( isOne() )
158        return copyObject();
159    else
160        return new InternalPrimePower();
161}
162
163//{{{ InternalCF * InternalPrimePower::neg ()
164// docu: see CanonicalForm::operator -()
165InternalCF *
166InternalPrimePower::neg ()
167{
168    if ( getRefCount() > 1 ) {
169        decRefCount();
170        mpz_t dummy;
171        mpz_init( dummy );
172        mpz_sub( dummy, primepow, thempi );
173        return new InternalPrimePower( dummy );
174    } else {
175        mpz_sub( thempi, primepow, thempi );
176        return this;
177    }
178}
179//}}}
180
181
182InternalCF* InternalPrimePower::addsame( InternalCF * c )
183{
184    if ( getRefCount() > 1 ) {
185        decRefCount();
186        mpz_t dummy;
187        mpz_init( dummy );
188        mpz_add( dummy, thempi, MPI( c ) );
189        if ( mpz_cmp( dummy, primepow ) >= 0 )
190            mpz_sub( dummy, dummy, primepow );
191        return new InternalPrimePower( dummy );
192    }
193    else {
194        mpz_add( thempi, thempi, MPI( c ) );
195        if ( mpz_cmp( thempi, primepow ) >= 0 )
196            mpz_sub( thempi, thempi, primepow );
197        return this;
198    }
199}
200
201InternalCF* InternalPrimePower::subsame( InternalCF * c )
202{
203    if ( getRefCount() > 1 ) {
204        decRefCount();
205        mpz_t dummy;
206        mpz_init( dummy );
207        mpz_sub( dummy, thempi, MPI( c ) );
208        if ( mpz_cmp_si( dummy, 0 ) < 0 )
209            mpz_add( dummy, dummy, primepow );
210        return new InternalPrimePower( dummy );
211    }
212    else {
213        mpz_sub( thempi, thempi, MPI( c ) );
214        if ( mpz_cmp_si( thempi, 0 ) < 0 )
215            mpz_add( thempi, thempi, primepow );
216        return this;
217    }
218}
219
220InternalCF* InternalPrimePower::mulsame( InternalCF * c )
221{
222    if ( getRefCount() > 1 ) {
223        decRefCount();
224        mpz_t dummy;
225        mpz_init( dummy );
226        mpz_mul( dummy, thempi, MPI( c ) );
227        mpz_mod( dummy, dummy, primepow );
228        return new InternalPrimePower( dummy );
229    }
230    else {
231        mpz_mul( thempi, thempi, MPI( c ) );
232        mpz_mod( thempi, thempi, primepow );
233        return this;
234    }
235}
236
237InternalCF* InternalPrimePower::dividesame( InternalCF * c )
238{
239    return divsame( c );
240}
241
242InternalCF* InternalPrimePower::divsame( InternalCF * c )
243{
244    if ( c == this ) {
245        if ( deleteObject() ) delete this;
246        return CFFactory::basic( 1 );
247    }
248    if ( getRefCount() > 1 ) {
249        decRefCount();
250        mpz_t dummy, a, b;
251        mpz_init( dummy ); mpz_init( a ); mpz_init( b );
252        mpz_gcdext( dummy, a, b, primepow, MPI( c ) );
253        ASSERT( mpz_cmp_si( dummy, 1 ) == 0, "illegal inversion" );
254        mpz_clear( dummy ); mpz_clear( a );
255        if ( mpz_cmp_si( b, 0 ) < 0 )
256            mpz_add( b, b, primepow );
257        mpz_mul( b, b, thempi );
258        mpz_mod( b, b, primepow );
259        return new InternalPrimePower( b );
260    }
261    else {
262        mpz_t dummy, a, b;
263        mpz_init( dummy ); mpz_init( a ); mpz_init( b );
264        mpz_gcdext( dummy, a, b, primepow, MPI( c ) );
265        ASSERT( mpz_cmp_si( dummy, 1 ) == 0, "illegal inversion" );
266        if ( mpz_cmp_si( b, 0 ) < 0 )
267            mpz_add( b, b, primepow );
268        mpz_mul( thempi, b, thempi );
269        mpz_mod( thempi, thempi, primepow );
270        mpz_clear( dummy ); mpz_clear( a ); mpz_clear( b );
271        return this;
272    }
273}
274
275InternalCF *
276InternalPrimePower::modulosame ( InternalCF * )
277{
278    if ( deleteObject() ) delete this;
279    return CFFactory::basic( 0 );
280}
281
282InternalCF *
283InternalPrimePower::modsame ( InternalCF * )
284{
285    if ( deleteObject() ) delete this;
286    return CFFactory::basic( 0 );
287}
288
289void
290InternalPrimePower::divremsame ( InternalCF * c, InternalCF * & quot, InternalCF * & rem )
291{
292    if ( c == this ) {
293        quot = CFFactory::basic( 1 );
294        rem = CFFactory::basic( 0 );
295    }
296    else {
297        mpz_t dummy, a, b;
298        mpz_init( dummy ); mpz_init( a ); mpz_init( b );
299        mpz_gcdext( dummy, a, b, primepow, MPI( c ) );
300        ASSERT( mpz_cmp_si( dummy, 1 ) == 0, "illegal inversion" );
301        mpz_clear( dummy ); mpz_clear( a );
302        if ( mpz_cmp_si( b, 0 ) < 0 )
303            mpz_add( b, b, primepow );
304        mpz_mul( b, b, thempi );
305        mpz_mod( b, b, primepow );
306        quot = new InternalPrimePower( b );
307        rem = CFFactory::basic( 0 );
308    }
309}
310
311bool
312InternalPrimePower::divremsamet ( InternalCF * c, InternalCF * & quot, InternalCF * & rem )
313{
314    divremsame( c, quot, rem );
315    return true;
316}
317
318//{{{ int InternalPrimePower::comparesame, comparecoeff ( InternalCF * c )
319// docu: see CanonicalForm::operator <(), CanonicalForm::operator ==()
320int
321InternalPrimePower::comparesame ( InternalCF * c )
322{
323    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == PrimePowerDomain, "incompatible base coefficients" );
324    return mpz_cmp( thempi, MPI( c ) );
325}
326
327int
328InternalPrimePower::comparecoeff ( InternalCF * )
329{
330    ASSERT1( 0, "comparecoeff() not implemented for class %s", this->classname() );
331    return 0;
332}
333//}}}
334
335InternalCF *
336InternalPrimePower::addcoeff ( InternalCF * )
337{
338    ASSERT( 0, "this function should never be called" );
339    return this;
340}
341
342InternalCF *
343InternalPrimePower::subcoeff ( InternalCF *, bool )
344{
345    ASSERT( 0, "this function should never be called" );
346    return this;
347}
348
349InternalCF *
350InternalPrimePower::mulcoeff ( InternalCF * )
351{
352    ASSERT( 0, "this function should never be called" );
353    return this;
354}
355
356InternalCF *
357InternalPrimePower::dividecoeff ( InternalCF *, bool )
358{
359    ASSERT( 0, "this function should never be called" );
360    return this;
361}
362
363InternalCF *
364InternalPrimePower::divcoeff ( InternalCF *, bool )
365{
366    ASSERT( 0, "this function should never be called" );
367    return this;
368}
369
370InternalCF *
371InternalPrimePower::modcoeff ( InternalCF *, bool )
372{
373    ASSERT( 0, "this function should never be called" );
374    return this;
375}
376
377InternalCF *
378InternalPrimePower::modulocoeff ( InternalCF *, bool )
379{
380    ASSERT( 0, "this function should never be called" );
381    return this;
382}
383
384void
385InternalPrimePower::divremcoeff ( InternalCF *, InternalCF * &, InternalCF * &, bool )
386{
387    ASSERT( 0, "this function should never be called" );
388}
389
390bool
391InternalPrimePower::divremcoefft ( InternalCF *, InternalCF * &, InternalCF * &, bool )
392{
393    ASSERT( 0, "this function should never be called" );
394    return true;
395}
396
397int
398InternalPrimePower::intval () const
399{
400  return (int)mpz_get_si( thempi );
401}
402
403int
404InternalPrimePower::intmod( int p ) const
405{
406  return (int)mpz_fdiv_ui( thempi, (unsigned long)p );
407}
408
409//{{{ int InternalPrimePower::sign () const
410// docu: see CanonicalForm::sign()
411int
412InternalPrimePower::sign () const
413{
414    return mpz_sgn( thempi );
415}
416//}}}
Note: See TracBrowser for help on using the repository browser.