source: git/factory/canonicalform.cc @ e9de47

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