source: git/factory/int_pp.cc @ c770dc

spielwiese
Last change on this file since c770dc was e4fe2b, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
FIX: Fixed huge BUG in cf_gmp.h CHG: starting to cleanup factory
  • Property mode set to 100644
File size: 9.9 KB
RevLine 
[493c477]1/* emacs edit mode for this file is -*- C++ -*- */
[341696]2/* $Id$ */
[2dd068]3
[e4fe2b]4#include "config.h"
[e3c305]5
[650f2d8]6#include "cf_assert.h"
[718e670]7
[2dd068]8#include "cf_defs.h"
9#include "int_pp.h"
10#include "canonicalform.h"
11#include "cf_factory.h"
[bf6475e]12#include "imm.h"
[2dd068]13
14MP_INT InternalPrimePower::primepow;
15MP_INT 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 ) {
[806c18]30        mpz_neg( &thempi, &thempi );
31        mpz_mod( &thempi, &thempi, &primepow );
32        mpz_sub( &thempi, &primepow, &thempi );
[2dd068]33    }
34    else
[806c18]35        mpz_mod( &thempi, &thempi, &primepow );
[2dd068]36}
37
38InternalPrimePower::InternalPrimePower( const MP_INT & mpi ) : thempi( mpi ) {}
39
[d07137]40InternalPrimePower::InternalPrimePower( const char * str, const int base )
[2dd068]41{
[d07137]42    mpz_init_set_str( &thempi, str, base );
[2dd068]43    if ( mpz_cmp_si( &thempi, 0 ) < 0 ) {
[806c18]44        mpz_neg( &thempi, &thempi );
45        mpz_mod( &thempi, &thempi, &primepow );
46        mpz_sub( &thempi, &primepow, &thempi );
[2dd068]47    }
48    else
[806c18]49        mpz_mod( &thempi, &thempi, &primepow );
[2dd068]50}
51
52InternalPrimePower::~InternalPrimePower()
53{
54    mpz_clear( &thempi );
55}
56
57InternalCF* InternalPrimePower::deepCopyObject() const
58{
59    MP_INT 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 ) {
[806c18]68        mpz_neg( &thempi, &thempi );
69        mpz_mod( &thempi, &thempi, &primepow );
70        mpz_sub( &thempi, &primepow, &thempi );
[2dd068]71    }
72    else
[806c18]73        mpz_mod( &thempi, &thempi, &primepow );
[2dd068]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 ) {
[806c18]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;
[2dd068]96    }
97}
98
99int
100InternalPrimePower::getp()
101{
102    return prime;
103}
104
105int
106InternalPrimePower::getk()
107{
108    return exp;
109}
110
[718e670]111#ifndef NOSTREAMIO
[181148]112void InternalPrimePower::print( OSTREAM & os, char * c )
[2dd068]113{
114    if ( *c == '*' && mpz_cmp_si( &thempi, 1 ) == 0 )
[806c18]115        os << c+1;
[2dd068]116    else if ( *c == '*' && mpz_cmp_si( &thempi, -1 ) == 0 )
[806c18]117        os << '-' << c+1;
[2dd068]118    else {
[806c18]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;
[2dd068]123    }
124}
[718e670]125#endif /* NOSTREAMIO */
[2dd068]126
[9442dc]127//{{{ bool InternalPrimePower::isOne, isZero () const
128// docu: see CanonicalForm::isOne(), CanonicalForm::isZero()
129bool
130InternalPrimePower::isOne () const
[2dd068]131{
[9442dc]132    return mpz_cmp_ui( &thempi, 1 ) == 0;
[2dd068]133}
134
[9442dc]135bool
136InternalPrimePower::isZero () const
[2dd068]137{
[9442dc]138    return mpz_sgn( &thempi ) == 0;
[2dd068]139}
[9442dc]140//}}}
[2dd068]141
142bool InternalPrimePower::is_imm() const
143{
144    return false;
145}
146
147InternalCF* InternalPrimePower::genZero()
148{
149    if ( isZero() )
[806c18]150        return copyObject();
[2dd068]151    else
[806c18]152        return new InternalPrimePower();
[2dd068]153}
154
155InternalCF* InternalPrimePower::genOne()
156{
157    if ( isOne() )
[806c18]158        return copyObject();
[2dd068]159    else
[806c18]160        return new InternalPrimePower();
[2dd068]161}
162
[9442dc]163//{{{ InternalCF * InternalPrimePower::neg ()
164// docu: see CanonicalForm::operator -()
165InternalCF *
166InternalPrimePower::neg ()
[2dd068]167{
168    if ( getRefCount() > 1 ) {
[806c18]169        decRefCount();
170        MP_INT dummy;
171        mpz_init( &dummy );
172        mpz_sub( &dummy, &primepow, &thempi );
173        return new InternalPrimePower( dummy );
[9442dc]174    } else {
[806c18]175        mpz_sub( &thempi, &primepow, &thempi );
176        return this;
[2dd068]177    }
178}
[9442dc]179//}}}
[2dd068]180
181
182InternalCF* InternalPrimePower::addsame( InternalCF * c )
183{
184    if ( getRefCount() > 1 ) {
[806c18]185        decRefCount();
186        MP_INT 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 );
[2dd068]192    }
193    else {
[806c18]194        mpz_add( &thempi, &thempi, &MPI( c ) );
195        if ( mpz_cmp( &thempi, &primepow ) >= 0 )
196            mpz_sub( &thempi, &thempi, &primepow );
197        return this;
[2dd068]198    }
199}
200
201InternalCF* InternalPrimePower::subsame( InternalCF * c )
202{
203    if ( getRefCount() > 1 ) {
[806c18]204        decRefCount();
205        MP_INT 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 );
[2dd068]211    }
212    else {
[806c18]213        mpz_sub( &thempi, &thempi, &MPI( c ) );
214        if ( mpz_cmp_si( &thempi, 0 ) < 0 )
215            mpz_add( &thempi, &thempi, &primepow );
216        return this;
[2dd068]217    }
218}
219
220InternalCF* InternalPrimePower::mulsame( InternalCF * c )
221{
222    if ( getRefCount() > 1 ) {
[806c18]223        decRefCount();
224        MP_INT dummy;
225        mpz_init( &dummy );
226        mpz_mul( &dummy, &thempi, &MPI( c ) );
227        mpz_mod( &dummy, &dummy, &primepow );
228        return new InternalPrimePower( dummy );
[2dd068]229    }
230    else {
[806c18]231        mpz_mul( &thempi, &thempi, &MPI( c ) );
232        mpz_mod( &thempi, &thempi, &primepow );
233        return this;
[2dd068]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 ) {
[806c18]245        if ( deleteObject() ) delete this;
246        return CFFactory::basic( 1 );
[2dd068]247    }
248    if ( getRefCount() > 1 ) {
[806c18]249        decRefCount();
250        MP_INT 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 );
[2dd068]260    }
261    else {
[806c18]262        MP_INT 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;
[2dd068]272    }
273}
274
[929cf9]275InternalCF *
276InternalPrimePower::modulosame ( InternalCF * )
[2dd068]277{
278    if ( deleteObject() ) delete this;
279    return CFFactory::basic( 0 );
280}
281
[929cf9]282InternalCF *
283InternalPrimePower::modsame ( InternalCF * )
[2dd068]284{
285    if ( deleteObject() ) delete this;
286    return CFFactory::basic( 0 );
287}
288
[929cf9]289void
290InternalPrimePower::divremsame ( InternalCF * c, InternalCF * & quot, InternalCF * & rem )
[2dd068]291{
292    if ( c == this ) {
[806c18]293        quot = CFFactory::basic( 1 );
294        rem = CFFactory::basic( 0 );
[2dd068]295    }
296    else {
[806c18]297        MP_INT 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 );
[2dd068]308    }
309}
310
[929cf9]311bool
312InternalPrimePower::divremsamet ( InternalCF * c, InternalCF * & quot, InternalCF * & rem )
[2dd068]313{
314    divremsame( c, quot, rem );
315    return true;
316}
317
[bf6475e]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
[929cf9]327int
328InternalPrimePower::comparecoeff ( InternalCF * )
[2dd068]329{
[a9d523]330    ASSERT1( 0, "comparecoeff() not implemented for class %s", this->classname() );
[2dd068]331    return 0;
332}
[bf6475e]333//}}}
[2dd068]334
[929cf9]335InternalCF *
336InternalPrimePower::addcoeff ( InternalCF * )
[2dd068]337{
338    ASSERT( 0, "this function should never be called" );
339    return this;
340}
341
[929cf9]342InternalCF *
343InternalPrimePower::subcoeff ( InternalCF *, bool )
[2dd068]344{
345    ASSERT( 0, "this function should never be called" );
346    return this;
347}
348
[929cf9]349InternalCF *
350InternalPrimePower::mulcoeff ( InternalCF * )
[2dd068]351{
352    ASSERT( 0, "this function should never be called" );
353    return this;
354}
355
[929cf9]356InternalCF *
357InternalPrimePower::dividecoeff ( InternalCF *, bool )
[2dd068]358{
359    ASSERT( 0, "this function should never be called" );
360    return this;
361}
362
[929cf9]363InternalCF *
364InternalPrimePower::divcoeff ( InternalCF *, bool )
[2dd068]365{
366    ASSERT( 0, "this function should never be called" );
367    return this;
368}
369
[929cf9]370InternalCF *
371InternalPrimePower::modcoeff ( InternalCF *, bool )
[2dd068]372{
373    ASSERT( 0, "this function should never be called" );
374    return this;
375}
376
[929cf9]377InternalCF *
378InternalPrimePower::modulocoeff ( InternalCF *, bool )
[2dd068]379{
380    ASSERT( 0, "this function should never be called" );
381    return this;
382}
383
[929cf9]384void
385InternalPrimePower::divremcoeff ( InternalCF *, InternalCF * &, InternalCF * &, bool )
[2dd068]386{
387    ASSERT( 0, "this function should never be called" );
388}
389
[929cf9]390bool
391InternalPrimePower::divremcoefft ( InternalCF *, InternalCF * &, InternalCF * &, bool )
[2dd068]392{
393    ASSERT( 0, "this function should never be called" );
394    return true;
395}
396
[929cf9]397int
398InternalPrimePower::intval () const
[2dd068]399{
400  return (int)mpz_get_si( &thempi );
401}
402
[929cf9]403int
404InternalPrimePower::intmod( int p ) const
[2dd068]405{
[cacfb6]406  return (int)mpz_fdiv_ui( &thempi, (unsigned long)p );
[2dd068]407}
408
[05ac04]409//{{{ int InternalPrimePower::sign () const
410// docu: see CanonicalForm::sign()
411int
412InternalPrimePower::sign () const
[2dd068]413{
[05ac04]414    return mpz_sgn( &thempi );
[2dd068]415}
[05ac04]416//}}}
Note: See TracBrowser for help on using the repository browser.