source: git/factory/int_pp.cc @ 362fc67

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