source: git/factory/int_pp.cc @ ba5e9e

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