source: git/factory/int_pp.cc @ cbb753

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