source: git/factory/canonicalform.cc @ 06d4ff

fieker-DuValspielwiese
Last change on this file since 06d4ff was b05571d, checked in by Jens Schmidt <schmidt@…>, 27 years ago
* canonicalform.cc (initCanonicalForm, mmInit): initialize memory managment if compiled with Singular. Declaration of mmInit() added. git-svn-id: file:///usr/local/Singular/svn/trunk@471 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 31.2 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: canonicalform.cc,v 1.8 1997-07-01 12:48:00 schmidt Exp $ */
3
4#include <config.h>
5
6#include "assert.h"
7
8#include "cf_defs.h"
9#include "cf_globals.h"
10#include "canonicalform.h"
11#include "cf_iter.h"
12#include "int_cf.h"
13#include "cf_factory.h"
14#include "imm.h"
15#include "gfops.h"
16#include "cf_binom.h"
17#if defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)
18#include "memman.h"
19#endif
20
21#ifndef NOSTREAMIO
22CanonicalForm readCF( istream& );
23#endif /* NOSTREAMIO */
24
25CanonicalForm::CanonicalForm() : value( CFFactory::basic( (int)0 ) )
26{
27}
28
29CanonicalForm::CanonicalForm( const int i ) : value( CFFactory::basic( i ) )
30{
31}
32
33CanonicalForm::CanonicalForm( const CanonicalForm & cf ) : value( is_imm( cf.value ) ? cf.value : cf.value->copyObject() )
34{
35}
36
37CanonicalForm::CanonicalForm( InternalCF * cf ) : value( cf )
38{
39}
40
41CanonicalForm::CanonicalForm( const Variable & v ) : value( CFFactory::poly( v ) )
42{
43}
44
45CanonicalForm::CanonicalForm( const Variable & v, int e ) : value( CFFactory::poly( v, e ) )
46{
47}
48
49CanonicalForm::CanonicalForm( const char * str ) : value( CFFactory::basic( str ) )
50{
51}
52
53CanonicalForm::~CanonicalForm()
54{
55    if ( (! is_imm( value )) && value->deleteObject() )
56        delete value;
57}
58
59InternalCF*
60CanonicalForm::getval() const
61{
62    if ( is_imm( value ) )
63        return value;
64    else
65        return value->copyObject();
66}
67
68bool
69CanonicalForm::isOne() const
70{
71    if ( is_imm( value ) == FFMARK )
72        return imm_isone_p( value );
73    else  if ( is_imm( value ) == GFMARK )
74        return imm_isone_gf( value );
75    else  if ( is_imm( value ) )
76        return imm_isone( value );
77    else
78        return value->isOne();
79}
80
81bool
82CanonicalForm::isZero() const
83{
84    if ( is_imm( value ) == FFMARK )
85        return imm_iszero_p( value );
86    else  if ( is_imm( value ) == GFMARK )
87        return imm_iszero_gf( value );
88    else  if ( is_imm( value ) )
89        return imm_iszero( value );
90    else
91        return value->isZero();
92}
93
94bool
95CanonicalForm::isImm() const
96{
97    return is_imm( value );
98}
99
100bool
101CanonicalForm::inZ() const
102{
103    if ( is_imm( value ) == INTMARK )
104        return true;
105    else if ( is_imm( value ) )
106        return false;
107    else
108        return value->levelcoeff() == IntegerDomain;
109}
110
111bool
112CanonicalForm::inQ() const
113{
114    if ( is_imm( value ) == INTMARK )
115        return true;
116    else if ( is_imm( value ) )
117        return false;
118    else
119        return value->levelcoeff() == IntegerDomain ||
120            value->levelcoeff() == RationalDomain;
121}
122
123bool
124CanonicalForm::inFF() const
125{
126    return is_imm( value ) == FFMARK;
127}
128
129bool
130CanonicalForm::inGF() const
131{
132    return is_imm( value ) == GFMARK;
133}
134
135bool
136CanonicalForm::inPP() const
137{
138    return ! is_imm( value ) && ( value->levelcoeff() == PrimePowerDomain );
139}
140
141bool
142CanonicalForm::inBaseDomain() const
143{
144    if ( is_imm( value ) )
145        return true;
146    else
147        return value->inBaseDomain();
148}
149
150bool
151CanonicalForm::inExtension() const
152{
153    if ( is_imm( value ) )
154        return false;
155    else
156        return value->inExtension();
157}
158
159bool
160CanonicalForm::inCoeffDomain() const
161{
162    if ( is_imm( value ) )
163        return true;
164    else
165        return value->inCoeffDomain();
166}
167
168bool
169CanonicalForm::inPolyDomain() const
170{
171    if ( is_imm( value ) )
172        return false;
173    else
174        return value->inPolyDomain();
175}
176
177bool
178CanonicalForm::inQuotDomain() const
179{
180    if ( is_imm( value ) )
181        return false;
182    else
183        return value->inQuotDomain();
184}
185
186int
187CanonicalForm::intval() const
188{
189    if ( is_imm( value ) )
190        return imm_intval( value );
191    else
192        return value->intval();
193}
194
195CanonicalForm
196CanonicalForm::lc() const
197{
198    if ( is_imm( value ) )
199        return *this;
200    else
201        return value->lc();
202}
203
204CanonicalForm
205CanonicalForm::LC() const
206{
207    if ( inBaseDomain() )
208        return *this;
209    else
210        return value->LC();
211}
212
213CanonicalForm
214CanonicalForm::LC( const Variable & v ) const
215{
216    if ( inBaseDomain() )
217        return *this;
218    else  if ( v == mvar() )
219        return value->LC();
220    else {
221        CanonicalForm f = swapvar( *this, v, mvar() );
222        if ( f.mvar() == mvar() )
223            return swapvar( f.value->LC(), v, mvar() );
224        else
225            return *this;
226    }
227}
228
229int
230CanonicalForm::degree() const
231{
232    if ( isZero() )
233        return -1;
234    else  if ( is_imm( value ) )
235        return 0;
236    else
237        return value->degree();
238}
239
240int
241CanonicalForm::degree( const Variable & v ) const
242{
243    if ( isZero() )
244        return -1;
245    else  if ( is_imm( value ) )
246        return 0;
247    else  if ( inBaseDomain() )
248        return 0;
249    else  if ( v == mvar() )
250        return value->degree();
251    else  if ( v > mvar() )
252        return 0;
253    else {
254        CanonicalForm f = swapvar( *this, v, mvar() );
255        if ( f.mvar() == mvar() )
256            return f.value->degree();
257        else
258            return 0;
259    }
260}
261
262int
263CanonicalForm::taildegree() const
264{
265    if ( isZero() )
266        return -1;
267    else  if ( is_imm( value ) )
268        return 0;
269    else
270        return value->taildegree();
271}
272
273CanonicalForm
274CanonicalForm::tailcoeff() const
275{
276    if ( inCoeffDomain() )
277        return *this;
278    else
279        return value->tailcoeff();
280}
281
282int
283CanonicalForm::level() const
284{
285    if ( is_imm( value ) )
286        return LEVELBASE;
287    else
288        return value->level();
289}
290
291Variable
292CanonicalForm::mvar() const
293{
294    if ( is_imm( value ) || value->inBaseDomain() )
295        return Variable();
296    else
297        return value->variable();
298}
299
300CanonicalForm
301CanonicalForm::num() const
302{
303    if ( is_imm( value ) )
304        return *this;
305    else
306        return CanonicalForm( value->num() );
307}
308
309CanonicalForm
310CanonicalForm::den() const
311{
312    if ( is_imm( value ) )
313        return 1;
314    else
315        return CanonicalForm( value->den() );
316}
317
318CanonicalForm
319CanonicalForm::deepCopy() const
320{
321    if ( is_imm( value ) )
322        return *this;
323    else
324        return CanonicalForm( value->deepCopyObject() );
325}
326
327CanonicalForm
328CanonicalForm::gcd( const CanonicalForm & ) const
329{
330//    return ::gcd( *this, f );
331    return 1;
332}
333
334CanonicalForm
335CanonicalForm::deriv() const
336{
337    if ( inCoeffDomain() )
338        return 0;
339    else {
340        CanonicalForm res = 0;
341        Variable x = mvar();
342        for ( CFIterator i = *this; i.hasTerms(); i++ )
343            if ( i.exp() > 0 )
344                res += power( x, i.exp()-1 ) * i.coeff() * i.exp();
345        return res;
346    }
347}
348
349CanonicalForm
350CanonicalForm::deriv( const Variable & x ) const
351{
352    if ( inCoeffDomain() )
353        return 0;
354    else {
355        CanonicalForm res = 0;
356        Variable y = mvar();
357        for ( CFIterator i = (y==x) ? *this : swapvar( *this, x, y ); i.hasTerms(); i++ )
358            if ( i.exp() > 0 )
359                res += power( y, i.exp()-1 ) * i.coeff() * i.exp();
360        return (y==x) ? res : swapvar( res, x, y );
361    }
362}
363
364CanonicalForm
365CanonicalForm::genCoeff( int type, int i )
366{
367    return CanonicalForm( CFFactory::basic( type, i ) );
368}
369
370CanonicalForm
371CanonicalForm::genZero() const
372{
373    int what = is_imm( value );
374    if ( what == FFMARK )
375        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0 ) );
376    else  if ( what == GFMARK )
377        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0 ) );
378    else  if ( what )
379        return CanonicalForm( CFFactory::basic( IntegerDomain, 0 ) );
380    else
381        return CanonicalForm( value->genZero() );
382}
383
384CanonicalForm
385CanonicalForm::genOne() const
386{
387    int what = is_imm( value );
388    if ( what == FFMARK )
389        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1 ) );
390    else  if ( what == GFMARK )
391        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1 ) );
392    else  if ( what )
393        return CanonicalForm( CFFactory::basic( IntegerDomain, 1 ) );
394    else
395        return CanonicalForm( value->genOne() );
396}
397
398bool
399CanonicalForm::isUnivariate() const
400{
401    if ( is_imm( value ) )
402        return false;
403    else
404        return value->isUnivariate();
405}
406
407#ifndef NOSTREAMIO
408void
409CanonicalForm::print( ostream & os, char * str ) const
410{
411    if ( is_imm( value ) )
412        imm_print( os, value, str );
413    else
414        value->print( os, str );
415}
416#endif /* NOSTREAMIO */
417
418bool
419operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
420{
421    int what = is_imm( lhs.value );
422    if ( what )
423        if ( what == is_imm( rhs.value ) )
424            return lhs.value == rhs.value;
425        else
426            return false;
427    else  if ( is_imm( rhs.value ) )
428        return false;
429    else  if ( lhs.level() == rhs.level() )
430        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
431            return lhs.value->comparesame( rhs.value ) == 0;
432        else
433            return rhs.value->comparesame( lhs.value ) == 0;
434    else
435        return false;
436}
437
438bool
439operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
440{
441    int what = is_imm( lhs.value );
442    if ( what )
443        if ( what == is_imm( rhs.value ) )
444            return lhs.value != rhs.value;
445        else
446            return true;
447    else  if ( is_imm( rhs.value ) )
448        return true;
449    else  if ( lhs.level() == rhs.level() )
450        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
451            return lhs.value->comparesame( rhs.value ) != 0;
452        else
453            return rhs.value->comparesame( lhs.value ) != 0;
454    else
455        return true;
456}
457
458bool
459operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
460{
461    int what = is_imm( lhs.value );
462    if ( what ) {
463        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
464        if ( what == INTMARK ) {
465            if ( what == is_imm( rhs.value ) )
466                return imm_cmp( lhs.value, rhs.value ) > 0;
467            else
468                return rhs.value->comparecoeff( lhs.value ) < 0;
469        }
470        else  if ( what == FFMARK ) {
471            if ( what == is_imm( rhs.value ) )
472                return imm_cmp_p( lhs.value, rhs.value ) > 0;
473            else
474                return rhs.value->comparecoeff( lhs.value ) < 0;
475        }
476        else {
477            if ( what == is_imm( rhs.value ) )
478                return imm_cmp_gf( lhs.value, rhs.value ) > 0;
479            else
480                return rhs.value->comparecoeff( lhs.value ) < 0;
481        }
482    }
483    else  if ( is_imm( rhs.value ) )
484        return lhs.value->comparecoeff( rhs.value ) > 0;
485    else  if ( lhs.level() == rhs.level() )
486        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
487            return lhs.value->comparesame( rhs.value ) > 0;
488        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
489            return lhs.value->comparecoeff( lhs.value ) > 0;
490        else
491            return rhs.value->comparecoeff( lhs.value ) < 0;
492    else
493        return lhs.value->level() > rhs.value->level();
494}
495
496bool
497operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
498{
499    int what = is_imm( lhs.value );
500    if ( what ) {
501        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
502        if ( what == INTMARK ) {
503            if ( what == is_imm( rhs.value ) )
504                return imm_cmp( lhs.value, rhs.value ) < 0;
505            else
506                return rhs.value->comparecoeff( lhs.value ) > 0;
507        }
508        else  if ( what == FFMARK ) {
509            if ( what == is_imm( rhs.value ) )
510                return imm_cmp( lhs.value, rhs.value ) < 0;
511            else
512                return rhs.value->comparecoeff( lhs.value ) > 0;
513        }
514        else {
515            if ( what == is_imm( rhs.value ) )
516                return imm_cmp( lhs.value, rhs.value ) < 0;
517            else
518                return rhs.value->comparecoeff( lhs.value ) > 0;
519        }
520    }
521    else  if ( is_imm( rhs.value ) )
522        return lhs.value->comparecoeff( rhs.value ) < 0;
523    else  if ( lhs.level() == rhs.level() )
524        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
525            return lhs.value->comparesame( rhs.value ) < 0;
526        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
527            return lhs.value->comparecoeff( lhs.value ) < 0;
528        else
529            return rhs.value->comparecoeff( lhs.value ) > 0;
530    else
531        return lhs.value->level() < rhs.value->level();
532}
533
534CanonicalForm&
535CanonicalForm::operator = ( const CanonicalForm & cf )
536{
537    if ( this != &cf ) {
538        if ( (! is_imm( value )) && value->deleteObject() )
539            delete value;
540        value = (is_imm( cf.value )) ? cf.value : cf.value->copyObject();
541    }
542    return *this;
543}
544
545CanonicalForm&
546CanonicalForm::operator = ( const int cf )
547{
548    if ( (! is_imm( value )) && value->deleteObject() )
549        delete value;
550    value = CFFactory::basic( cf );
551    return *this;
552}
553
554CanonicalForm&
555CanonicalForm::operator += ( const CanonicalForm & cf )
556{
557    int what = is_imm( value );
558    if ( what ) {
559        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
560        if ( (what = is_imm( cf.value )) == FFMARK )
561            value = imm_add_p( value, cf.value );
562        else  if ( what == GFMARK )
563            value = imm_add_gf( value, cf.value );
564        else  if ( what )
565            value = imm_add( value, cf.value );
566        else {
567            InternalCF * dummy = cf.value->copyObject();
568            value = dummy->addcoeff( value );
569        }
570    }
571    else  if ( is_imm( cf.value ) )
572        value = value->addcoeff( cf.value );
573    else  if ( value->level() == cf.value->level() ) {
574        if ( value->levelcoeff() == cf.value->levelcoeff() )
575            value = value->addsame( cf.value );
576        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
577            value = value->addcoeff( cf.value );
578        else {
579            InternalCF * dummy = cf.value->copyObject();
580            dummy = dummy->addcoeff( value );
581            if ( value->deleteObject() ) delete value;
582            value = dummy;
583        }
584    }
585    else  if ( level() > cf.level() )
586        value = value->addcoeff( cf.value );
587    else {
588        InternalCF * dummy = cf.value->copyObject();
589        dummy = dummy->addcoeff( value );
590        if ( value->deleteObject() ) delete value;
591        value = dummy;
592    }
593    return *this;
594}
595
596CanonicalForm&
597CanonicalForm::operator -= ( const CanonicalForm & cf )
598{
599    int what = is_imm( value );
600    if ( what ) {
601        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
602        if ( (what = is_imm( cf.value )) == FFMARK )
603            value = imm_sub_p( value, cf.value );
604        else  if ( what == GFMARK )
605            value = imm_sub_gf( value, cf.value );
606        else  if ( what )
607            value = imm_sub( value, cf.value );
608        else {
609            InternalCF * dummy = cf.value->copyObject();
610            value = dummy->subcoeff( value, true );
611        }
612    }
613    else  if ( is_imm( cf.value ) )
614        value = value->subcoeff( cf.value, false );
615    else  if ( value->level() == cf.value->level() ) {
616        if ( value->levelcoeff() == cf.value->levelcoeff() )
617            value = value->subsame( cf.value );
618        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
619            value = value->subcoeff( cf.value, false );
620        else {
621            InternalCF * dummy = cf.value->copyObject();
622            dummy = dummy->subcoeff( value, true );
623            if ( value->deleteObject() ) delete value;
624            value = dummy;
625        }
626    }
627    else  if ( level() > cf.level() )
628        value = value->subcoeff( cf.value, false );
629    else {
630        InternalCF * dummy = cf.value->copyObject();
631        dummy = dummy->subcoeff( value, true );
632        if ( value->deleteObject() ) delete value;
633        value = dummy;
634    }
635    return *this;
636}
637
638CanonicalForm&
639CanonicalForm::operator *= ( const CanonicalForm & cf )
640{
641    int what = is_imm( value );
642    if ( what ) {
643        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
644        if ( (what = is_imm( cf.value )) == FFMARK )
645            value = imm_mul_p( value, cf.value );
646        else  if ( what == GFMARK )
647            value = imm_mul_gf( value, cf.value );
648        else  if ( what )
649            value = imm_mul( value, cf.value );
650        else {
651            InternalCF * dummy = cf.value->copyObject();
652            value = dummy->mulcoeff( value );
653        }
654    }
655    else  if ( is_imm( cf.value ) )
656        value = value->mulcoeff( cf.value );
657    else  if ( value->level() == cf.value->level() ) {
658        if ( value->levelcoeff() == cf.value->levelcoeff() )
659            value = value->mulsame( cf.value );
660        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
661            value = value->mulcoeff( cf.value );
662        else {
663            InternalCF * dummy = cf.value->copyObject();
664            dummy = dummy->mulcoeff( value );
665            if ( value->deleteObject() ) delete value;
666            value = dummy;
667        }
668    }
669    else  if ( level() > cf.level() )
670        value = value->mulcoeff( cf.value );
671    else {
672        InternalCF * dummy = cf.value->copyObject();
673        dummy = dummy->mulcoeff( value );
674        if ( value->deleteObject() ) delete value;
675        value = dummy;
676    }
677    return *this;
678}
679
680CanonicalForm&
681CanonicalForm::operator /= ( const CanonicalForm & cf )
682{
683    int what = is_imm( value );
684    if ( what ) {
685        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
686        if ( (what = is_imm( cf.value )) == FFMARK )
687            value = imm_div_p( value, cf.value );
688        else  if ( what == GFMARK )
689            value = imm_div_gf( value, cf.value );
690        else  if ( what )
691            value = imm_divrat( value, cf.value );
692        else {
693            InternalCF * dummy = cf.value->copyObject();
694            value = dummy->dividecoeff( value, true );
695        }
696    }
697    else  if ( is_imm( cf.value ) )
698        value = value->dividecoeff( cf.value, false );
699    else  if ( value->level() == cf.value->level() ) {
700        if ( value->levelcoeff() == cf.value->levelcoeff() )
701            value = value->dividesame( cf.value );
702        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
703            value = value->dividecoeff( cf.value, false );
704        else {
705            InternalCF * dummy = cf.value->copyObject();
706            dummy = dummy->dividecoeff( value, true );
707            if ( value->deleteObject() ) delete value;
708            value = dummy;
709        }
710    }
711    else  if ( level() > cf.level() )
712        value = value->dividecoeff( cf.value, false );
713    else {
714        InternalCF * dummy = cf.value->copyObject();
715        dummy = dummy->dividecoeff( value, true );
716        if ( value->deleteObject() ) delete value;
717        value = dummy;
718    }
719    return *this;
720}
721
722CanonicalForm&
723CanonicalForm::div ( const CanonicalForm & cf )
724{
725    int what = is_imm( value );
726    if ( what ) {
727        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
728        if ( (what = is_imm( cf.value )) == FFMARK )
729            value = imm_div_p( value, cf.value );
730        else  if ( what == GFMARK )
731            value = imm_div_gf( value, cf.value );
732        else  if ( what )
733            value = imm_div( value, cf.value );
734        else {
735            InternalCF * dummy = cf.value->copyObject();
736            value = dummy->divcoeff( value, true );
737        }
738    }
739    else  if ( is_imm( cf.value ) )
740        value = value->divcoeff( cf.value, false );
741    else  if ( value->level() == cf.value->level() ) {
742        if ( value->levelcoeff() == cf.value->levelcoeff() )
743            value = value->divsame( cf.value );
744        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
745            value = value->divcoeff( cf.value, false );
746        else {
747            InternalCF * dummy = cf.value->copyObject();
748            dummy = dummy->divcoeff( value, true );
749            if ( value->deleteObject() ) delete value;
750            value = dummy;
751        }
752    }
753    else  if ( level() > cf.level() )
754        value = value->divcoeff( cf.value, false );
755    else {
756        InternalCF * dummy = cf.value->copyObject();
757        dummy = dummy->divcoeff( value, true );
758        if ( value->deleteObject() ) delete value;
759        value = dummy;
760    }
761    return *this;
762}
763
764CanonicalForm&
765CanonicalForm::operator %= ( const CanonicalForm& cf )
766{
767    int what = is_imm( value );
768    if ( what ) {
769        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
770        if ( (what = is_imm( cf.value )) == FFMARK )
771            value = imm_mod_p( value, cf.value );
772        else  if ( what == GFMARK )
773            value = imm_mod_gf( value, cf.value );
774        else  if ( what )
775            value = imm_mod( value, cf.value );
776        else {
777            InternalCF * dummy = cf.value->copyObject();
778            value = dummy->modulocoeff( value, true );
779        }
780    }
781    else  if ( is_imm( cf.value ) )
782        value = value->modulocoeff( cf.value, false );
783    else  if ( value->level() == cf.value->level() ) {
784        if ( value->levelcoeff() == cf.value->levelcoeff() )
785            value = value->modulosame( cf.value );
786        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
787            value = value->modulocoeff( cf.value, false );
788        else {
789            InternalCF * dummy = cf.value->copyObject();
790            dummy = dummy->modulocoeff( value, true );
791            if ( value->deleteObject() ) delete value;
792            value = dummy;
793        }
794    }
795    else  if ( level() > cf.level() )
796        value = value->modulocoeff( cf.value, false );
797    else {
798        InternalCF * dummy = cf.value->copyObject();
799        dummy = dummy->modulocoeff( value, true );
800        if ( value->deleteObject() ) delete value;
801        value = dummy;
802    }
803    return *this;
804}
805
806CanonicalForm&
807CanonicalForm::mod( const CanonicalForm & cf )
808{
809    int what = is_imm( value );
810    if ( what ) {
811        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
812        if ( (what = is_imm( cf.value )) == FFMARK )
813            value = imm_mod_p( value, cf.value );
814        else  if ( what == GFMARK )
815            value = imm_mod_gf( value, cf.value );
816        else  if ( what )
817            value = imm_mod( value, cf.value );
818        else {
819            InternalCF * dummy = cf.value->copyObject();
820            value = dummy->modcoeff( value, true );
821        }
822    }
823    else  if ( is_imm( cf.value ) )
824        value = value->modcoeff( cf.value, false );
825    else  if ( value->level() == cf.value->level() ) {
826        if ( value->levelcoeff() == cf.value->levelcoeff() )
827            value = value->modsame( cf.value );
828        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
829            value = value->modcoeff( cf.value, false );
830        else {
831            InternalCF * dummy = cf.value->copyObject();
832            dummy = dummy->modcoeff( value, true );
833            if ( value->deleteObject() ) delete value;
834            value = dummy;
835        }
836    }
837    else  if ( level() > cf.level() )
838        value = value->modcoeff( cf.value, false );
839    else {
840        InternalCF * dummy = cf.value->copyObject();
841        dummy = dummy->modcoeff( value, true );
842        if ( value->deleteObject() ) delete value;
843        value = dummy;
844    }
845    return *this;
846}
847
848CanonicalForm
849operator - ( const CanonicalForm & cf )
850{
851    CanonicalForm result( cf );
852    int what = is_imm( result.value );
853    if ( what == FFMARK )
854        result.value = imm_neg_p( result.value );
855    else  if ( what == GFMARK )
856        result.value = imm_neg_gf( result.value );
857    else  if ( what )
858        result.value = imm_neg( result.value );
859    else
860        result.value = result.value->neg();
861    return result;
862}
863
864CanonicalForm
865operator + ( const CanonicalForm &c1, const CanonicalForm &c2 )
866{
867    CanonicalForm result( c1 );
868    result += c2;
869    return result;
870}
871
872CanonicalForm
873operator - ( const CanonicalForm &c1, const CanonicalForm &c2 )
874{
875    CanonicalForm result( c1 );
876    result -= c2;
877    return result;
878}
879
880CanonicalForm
881operator * ( const CanonicalForm &c1, const CanonicalForm &c2 )
882{
883    CanonicalForm result( c1 );
884    result *= c2;
885    return result;
886}
887
888CanonicalForm
889operator / ( const CanonicalForm &c1, const CanonicalForm &c2 )
890{
891    CanonicalForm result( c1 );
892    result /= c2;
893    return result;
894}
895
896CanonicalForm
897div ( const CanonicalForm &c1, const CanonicalForm &c2 )
898{
899    CanonicalForm result( c1 );
900    result.div( c2 );
901    return result;
902}
903
904CanonicalForm
905mod ( const CanonicalForm &c1, const CanonicalForm &c2 )
906{
907    CanonicalForm result( c1 );
908    result.mod( c2 );
909    return result;
910}
911
912CanonicalForm
913operator % ( const CanonicalForm &c1, const CanonicalForm &c2 )
914{
915    CanonicalForm result( c1 );
916    result %= c2;
917    return result;
918}
919
920void
921divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
922{
923    InternalCF * qq = 0, * rr = 0;
924    int what = is_imm( f.value );
925    if ( what )
926        if ( is_imm( g.value ) ) {
927            if ( what == FFMARK )
928                imm_divrem_p( f.value, g.value, qq, rr );
929            else  if ( what == GFMARK )
930                imm_divrem_gf( f.value, g.value, qq, rr );
931            else
932                imm_divrem( f.value, g.value, qq, rr );
933        }
934        else
935            g.value->divremcoeff( f.value, qq, rr, true );
936    else  if ( (what=is_imm( g.value )) )
937        f.value->divremcoeff( g.value, qq, rr, false );
938    else  if ( f.value->level() == g.value->level() )
939        if ( f.value->levelcoeff() == g.value->levelcoeff() )
940            f.value->divremsame( g.value, qq, rr );
941        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
942            f.value->divremcoeff( g.value, qq, rr, false );
943        else
944            g.value->divremcoeff( f.value, qq, rr, true );
945    else  if ( f.value->level() > g.value->level() )
946        f.value->divremcoeff( g.value, qq, rr, false );
947    else
948        g.value->divremcoeff( f.value, qq, rr, true );
949    ASSERT( qq != 0 && rr != 0, "error in divrem" );
950    q = CanonicalForm( qq );
951    r = CanonicalForm( rr );
952}
953
954bool
955divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
956{
957    InternalCF * qq = 0, * rr = 0;
958    int what = is_imm( f.value );
959    bool result = true;
960    if ( what )
961        if ( is_imm( g.value ) ) {
962            if ( what == FFMARK )
963                imm_divrem_p( f.value, g.value, qq, rr );
964            else  if ( what == GFMARK )
965                imm_divrem_gf( f.value, g.value, qq, rr );
966            else
967                imm_divrem( f.value, g.value, qq, rr );
968        }
969        else
970            result = g.value->divremcoefft( f.value, qq, rr, true );
971    else  if ( (what=is_imm( g.value )) )
972        result = f.value->divremcoefft( g.value, qq, rr, false );
973    else  if ( f.value->level() == g.value->level() )
974        if ( f.value->levelcoeff() == g.value->levelcoeff() )
975            result = f.value->divremsamet( g.value, qq, rr );
976        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
977            result = f.value->divremcoefft( g.value, qq, rr, false );
978        else
979            result = g.value->divremcoefft( f.value, qq, rr, true );
980    else  if ( f.value->level() > g.value->level() )
981        result = f.value->divremcoefft( g.value, qq, rr, false );
982    else
983        result = g.value->divremcoefft( f.value, qq, rr, true );
984    if ( result ) {
985        ASSERT( qq != 0 && rr != 0, "error in divrem" );
986        q = CanonicalForm( qq );
987        r = CanonicalForm( rr );
988    }
989    else {
990        q = 0; r = 0;
991    }
992    return result;
993}
994
995#ifndef NOSTREAMIO
996ostream&
997operator << ( ostream & os, const CanonicalForm & cf )
998{
999    cf.print( os, "" );
1000    return os;
1001}
1002#endif /* NOSTREAMIO */
1003
1004#ifndef NOSTREAMIO
1005istream&
1006operator >> ( istream & is, CanonicalForm & cf )
1007{
1008#ifndef SINGULAR
1009    cf = readCF( is );
1010    return is;
1011#else /* SINGULAR */
1012    return 0;
1013#endif /* SINGULAR */
1014}
1015#endif /* NOSTREAMIO */
1016
1017CanonicalForm
1018CanonicalForm::operator () ( const CanonicalForm & f ) const
1019{
1020    if ( inBaseDomain() )
1021        return *this;
1022    else {
1023        CanonicalForm result = 0;
1024        for ( CFIterator i = *this; i.hasTerms(); i++ )
1025            if ( i.exp() == 0 )
1026                result += i.coeff();
1027            else
1028                result += power( f, i.exp() ) * i.coeff();
1029        return result;
1030    }
1031}
1032
1033CanonicalForm
1034CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
1035{
1036    if ( inBaseDomain() || v > mvar() )
1037        return *this;
1038    else  if ( v == mvar() ) {
1039        CanonicalForm result = 0;
1040        for ( CFIterator i = *this; i.hasTerms(); i++ )
1041            if ( i.exp() == 0 )
1042                result += i.coeff();
1043            else
1044                result += power( f, i.exp() ) * i.coeff();
1045        return result;
1046    }
1047    else {
1048        CanonicalForm G = swapvar( *this, v, Variable::highest() );
1049        if ( G.mvar() != Variable::highest() )
1050            return *this;
1051        CanonicalForm result = 0;
1052        for ( CFIterator i = G; i.hasTerms(); ++i )
1053            if ( i.exp() == 0 )
1054                result += i.coeff();
1055            else
1056                result += power( f, i.exp() ) * i.coeff();
1057        return result;
1058    }
1059}
1060
1061CanonicalForm
1062CanonicalForm::operator[] ( int i ) const
1063{
1064    return value->coeff( i );
1065}
1066
1067int
1068CanonicalForm::sign() const
1069{
1070    if ( is_imm( value ) )
1071        return imm_sign( value );
1072    else
1073        return value->sign();
1074}
1075
1076CanonicalForm
1077power ( const CanonicalForm & f, int n )
1078{
1079    ASSERT( n >= 0, "illegal exponent" );
1080    if ( f == 0 )
1081        return 0;
1082    else  if ( f == 1 )
1083        return f;
1084    else  if ( f == -1 ) {
1085        if ( n % 2 == 0 )
1086            return 1;
1087        else
1088            return -1;
1089    }
1090    else  if ( n == 0 )
1091        return 1;
1092    else {
1093        CanonicalForm result = f;
1094        for ( int i = 1; i < n; i++ )
1095            result *= f;
1096        return result;
1097    }
1098}
1099
1100CanonicalForm
1101power ( const Variable & v, int n )
1102{
1103    ASSERT( n >= 0, "illegal exponent" );
1104    if ( n == 0 )
1105        return 1;
1106    else  if ( n == 1 )
1107        return v;
1108    else  if ( v.level() < 0 ) {
1109        CanonicalForm result( v, n-1 );
1110        return result * v;
1111    }
1112    else
1113        return CanonicalForm( v, n );
1114}
1115
1116
1117int initializeGMP();
1118int initializeCharacteristic();
1119#ifdef SINGULAR
1120int mmInit(void);
1121#endif
1122
1123int
1124initCanonicalForm( void )
1125{
1126    static bool initialized = false;
1127    if ( ! initialized ) {
1128#if (defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)) || defined (SINGULAR)
1129        (void)mmInit();
1130#endif
1131
1132        Off( SW_RATIONAL );
1133        Off( SW_QUOTIENT );
1134        Off( SW_SYMMETRIC_FF );
1135        Off( SW_BERLEKAMP );
1136        Off( SW_FAC_USE_BIG_PRIMES );
1137        Off( SW_FAC_QUADRATICLIFT );
1138        Off( SW_USE_EZGCD );
1139
1140        (void)initializeCharacteristic();
1141        (void)initializeGMP();
1142        initPT();
1143        initialized = true;
1144    }
1145    return 1;
1146}
1147
1148
1149CanonicalForm
1150CanonicalForm::mapinto () const
1151{
1152    ASSERT( is_imm( value ) ||  ! value->inExtension(), "cannot map into different Extension" );
1153    if ( is_imm( value ) )
1154        if ( getCharacteristic() == 0 )
1155            if ( is_imm( value ) == FFMARK )
1156                return CanonicalForm( int2imm( ff_symmetric( imm2int( value ) ) ) );
1157            else  if ( is_imm( value ) == GFMARK )
1158                return CanonicalForm( int2imm( ff_symmetric( gf_gf2ff( imm2int( value ) ) ) ) );
1159            else
1160                return *this;
1161        else  if ( CFFactory::gettype() == PrimePowerDomain )
1162            return CanonicalForm( CFFactory::basic( imm2int( value ) ) );
1163        else  if ( getGFDegree() == 1 )
1164            return CanonicalForm( int2imm_p( ff_norm( imm2int( value ) ) ) );
1165        else
1166            return CanonicalForm( int2imm_gf( gf_int2gf( imm2int( value ) ) ) );
1167    else  if ( value->inBaseDomain() )
1168        if ( getCharacteristic() == 0 )
1169            if ( value->levelcoeff() == PrimePowerDomain )
1170                return CFFactory::basic( getmpi( value, true ) );
1171            else
1172                return *this;
1173        else  if ( CFFactory::gettype() == PrimePowerDomain ) {
1174            ASSERT( value->levelcoeff() == PrimePowerDomain || value->levelcoeff() == IntegerDomain, "no proper map defined" );
1175            if ( value->levelcoeff() == PrimePowerDomain )
1176                return *this;
1177            else
1178                return CFFactory::basic( getmpi( value ) );
1179        }
1180        else {
1181            int val;
1182            if ( value->levelcoeff() == IntegerDomain )
1183                val = value->intmod( ff_prime );
1184            else  if ( value->levelcoeff() == RationalDomain )
1185                return num().mapinto() / den().mapinto();
1186            else {
1187                ASSERT( 0, "illegal domain" );
1188                return 0;
1189            }
1190            if ( getGFDegree() > 1 )
1191                return CanonicalForm( int2imm_gf( gf_int2gf( val ) ) );
1192            else
1193                return CanonicalForm( int2imm_p( val ) );
1194        }
1195    else {
1196        Variable x = value->variable();
1197        CanonicalForm result;
1198        for ( CFIterator i = *this; i.hasTerms(); i++ )
1199            result += power( x, i.exp() ) * i.coeff().mapinto();
1200        return result;
1201    }
1202}
1203
1204void
1205On( int sw )
1206{
1207    cf_glob_switches.On( sw );
1208}
1209
1210void
1211Off( int sw )
1212{
1213    cf_glob_switches.Off( sw );
1214}
1215
1216bool
1217isOn( int sw )
1218{
1219    return cf_glob_switches.isOn( sw );
1220}
1221
1222bool
1223CanonicalForm::isFFinGF() const
1224{
1225    return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
1226}
1227
1228static void
1229fillVarsRec ( const CanonicalForm & f, int * vars )
1230{
1231    int n;
1232    if ( (n = f.level()) > 0 ) {
1233        vars[n] = 1;
1234        CFIterator i;
1235        for ( i = f; i.hasTerms(); ++i )
1236            fillVarsRec( i.coeff(), vars );
1237    }
1238}
1239
1240CanonicalForm
1241CanonicalForm::sqrt ( ) const
1242{
1243    if ( is_imm( value ) ) {
1244        ASSERT( is_imm( value ) == INTMARK, "not implemented" );
1245        int a = imm2int( value );
1246        if ( a == 1 )
1247            return CanonicalForm( CFFactory::basic( 1 ) );
1248        else {
1249            int h, x0, x1 = a;
1250            do {
1251                x0 = x1;
1252                h = x0 * x0 + a - 1;
1253                if ( h % (2 * x0) == 0 )
1254                    x1 = h / (2 * x0);
1255                else
1256                    x1 = (h - 1)  / (2 * x0);
1257            } while ( x1 < x0 );
1258            return CanonicalForm( CFFactory::basic( x1 ) );
1259        }
1260    }
1261    else
1262        return CanonicalForm( value->sqrt() );
1263}
1264
1265
1266int
1267getNumVars( const CanonicalForm & f )
1268{
1269    int n;
1270    if ( f.inCoeffDomain() )
1271        return 0;
1272    else  if ( (n = f.level()) == 1 )
1273        return 1;
1274    else {
1275        int * vars = new int[ n+1 ];
1276        int i;
1277        for ( i = 0; i < n; i++ ) vars[i] = 0;
1278        for ( CFIterator I = f; I.hasTerms(); ++I )
1279            fillVarsRec( I.coeff(), vars );
1280        int m = 0;
1281        for ( i = 1; i < n; i++ )
1282            if ( vars[i] != 0 ) m++;
1283        delete [] vars;
1284        return m+1;
1285    }
1286}
1287
1288CanonicalForm
1289getVars( const CanonicalForm & f )
1290{
1291    int n;
1292    if ( f.inCoeffDomain() )
1293        return 1;
1294    else  if ( (n = f.level()) == 1 )
1295        return Variable( 1 );
1296    else {
1297        int * vars = new int[ n+1 ];
1298        int i;
1299        for ( i = 0; i <= n; i++ ) vars[i] = 0;
1300        for ( CFIterator I = f; I.hasTerms(); ++I )
1301            fillVarsRec( I.coeff(), vars );
1302        CanonicalForm result = 1;
1303        for ( i = n; i > 0; i-- )
1304            if ( vars[i] != 0 ) result *= Variable( i );
1305        delete [] vars;
1306        return f.mvar() * result;
1307    }
1308}
1309
1310bool
1311divides ( const CanonicalForm & f, const CanonicalForm & g )
1312{
1313    if ( g.level() > 0 && g.level() == f.level() )
1314        if ( divides( f.tailcoeff(), g.tailcoeff() ) && divides( f.LC(), g.LC() ) ) {
1315            CanonicalForm q, r;
1316            bool ok = divremt( g, f, q, r );
1317            return ok && r == 0;
1318        }
1319        else
1320            return false;
1321    else {
1322        CanonicalForm q, r;
1323        bool ok = divremt( g, f, q, r );
1324        return ok && r == 0;
1325    }
1326}
Note: See TracBrowser for help on using the repository browser.