source: git/factory/int_pp.cc @ a8fbae

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