source: git/factory/int_pp.cc @ bf6475e

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