source: git/factory/canonicalform.cc @ c5289a

fieker-DuValspielwiese
Last change on this file since c5289a was 0ad478, checked in by Hans Schoenemann <hannes@…>, 4 years ago
opt: getChracteristic, compiler warnings
  • Property mode set to 100644
File size: 58.2 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2
3
4#include "config.h"
5
6
7#include "cf_assert.h"
8#include "cf_factory.h"
9
10#include "cf_defs.h"
11#include "cf_globals.h"
12#include "canonicalform.h"
13#include "cf_iter.h"
14#include "int_cf.h"
15#include "cf_algorithm.h"
16#include "imm.h"
17#include "int_pp.h"
18#include "gfops.h"
19#include "facMul.h"
20#include "facAlgFuncUtil.h"
21#include "FLINTconvert.h"
22#include "cf_binom.h"
23
24#ifndef NOSTREAMIO
25CanonicalForm readCF( ISTREAM& );
26#endif /* NOSTREAMIO */
27
28/** constructors, destructors, selectors **/
29CanonicalForm::CanonicalForm( const char * str, const int base ) : value( CFFactory::basic( str, base ) )
30{
31}
32
33InternalCF*
34CanonicalForm::getval() const
35{
36    if ( is_imm( value ) )
37        return value;
38    else
39        return value->copyObject();
40}
41
42CanonicalForm
43CanonicalForm::deepCopy() const
44{
45    if ( is_imm( value ) )
46        return *this;
47    else
48        return CanonicalForm( value->deepCopyObject() );
49}
50
51void
52CanonicalForm::mpzval(mpz_t val) const
53{
54    ASSERT (!is_imm (value) && value->levelcoeff() == IntegerDomain, "non-immediate integer expected");
55    getmpi (value, val);
56}
57
58
59/** predicates **/
60#if 0
61bool
62CanonicalForm::isImm() const
63{
64    return is_imm( value );
65}
66#endif
67
68bool
69CanonicalForm::inZ() const
70{
71    if ( is_imm( value ) == INTMARK )
72        return true;
73    else if ( is_imm( value ) )
74        return false;
75    else
76        return value->levelcoeff() == IntegerDomain;
77}
78
79bool
80CanonicalForm::inQ() const
81{
82    if ( is_imm( value ) == INTMARK )
83        return true;
84    else if ( is_imm( value ) )
85        return false;
86    else
87        return value->levelcoeff() == IntegerDomain ||
88            value->levelcoeff() == RationalDomain;
89}
90
91bool
92CanonicalForm::inFF() const
93{
94    return is_imm( value ) == FFMARK;
95}
96
97bool
98CanonicalForm::inGF() const
99{
100    return is_imm( value ) == GFMARK;
101}
102
103bool
104CanonicalForm::inBaseDomain() const
105{
106    if ( is_imm( value ) )
107        return true;
108    else
109        return value->inBaseDomain();
110}
111
112bool
113CanonicalForm::inExtension() const
114{
115    if ( is_imm( value ) )
116        return false;
117    else
118        return value->inExtension();
119}
120
121bool
122CanonicalForm::inCoeffDomain() const
123{
124    if ( is_imm( value ) )
125        return true;
126    else
127        return value->inCoeffDomain();
128}
129
130bool
131CanonicalForm::inPolyDomain() const
132{
133    if ( is_imm( value ) )
134        return false;
135    else
136        return value->inPolyDomain();
137}
138
139bool
140CanonicalForm::inQuotDomain() const
141{
142    if ( is_imm( value ) )
143        return false;
144    else
145        return value->inQuotDomain();
146}
147
148bool
149CanonicalForm::isFFinGF() const
150{
151    return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
152}
153
154bool
155CanonicalForm::isUnivariate() const
156{
157    if ( is_imm( value ) )
158        return false;
159    else
160        return value->isUnivariate();
161}
162
163// is_homogeneous returns 1 iff f is homogeneous, 0 otherwise//
164bool
165CanonicalForm::isHomogeneous() const
166{
167  if (this->isZero()) return true;
168  else if (this->inCoeffDomain()) return true;
169  else
170  {
171#if 0
172    CFIterator i;
173    int cdeg = -2, dummy;
174    for ( i = *this; i.hasTerms(); i++ )
175    {
176      if (!(i.coeff().isHomogeneous())) return false;
177      if ( (dummy = totaldegree( i.coeff() ) + i.exp()) != cdeg )
178      {
179         if (cdeg == -2) cdeg = dummy;
180         else return false;
181      }
182    }
183    return true;
184#else
185    CFList termlist= get_Terms(*this);
186    CFListIterator i;
187    int deg= totaldegree(termlist.getFirst());
188
189    for ( i=termlist; i.hasItem(); i++ )
190      if ( totaldegree(i.getItem()) != deg ) return false;
191    return true;
192#endif
193  }
194}
195
196
197
198/** conversion functions **/
199long
200CanonicalForm::intval() const
201{
202    if ( is_imm( value ) )
203        return imm_intval( value );
204    else
205        return value->intval();
206}
207
208
209CanonicalForm
210CanonicalForm::mapinto () const
211{
212    //ASSERT( is_imm( value ) ||  ! value->inExtension(), "cannot map into different Extension" );
213    int ch=getCharacteristic();
214    if ( is_imm( value ) )
215        if ( ch == 0 )
216            if ( is_imm( value ) == FFMARK )
217                return CanonicalForm( int2imm( ff_symmetric( imm2int( value ) ) ) );
218            else  if ( is_imm( value ) == GFMARK )
219                return CanonicalForm( int2imm( ff_symmetric( gf_gf2ff( imm2int( value ) ) ) ) );
220            else
221                return *this;
222        else  if ( CFFactory::gettype() == PrimePowerDomain )
223            return CanonicalForm( CFFactory::basic( imm2int( value ) ) );
224        else  if ( getGFDegree() == 1 )
225            return CanonicalForm( int2imm_p( ff_norm( imm2int( value ) ) ) );
226        else
227            return CanonicalForm( int2imm_gf( gf_int2gf( imm2int( value ) ) ) );
228    else  if ( value->inBaseDomain() )
229        if ( ch == 0 )
230            #ifndef HAVE_NTL
231            if ( value->levelcoeff() == PrimePowerDomain )
232            {
233              mpz_t d;
234              getmpi( value,d);
235              if ( mpz_cmp( InternalPrimePower::primepowhalf, d ) < 0 )
236                mpz_sub( d, d, InternalPrimePower::primepow );
237              return CFFactory::basic( d );
238            }
239            else
240            #endif
241                return *this;
242        #ifndef HAVE_NTL
243        else  if ( CFFactory::gettype() == PrimePowerDomain )
244        {
245            ASSERT( value->levelcoeff() == PrimePowerDomain || value->levelcoeff() == IntegerDomain, "no proper map defined" );
246            if ( value->levelcoeff() == PrimePowerDomain )
247                return *this;
248            else
249            {
250              mpz_t d;
251              getmpi(value,d);
252              if ( mpz_cmp( InternalPrimePower::primepowhalf, d ) < 0 )
253                mpz_sub( d, d, InternalPrimePower::primepow );
254              return CFFactory::basic( d );
255            }
256        }
257        #endif
258        else
259        {
260            int val;
261            if ( value->levelcoeff() == IntegerDomain )
262                val = value->intmod( ff_prime );
263            else  if ( value->levelcoeff() == RationalDomain )
264                return num().mapinto() / den().mapinto();
265            else {
266                ASSERT( 0, "illegal domain" );
267                return 0;
268            }
269            if ( getGFDegree() > 1 )
270                return CanonicalForm( int2imm_gf( gf_int2gf( val ) ) );
271            else
272                return CanonicalForm( int2imm_p( val ) );
273        }
274    else
275    {
276        Variable x = value->variable();
277        CanonicalForm result;
278        for ( CFIterator i = *this; i.hasTerms(); i++ )
279            result += (power( x, i.exp() ) * i.coeff().mapinto());
280        return result;
281    }
282}
283/** CanonicalForm CanonicalForm::lc (), Lc (), LC (), LC ( v ) const
284 *
285 * lc(), Lc(), LC() - leading coefficient functions.
286 *
287 * All methods return CO if CO is in a base domain.
288 *
289 * lc() returns the leading coefficient of CO with respect to
290 * lexicographic ordering.  Elements in an algebraic extension
291 * are considered polynomials so lc() always returns a leading
292 * coefficient in a base domain.  This method is useful to get
293 * the base domain over which CO is defined.
294 *
295 * Lc() returns the leading coefficient of CO with respect to
296 * lexicographic ordering.  In contrast to lc() elements in an
297 * algebraic extension are considered coefficients so Lc() always
298 * returns a leading coefficient in a coefficient domain.
299 *
300 * LC() returns the leading coefficient of CO where CO is
301 * considered a univariate polynomial in its main variable.  An
302 * element of an algebraic extension is considered an univariate
303 * polynomial, too.
304 *
305 * LC( v ) returns the leading coefficient of CO where CO is
306 * considered an univariate polynomial in the polynomial variable
307 * v.
308 * Note: If v is less than the main variable of CO we have to
309 * swap variables which may be quite expensive.
310 *
311 * Examples:
312 * > Let x < y be polynomial variables, a an algebraic variable.
313 *
314 * > (3*a*x*y^2+y+x).lc() = 3
315 *
316 * > (3*a*x*y^2+y+x).Lc() = 3*a
317 *
318 * > (3*a*x*y^2+y+x).LC() = 3*a*x
319 *
320 * > (3*a*x*y^2+y+x).LC( x ) = 3*a*y^2+1
321 *
322 *
323 * > (3*a^2+4*a).lc() = 3
324 *
325 * > (3*a^2+4*a).Lc() = 3*a^2+4*a
326 *
327 * > (3*a^2+4*a).LC() = 3
328 *
329 * > (3*a^2+4*a).LC( x ) = 3*a^2+4*a
330 *
331 * @sa InternalCF::lc(), InternalCF::Lc(), InternalCF::LC(),
332 * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
333 * ::lc(), ::Lc(), ::LC(), ::LC( v )
334 *
335**/
336CanonicalForm
337CanonicalForm::lc () const
338{
339    if ( is_imm( value ) )
340        return *this;
341    else
342        return value->lc();
343}
344
345/**
346 * @sa CanonicalForm::lc(), CanonicalForm::LC(), InternalCF::lc(),
347 * InternalCF::Lc(), InternalCF::LC(),
348 * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
349 * ::lc(), ::Lc(), ::LC(), ::LC( v )
350**/
351CanonicalForm
352CanonicalForm::Lc () const
353{
354    if ( is_imm( value ) || value->inCoeffDomain() )
355        return *this;
356    else
357        return value->Lc();
358}
359
360/**
361 * @sa CanonicalForm::lc(), CanonicalForm::Lc(), InternalCF::lc(),
362 * InternalCF::Lc(), InternalCF::LC(),
363 * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
364 * ::lc(), ::Lc(), ::LC(), ::LC( v )
365**/
366CanonicalForm
367CanonicalForm::LC () const
368{
369    if ( is_imm( value ) )
370        return *this;
371    else
372        return value->LC();
373}
374
375/**
376 * @sa CanonicalForm::lc(), CanonicalForm::Lc(), InternalCF::lc(),
377 * InternalCF::Lc(), InternalCF::LC(),
378 * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
379 * ::lc(), ::Lc(), ::LC(), ::LC( v )
380**/
381CanonicalForm
382CanonicalForm::LC ( const Variable & v ) const
383{
384    if ( is_imm( value ) || value->inCoeffDomain() )
385        return *this;
386
387    Variable x = value->variable();
388    if ( v > x )
389        return *this;
390    else if ( v == x )
391        return value->LC();
392    else {
393        CanonicalForm f = swapvar( *this, v, x );
394         if ( f.mvar() == x )
395             return swapvar( f.value->LC(), v, x );
396         else
397            // v did not occur in f
398            return *this;
399    }
400}
401
402/**
403 * Returns -1 for the zero polynomial and 0 if
404 * CO is in a base domain.
405 *
406 * degree() returns the degree of CO in its main variable.
407 * Elements in an algebraic extension are considered polynomials.
408 *
409 * @sa InternalCF::degree(), InternalPoly::degree(),
410 * ::degree(), ::degree( v )
411 *
412**/
413int
414CanonicalForm::degree() const
415{
416    int what = is_imm( value );
417    if ( what )
418        if ( what == FFMARK )
419            return imm_iszero_p( value ) ? -1 : 0;
420        else if ( what == INTMARK )
421            return imm_iszero( value ) ? -1 : 0;
422        else
423            return imm_iszero_gf( value ) ? -1 : 0;
424    else
425        return value->degree();
426}
427
428/**
429 * returns -1 for the zero polynomial and 0 if
430 * CO is in a base domain.
431 *
432 * degree( v ) returns the degree of CO with respect to v.
433 * Elements in an algebraic extension are considered polynomials,
434 * and v may be algebraic.
435 *
436 * @sa InternalCF::degree(), InternalPoly::degree(),
437 * ::degree(), ::degree( v )
438**/
439int
440CanonicalForm::degree( const Variable & v ) const
441{
442    int what = is_imm( value );
443#if 0
444    if ( what )
445        if ( what == FFMARK )
446            return imm_iszero_p( value ) ? -1 : 0;
447        else if ( what == INTMARK )
448            return imm_iszero( value ) ? -1 : 0;
449        else
450            return imm_iszero_gf( value ) ? -1 : 0;
451    else if ( value->inBaseDomain() )
452        return value->degree();
453#else
454    switch(what)
455    {
456      case FFMARK: return imm_iszero_p( value ) ? -1 : 0;
457      case INTMARK: return imm_iszero( value ) ? -1 : 0;
458      case GFMARK:  return imm_iszero_gf( value ) ? -1 : 0;
459      case 0: if ( value->inBaseDomain() )
460              return value->degree();
461              break;
462    }
463#endif
464
465    Variable x = value->variable();
466    if ( v == x )
467        return value->degree();
468    else  if ( v > x )
469        // relatively to v, f is in a coefficient ring
470        return 0;
471    else {
472        int coeffdeg, result = 0;
473        // search for maximum of coefficient degree
474        for ( CFIterator i = *this; i.hasTerms(); i++ ) {
475            coeffdeg = i.coeff().degree( v );
476            if ( coeffdeg > result )
477                result = coeffdeg;
478        }
479        return result;
480    }
481}
482
483/**
484 *
485 * tailcoeff() - return least coefficient
486 *
487 * tailcoeff() returns the coefficient of the term with the least
488 * degree in CO where CO is considered an univariate polynomial
489 * in its main variable.  Elements in an algebraic extension are
490 * considered coefficients.
491 *
492 * @sa CanonicalForm::taildegree(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
493 * InternalPoly::tailcoeff(), InternalPoly::taildegree,
494 * ::tailcoeff(), ::taildegree()
495 *
496**/
497CanonicalForm
498CanonicalForm::tailcoeff () const
499{
500    if ( is_imm( value ) || value->inCoeffDomain() )
501        return *this;
502    else
503        return value->tailcoeff();
504}
505
506/**
507 * tailcoeff( v ) returns the tail coefficient of CO where CO is
508 * considered an univariate polynomial in the polynomial variable
509 * v.
510 * Note: If v is less than the main variable of CO we have to
511 * swap variables which may be quite expensive.
512 *
513 * @sa CanonicalForm::taildegree(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
514 * InternalPoly::tailcoeff(), InternalPoly::taildegree,
515 * ::tailcoeff(), ::taildegree()
516**/
517CanonicalForm
518CanonicalForm::tailcoeff (const Variable& v) const
519{
520    if ( is_imm( value ) || value->inCoeffDomain() )
521        return *this;
522
523    Variable x = value->variable();
524    if ( v > x )
525        return *this;
526    else if ( v == x )
527        return value->tailcoeff();
528    else {
529        CanonicalForm f = swapvar( *this, v, x );
530         if ( f.mvar() == x )
531             return swapvar( f.value->tailcoeff(), v, x );
532         else
533            // v did not occur in f
534            return *this;
535    }
536}
537
538
539/**
540 * taildegree() returns -1 for the zero polynomial, 0 if CO is in
541 * a base domain, otherwise the least degree of CO where CO is
542 * considered a univariate polynomial in its main variable.  In
543 * contrast to tailcoeff(), elements in an algebraic extension
544 * are considered polynomials, not coefficients, and such may
545 * have a taildegree larger than zero.
546 *
547 * @sa CanonicalForm::tailcoeff(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
548 * InternalPoly::tailcoeff(), InternalPoly::taildegree,
549 * ::tailcoeff(), ::taildegree()
550**/
551int
552CanonicalForm::taildegree () const
553{
554    int what = is_imm( value );
555    if ( what )
556        if ( what == FFMARK )
557            return imm_iszero_p( value ) ? -1 : 0;
558        else if ( what == INTMARK )
559            return imm_iszero( value ) ? -1 : 0;
560        else
561            return imm_iszero_gf( value ) ? -1 : 0;
562    else
563        return value->taildegree();
564}
565
566/**
567 * level() returns the level of CO.  For a list of the levels and
568 * their meanings, see cf_defs.h.
569 *
570 * @sa InternalCF::level(), InternalCF::variable(),
571 * InternalPoly::level(), InternalPoly::variable(), ::level(),
572 * ::mvar()
573 *
574**/
575int
576CanonicalForm::level () const
577{
578    if ( is_imm( value ) )
579        return LEVELBASE;
580    else
581        return value->level();
582}
583
584/**
585 * mvar() returns the main variable of CO or Variable() if CO is
586 * in a base domain.
587 *
588 * @sa InternalCF::level(), InternalCF::variable(),
589 * InternalPoly::level(), InternalPoly::variable(), ::level(),
590 * ::mvar()
591**/
592Variable
593CanonicalForm::mvar () const
594{
595    if ( is_imm( value ) )
596        return Variable();
597    else
598        return value->variable();
599}
600
601/**
602 * num() returns the numerator of CO if CO is a rational number,
603 * CO itself otherwise.
604 *
605 * @sa InternalCF::num(), InternalCF::den(),
606 * InternalRational::num(), InternalRational::den(), ::num(),
607 * ::den()
608 *
609**/
610CanonicalForm
611CanonicalForm::num () const
612{
613    if ( is_imm( value ) )
614        return *this;
615    else
616        return CanonicalForm( value->num() );
617}
618
619/**
620 * den() returns the denominator of CO if CO is a rational
621 * number, 1 (from the current domain!) otherwise.
622 *
623 * @sa InternalCF::num(), InternalCF::den(),
624 * InternalRational::num(), InternalRational::den(), ::num(),
625 * ::den()
626**/
627CanonicalForm
628CanonicalForm::den () const
629{
630    if ( is_imm( value ) )
631        return CanonicalForm( 1 );
632    else
633        return CanonicalForm( value->den() );
634}
635
636/** assignment operators **/
637CanonicalForm &
638CanonicalForm::operator += ( const CanonicalForm & cf )
639{
640    int what = is_imm( value );
641    if ( what ) {
642        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
643        if ( (what = is_imm( cf.value )) == FFMARK )
644            value = imm_add_p( value, cf.value );
645        else  if ( what == GFMARK )
646            value = imm_add_gf( value, cf.value );
647        else  if ( what )
648            value = imm_add( value, cf.value );
649        else {
650            InternalCF * dummy = cf.value->copyObject();
651            value = dummy->addcoeff( value );
652        }
653    }
654    else  if ( is_imm( cf.value ) )
655        value = value->addcoeff( cf.value );
656    else  if ( value->level() == cf.value->level() ) {
657        if ( value->levelcoeff() == cf.value->levelcoeff() )
658            value = value->addsame( cf.value );
659        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
660            value = value->addcoeff( cf.value );
661        else {
662            InternalCF * dummy = cf.value->copyObject();
663            dummy = dummy->addcoeff( value );
664            if ( value->deleteObject() ) delete value;
665            value = dummy;
666        }
667    }
668    else  if ( level() > cf.level() )
669        value = value->addcoeff( cf.value );
670    else {
671        InternalCF * dummy = cf.value->copyObject();
672        dummy = dummy->addcoeff( value );
673        if ( value->deleteObject() ) delete value;
674        value = dummy;
675    }
676    return *this;
677}
678
679CanonicalForm &
680CanonicalForm::operator -= ( const CanonicalForm & cf )
681{
682    int what = is_imm( value );
683    if ( what ) {
684        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
685        if ( (what = is_imm( cf.value )) == FFMARK )
686            value = imm_sub_p( value, cf.value );
687        else  if ( what == GFMARK )
688            value = imm_sub_gf( value, cf.value );
689        else  if ( what )
690            value = imm_sub( value, cf.value );
691        else {
692            InternalCF * dummy = cf.value->copyObject();
693            value = dummy->subcoeff( value, true );
694        }
695    }
696    else  if ( is_imm( cf.value ) )
697        value = value->subcoeff( cf.value, false );
698    else  if ( value->level() == cf.value->level() ) {
699        if ( value->levelcoeff() == cf.value->levelcoeff() )
700            value = value->subsame( cf.value );
701        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
702            value = value->subcoeff( cf.value, false );
703        else {
704            InternalCF * dummy = cf.value->copyObject();
705            dummy = dummy->subcoeff( value, true );
706            if ( value->deleteObject() ) delete value;
707            value = dummy;
708        }
709    }
710    else  if ( level() > cf.level() )
711        value = value->subcoeff( cf.value, false );
712    else {
713        InternalCF * dummy = cf.value->copyObject();
714        dummy = dummy->subcoeff( value, true );
715        if ( value->deleteObject() ) delete value;
716        value = dummy;
717    }
718    return *this;
719}
720
721CanonicalForm &
722CanonicalForm::operator *= ( const CanonicalForm & cf )
723{
724    int what = is_imm( value );
725    if ( what ) {
726        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
727        if ( (what = is_imm( cf.value )) == FFMARK )
728            value = imm_mul_p( value, cf.value );
729        else  if ( what == GFMARK )
730            value = imm_mul_gf( value, cf.value );
731        else  if ( what )
732            value = imm_mul( value, cf.value );
733        else {
734            InternalCF * dummy = cf.value->copyObject();
735            value = dummy->mulcoeff( value );
736        }
737    }
738    else  if ( is_imm( cf.value ) )
739        value = value->mulcoeff( cf.value );
740    else  if ( value->level() == cf.value->level() ) {
741#if (HAVE_NTL && HAVE_FLINT && __FLINT_RELEASE >= 20400)
742#if (__FLINT_RELEASE >= 20503)
743        int ch=getCharacteristic();
744        int l_this,l_cf,m=1;
745        if ((ch>0)
746        && (CFFactory::gettype() != GaloisFieldDomain)
747        &&(!hasAlgVar(*this))
748        &&(!hasAlgVar(cf))
749        &&((l_cf=size_maxexp(cf,m))>10)
750        &&((l_this=size_maxexp(*this,m))>10)
751        )
752        {
753          *this=mulFlintMP_Zp(*this,l_this,cf,l_cf,m);
754        }
755        else
756        /*-----------------------------------------------------*/
757        if ((ch==0)
758        &&(!hasAlgVar(*this))
759        &&(!hasAlgVar(cf))
760        &&((l_cf=size_maxexp(cf,m))>10)
761        &&((l_this=size_maxexp(*this,m))>10)
762        )
763        {
764          *this=mulFlintMP_QQ(*this,l_this,cf,l_cf,m);
765        }
766        else
767#endif
768
769        if (value->levelcoeff() == cf.value->levelcoeff() && cf.isUnivariate() && (*this).isUnivariate())
770        {
771          if (value->level() < 0 || CFFactory::gettype() == GaloisFieldDomain || (size (cf) <= 10 || size (*this) <= 10) )
772            value = value->mulsame( cf.value );
773          else
774            *this= mulNTL (*this, cf);
775        }
776        else if (value->levelcoeff() == cf.value->levelcoeff() && (!cf.isUnivariate() || !(*this).isUnivariate()))
777            value = value->mulsame( cf.value );
778#else
779        if ( value->levelcoeff() == cf.value->levelcoeff() )
780            value = value->mulsame( cf.value );
781#endif
782        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
783            value = value->mulcoeff( cf.value );
784        else {
785            InternalCF * dummy = cf.value->copyObject();
786            dummy = dummy->mulcoeff( value );
787            if ( value->deleteObject() ) delete value;
788            value = dummy;
789        }
790    }
791    else  if ( level() > cf.level() )
792        value = value->mulcoeff( cf.value );
793    else {
794        InternalCF * dummy = cf.value->copyObject();
795        dummy = dummy->mulcoeff( value );
796        if ( value->deleteObject() ) delete value;
797        value = dummy;
798    }
799    return *this;
800}
801
802CanonicalForm &
803CanonicalForm::operator /= ( const CanonicalForm & cf )
804{
805    int what = is_imm( value );
806    if ( what ) {
807        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
808        if ( (what = is_imm( cf.value )) == FFMARK )
809            value = imm_div_p( value, cf.value );
810        else  if ( what == GFMARK )
811            value = imm_div_gf( value, cf.value );
812        else  if ( what )
813            value = imm_divrat( value, cf.value );
814        else {
815            InternalCF * dummy = cf.value->copyObject();
816            value = dummy->dividecoeff( value, true );
817        }
818    }
819    else  if ( is_imm( cf.value ) )
820        value = value->dividecoeff( cf.value, false );
821    else  if ( value->level() == cf.value->level() ) {
822#if (HAVE_NTL && HAVE_FLINT && __FLINT_RELEASE >= 20400)
823        if ( value->levelcoeff() == cf.value->levelcoeff() && (*this).isUnivariate() && cf.isUnivariate())
824        {
825            if (value->level() < 0 || CFFactory::gettype() == GaloisFieldDomain)
826              value = value->dividesame( cf.value );
827            else
828              *this= divNTL (*this, cf);
829        }
830        else if (value->levelcoeff() == cf.value->levelcoeff() && (!cf.isUnivariate() || !(*this).isUnivariate()))
831            value = value->dividesame( cf.value );
832#else
833        if (value->levelcoeff() == cf.value->levelcoeff() )
834            value = value->dividesame( cf.value );
835#endif
836        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
837            value = value->dividecoeff( cf.value, false );
838        else {
839            InternalCF * dummy = cf.value->copyObject();
840            dummy = dummy->dividecoeff( value, true );
841            if ( value->deleteObject() ) delete value;
842            value = dummy;
843        }
844    }
845    else  if ( level() > cf.level() )
846        value = value->dividecoeff( cf.value, false );
847    else {
848        InternalCF * dummy = cf.value->copyObject();
849        dummy = dummy->dividecoeff( value, true );
850        if ( value->deleteObject() ) delete value;
851        value = dummy;
852    }
853    return *this;
854}
855
856CanonicalForm &
857CanonicalForm::div ( const CanonicalForm & cf )
858{
859    int what = is_imm( value );
860    if ( what ) {
861        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
862        if ( (what = is_imm( cf.value )) == FFMARK )
863            value = imm_div_p( value, cf.value );
864        else  if ( what == GFMARK )
865            value = imm_div_gf( value, cf.value );
866        else  if ( what )
867            value = imm_div( value, cf.value );
868        else {
869            InternalCF * dummy = cf.value->copyObject();
870            value = dummy->divcoeff( value, true );
871        }
872    }
873    else  if ( is_imm( cf.value ) )
874        value = value->divcoeff( cf.value, false );
875    else  if ( value->level() == cf.value->level() ) {
876        if ( value->levelcoeff() == cf.value->levelcoeff() )
877            value = value->divsame( cf.value );
878        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
879            value = value->divcoeff( cf.value, false );
880        else {
881            InternalCF * dummy = cf.value->copyObject();
882            dummy = dummy->divcoeff( value, true );
883            if ( value->deleteObject() ) delete value;
884            value = dummy;
885        }
886    }
887    else  if ( level() > cf.level() )
888        value = value->divcoeff( cf.value, false );
889    else {
890        InternalCF * dummy = cf.value->copyObject();
891        dummy = dummy->divcoeff( value, true );
892        if ( value->deleteObject() ) delete value;
893        value = dummy;
894    }
895    return *this;
896}
897
898///same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
899CanonicalForm &
900CanonicalForm::tryDiv ( const CanonicalForm & cf, const CanonicalForm& M, bool& fail )
901{
902    ASSERT (getCharacteristic() > 0, "expected positive characteristic");
903    ASSERT (!getReduce (M.mvar()), "do not reduce modulo M");
904    fail= false;
905    int what = is_imm( value );
906    if ( what ) {
907        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
908        if ( (what = is_imm( cf.value )) == FFMARK )
909            value = imm_div_p( value, cf.value );
910        else  if ( what == GFMARK )
911            value = imm_div_gf( value, cf.value );
912        else {
913            InternalCF * dummy = cf.value->copyObject();
914            value = dummy->divcoeff( value, true );
915        }
916    }
917    else  if ( is_imm( cf.value ) )
918        value = value->tryDivcoeff (cf.value, false, M, fail);
919    else  if ( value->level() == cf.value->level() ) {
920        if ( value->levelcoeff() == cf.value->levelcoeff() )
921            value = value->tryDivsame( cf.value, M, fail );
922        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
923            value = value->tryDivcoeff( cf.value, false, M, fail );
924        else {
925            InternalCF * dummy = cf.value->copyObject();
926            dummy = dummy->tryDivcoeff( value, true, M, fail );
927            if ( value->deleteObject() ) delete value;
928            value = dummy;
929        }
930    }
931    else  if ( level() > cf.level() )
932        value = value->tryDivcoeff( cf.value, false, M, fail );
933    else {
934        InternalCF * dummy = cf.value->copyObject();
935        dummy = dummy->tryDivcoeff( value, true, M, fail );
936        if ( value->deleteObject() ) delete value;
937        value = dummy;
938    }
939    return *this;
940}
941
942CanonicalForm &
943CanonicalForm::operator %= ( const CanonicalForm & cf )
944{
945    int what = is_imm( value );
946    if ( what ) {
947        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
948        if ( (what = is_imm( cf.value )) == FFMARK )
949            value = imm_mod_p( value, cf.value );
950        else  if ( what == GFMARK )
951            value = imm_mod_gf( value, cf.value );
952        else  if ( what )
953            value = imm_mod( value, cf.value );
954        else {
955            InternalCF * dummy = cf.value->copyObject();
956            value = dummy->modulocoeff( value, true );
957        }
958    }
959    else  if ( is_imm( cf.value ) )
960        value = value->modulocoeff( cf.value, false );
961    else  if ( value->level() == cf.value->level() ) {
962        if ( value->levelcoeff() == cf.value->levelcoeff() )
963            value = value->modulosame( cf.value );
964        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
965            value = value->modulocoeff( cf.value, false );
966        else {
967            InternalCF * dummy = cf.value->copyObject();
968            dummy = dummy->modulocoeff( value, true );
969            if ( value->deleteObject() ) delete value;
970            value = dummy;
971        }
972    }
973    else  if ( level() > cf.level() )
974        value = value->modulocoeff( cf.value, false );
975    else {
976        InternalCF * dummy = cf.value->copyObject();
977        dummy = dummy->modulocoeff( value, true );
978        if ( value->deleteObject() ) delete value;
979        value = dummy;
980    }
981    return *this;
982}
983
984CanonicalForm &
985CanonicalForm::mod ( const CanonicalForm & cf )
986{
987    int what = is_imm( value );
988    if ( what ) {
989        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
990        if ( (what = is_imm( cf.value )) == FFMARK )
991            value = imm_mod_p( value, cf.value );
992        else  if ( what == GFMARK )
993            value = imm_mod_gf( value, cf.value );
994        else  if ( what )
995            value = imm_mod( value, cf.value );
996        else {
997            InternalCF * dummy = cf.value->copyObject();
998            value = dummy->modcoeff( value, true );
999        }
1000    }
1001    else  if ( is_imm( cf.value ) )
1002        value = value->modcoeff( cf.value, false );
1003    else  if ( value->level() == cf.value->level() ) {
1004        if ( value->levelcoeff() == cf.value->levelcoeff() )
1005            value = value->modsame( cf.value );
1006        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
1007            value = value->modcoeff( cf.value, false );
1008        else {
1009            InternalCF * dummy = cf.value->copyObject();
1010            dummy = dummy->modcoeff( value, true );
1011            if ( value->deleteObject() ) delete value;
1012            value = dummy;
1013        }
1014    }
1015    else  if ( level() > cf.level() )
1016        value = value->modcoeff( cf.value, false );
1017    else {
1018        InternalCF * dummy = cf.value->copyObject();
1019        dummy = dummy->modcoeff( value, true );
1020        if ( value->deleteObject() ) delete value;
1021        value = dummy;
1022    }
1023    return *this;
1024}
1025
1026void
1027divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
1028{
1029    InternalCF * qq = 0, * rr = 0;
1030    int what = is_imm( f.value );
1031    if ( what )
1032        if ( is_imm( g.value ) ) {
1033            if ( what == FFMARK )
1034                imm_divrem_p( f.value, g.value, qq, rr );
1035            else  if ( what == GFMARK )
1036                imm_divrem_gf( f.value, g.value, qq, rr );
1037            else
1038                imm_divrem( f.value, g.value, qq, rr );
1039        }
1040        else
1041            g.value->divremcoeff( f.value, qq, rr, true );
1042    else  if ( (what=is_imm( g.value )) )
1043        f.value->divremcoeff( g.value, qq, rr, false );
1044    else  if ( f.value->level() == g.value->level() )
1045        if ( f.value->levelcoeff() == g.value->levelcoeff() )
1046            f.value->divremsame( g.value, qq, rr );
1047        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
1048            f.value->divremcoeff( g.value, qq, rr, false );
1049        else
1050            g.value->divremcoeff( f.value, qq, rr, true );
1051    else  if ( f.value->level() > g.value->level() )
1052        f.value->divremcoeff( g.value, qq, rr, false );
1053    else
1054        g.value->divremcoeff( f.value, qq, rr, true );
1055    ASSERT( qq != 0 && rr != 0, "error in divrem" );
1056    q = CanonicalForm( qq );
1057    r = CanonicalForm( rr );
1058}
1059
1060bool
1061divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
1062{
1063    InternalCF * qq = 0, * rr = 0;
1064    int what = is_imm( f.value );
1065    bool result = true;
1066    if ( what )
1067        if ( is_imm( g.value ) ) {
1068            if ( what == FFMARK )
1069                imm_divrem_p( f.value, g.value, qq, rr );
1070            else  if ( what == GFMARK )
1071                imm_divrem_gf( f.value, g.value, qq, rr );
1072            else
1073                imm_divrem( f.value, g.value, qq, rr );
1074        }
1075        else
1076            result = g.value->divremcoefft( f.value, qq, rr, true );
1077    else  if ( (what=is_imm( g.value )) )
1078        result = f.value->divremcoefft( g.value, qq, rr, false );
1079    else  if ( f.value->level() == g.value->level() )
1080        if ( f.value->levelcoeff() == g.value->levelcoeff() )
1081            result = f.value->divremsamet( g.value, qq, rr );
1082        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
1083            result = f.value->divremcoefft( g.value, qq, rr, false );
1084        else
1085            result = g.value->divremcoefft( f.value, qq, rr, true );
1086    else  if ( f.value->level() > g.value->level() )
1087        result = f.value->divremcoefft( g.value, qq, rr, false );
1088    else
1089        result = g.value->divremcoefft( f.value, qq, rr, true );
1090    if ( result ) {
1091        ASSERT( qq != 0 && rr != 0, "error in divrem" );
1092        q = CanonicalForm( qq );
1093        r = CanonicalForm( rr );
1094    }
1095    else {
1096        q = 0; r = 0;
1097    }
1098    return result;
1099}
1100
1101///same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
1102bool
1103tryDivremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const CanonicalForm& M, bool& fail )
1104{
1105    ASSERT (getCharacteristic() > 0, "expected positive characteristic");
1106    ASSERT (!getReduce (M.mvar()), "do not reduce modulo M");
1107    fail= false;
1108    InternalCF * qq = 0, * rr = 0;
1109    int what = is_imm( f.value );
1110    bool result = true;
1111    if ( what )
1112        if ( is_imm( g.value ) ) {
1113            if ( what == FFMARK )
1114                imm_divrem_p( f.value, g.value, qq, rr );
1115            else  if ( what == GFMARK )
1116                imm_divrem_gf( f.value, g.value, qq, rr );
1117        }
1118        else
1119            result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
1120    else  if ( (what=is_imm( g.value )) )
1121        result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
1122    else  if ( f.value->level() == g.value->level() )
1123        if ( f.value->levelcoeff() == g.value->levelcoeff() )
1124            result = f.value->tryDivremsamet( g.value, qq, rr, M, fail );
1125        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
1126            result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
1127        else
1128            result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
1129    else  if ( f.value->level() > g.value->level() )
1130        result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
1131    else
1132        result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
1133    if (fail)
1134    {
1135      q= 0;
1136      r= 0;
1137      return false;
1138    }
1139    if ( result ) {
1140        ASSERT( qq != 0 && rr != 0, "error in divrem" );
1141        q = CanonicalForm( qq );
1142        r = CanonicalForm( rr );
1143        q= reduce (q, M);
1144        r= reduce (r, M);
1145    }
1146    else {
1147        q = 0; r = 0;
1148    }
1149    return result;
1150}
1151
1152/**
1153 *
1154 * operator ()() - evaluation operator.
1155 *
1156 * Returns CO if CO is in a base domain.
1157 *
1158 * operator () ( f ) returns CO with f inserted for the main
1159 * variable.  Elements in an algebraic extension are considered
1160 * polynomials.
1161 *
1162**/
1163CanonicalForm
1164CanonicalForm::operator () ( const CanonicalForm & f ) const
1165{
1166    if ( is_imm( value ) || value->inBaseDomain() )
1167        return *this;
1168    else {
1169#if 0
1170        CFIterator i = *this;
1171        int lastExp = i.exp();
1172        CanonicalForm result = i.coeff();
1173        i++;
1174        while ( i.hasTerms() ) {
1175            if ( (lastExp - i.exp()) == 1 )
1176                result *= f;
1177            else
1178                result *= power( f, lastExp - i.exp() );
1179            result += i.coeff();
1180            lastExp = i.exp();
1181            i++;
1182        }
1183        if ( lastExp != 0 )
1184            result *= power( f, lastExp );
1185#else
1186        CFIterator i = *this;
1187        int lastExp = i.exp();
1188        CanonicalForm result = i.coeff();
1189        i++;
1190        while ( i.hasTerms() )
1191        {
1192            int i_exp=i.exp();
1193            if ( (lastExp - i_exp /* i.exp()*/) == 1 )
1194                result *= f;
1195            else
1196                result *= power( f, lastExp - i_exp /*i.exp()*/ );
1197            result += i.coeff();
1198            lastExp = i_exp /*i.exp()*/;
1199            i++;
1200        }
1201        if ( lastExp != 0 )
1202            result *= power( f, lastExp );
1203#endif
1204        return result;
1205    }
1206}
1207
1208/**
1209 * Returns CO if CO is in a base domain.
1210 *
1211 * operator () ( f, v ) returns CO with f inserted for v.
1212 * Elements in an algebraic extension are considered polynomials
1213 * and v may be an algebraic variable.
1214**/
1215CanonicalForm
1216CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
1217{
1218    if ( is_imm( value ) || value->inBaseDomain() )
1219        return *this;
1220
1221    Variable x = value->variable();
1222    if ( v > x )
1223        return *this;
1224    else  if ( v == x )
1225        return (*this)( f );
1226    else {
1227        // v is less than main variable of f
1228        CanonicalForm result = 0;
1229        for ( CFIterator i = *this; i.hasTerms(); i++ )
1230            result += i.coeff()( f, v ) * power( x, i.exp() );
1231        return result;
1232    }
1233}
1234
1235/**
1236 *
1237 * operator []() - return i'th coefficient from CO.
1238 *
1239 * Returns CO if CO is in a base domain and i equals zero.
1240 * Returns zero (from the current domain) if CO is in a base
1241 * domain and i is larger than zero.  Otherwise, returns the
1242 * coefficient to x^i in CO (if x denotes the main variable of
1243 * CO) or zero if CO does not contain x^i.  Elements in an
1244 * algebraic extension are considered polynomials.  i should be
1245 * larger or equal zero.
1246 *
1247 * Note: Never use a loop like
1248 *
1249~~~~~~~~~~~~~~~~~~~~~{.c}
1250    for ( int i = degree( f ); i >= 0; i-- )
1251         foo( i, f[ i ] );
1252~~~~~~~~~~~~~~~~~~~~~
1253 *
1254 * which is much slower than
1255 *
1256~~~~~~~~~~~~~~~~~~~~~{.c}
1257 * for ( int i = degree( f ), CFIterator I = f; I.hasTerms(); I++ ) {
1258 *     // fill gap with zeroes
1259 *     for ( ; i > I.exp(); i-- )
1260 *         foo( i, 0 );
1261 *     // at this point, i == I.exp()
1262 *     foo( i, i.coeff() );
1263 *     i--;
1264 * }
1265 * // work through trailing zeroes
1266 * for ( ; i >= 0; i-- )
1267 *     foo( i, 0 );
1268~~~~~~~~~~~~~~~~~~~~~
1269 *
1270**/
1271CanonicalForm
1272CanonicalForm::operator [] ( int i ) const
1273{
1274    ASSERT( i >= 0, "index to operator [] less than zero" );
1275    if ( is_imm( value ) )
1276        if ( i == 0 )
1277            return *this;
1278        else
1279            return CanonicalForm( 0 );
1280    else
1281        return value->coeff( i );
1282}
1283
1284/**
1285 *
1286 * deriv() - return the formal derivation of CO.
1287 *
1288 * deriv() derives CO with respect to its main variable.  Returns
1289 * zero from the current domain if f is in a coefficient domain.
1290 *
1291 * @sa  CanonicalForm::deriv ( const Variable & x )
1292 *
1293**/
1294CanonicalForm
1295CanonicalForm::deriv () const
1296{
1297    if ( is_imm( value ) || value->inCoeffDomain() )
1298        return CanonicalForm( 0 );
1299    else {
1300        CanonicalForm result = 0;
1301        Variable x = value->variable();
1302        for ( CFIterator i = *this; i.hasTerms(); i++ )
1303            if ( i.exp() > 0 )
1304                result += power( x, i.exp()-1 ) * i.coeff() * i.exp();
1305        return result;
1306    }
1307}
1308
1309/**
1310 * deriv( x ) derives CO with respect to x.  x should be a
1311 * polynomial variable.  Returns zero from the current domain if
1312 * f is in a coefficient domain.
1313**/
1314CanonicalForm
1315CanonicalForm::deriv ( const Variable & x ) const
1316{
1317    ASSERT( x.level() > 0, "cannot derive with respect to algebraic variables" );
1318    if ( is_imm( value ) || value->inCoeffDomain() )
1319        return CanonicalForm( 0 );
1320
1321    Variable y = value->variable();
1322    if ( x > y )
1323        return CanonicalForm( 0 );
1324    else if ( x == y )
1325        return deriv();
1326    else {
1327        CanonicalForm result = 0;
1328        for ( CFIterator i = *this; i.hasTerms(); i++ )
1329            result += i.coeff().deriv( x ) * power( y, i.exp() );
1330        return result;
1331    }
1332}
1333
1334/** int CanonicalForm::sign () const
1335 *
1336 * sign() - return sign of CO.
1337 *
1338 * If CO is an integer or a rational number, the sign is defined
1339 * as usual.  If CO is an element of a prime power domain or of
1340 * FF(p) and SW_SYMMETRIC_FF is on, the sign of CO is the sign of
1341 * the symmetric representation of CO.  If CO is in GF(q) or in
1342 * FF(p) and SW_SYMMETRIC_FF is off, the sign of CO is zero iff
1343 * CO is zero, otherwise the sign is one.
1344 *
1345 * If CO is a polynomial or in an extension of one of the base
1346 * domains, the sign of CO is the sign of its leading
1347 * coefficient.
1348 *
1349 * @sa InternalCF::sign(), InternalInteger::sign(),
1350 * InternalRational::sign(),
1351 * InternalPoly::sign(), imm_sign(), gf_sign()
1352 *
1353**/
1354int
1355CanonicalForm::sign () const
1356{
1357    if ( is_imm( value ) )
1358        return imm_sign( value );
1359    else
1360        return value->sign();
1361}
1362
1363/** CanonicalForm CanonicalForm::sqrt () const
1364 *
1365 * sqrt() - calculate integer square root.
1366 *
1367 * CO has to be an integer greater or equal zero.  Returns the
1368 * largest integer less or equal sqrt(CO).
1369 *
1370 * In the immediate case, we use the newton method to find the
1371 * root.  The algorithm is from H. Cohen - 'A Course in
1372 * Computational Algebraic Number Theory', ch. 1.7.1.
1373 *
1374 * @sa InternalCF::sqrt(), InternalInteger::sqrt(), ::sqrt()
1375 *
1376**/
1377CanonicalForm
1378CanonicalForm::sqrt () const
1379{
1380    if ( is_imm( value ) ) {
1381        ASSERT( is_imm( value ) == INTMARK, "sqrt() not implemented" );
1382        long n = imm2int( value );
1383        ASSERT( n >= 0, "arg to sqrt() less than zero" );
1384        if ( n == 0 || n == 1 )
1385            return CanonicalForm( n );
1386        else {
1387            long x, y = n;
1388            do {
1389                x = y;
1390                // the intermediate result may not fit into an
1391                // integer, but the result does
1392                y = (unsigned long)(x + n/x)/2;
1393            } while ( y < x );
1394            return CanonicalForm( x );
1395        }
1396    }
1397    else
1398        return CanonicalForm( value->sqrt() );
1399}
1400
1401/** int CanonicalForm::ilog2 () const
1402 *
1403 * ilog2() - integer logarithm to base 2.
1404 *
1405 * Returns the largest integer less or equal logarithm of CO to
1406 * base 2.  CO should be a positive integer.
1407 *
1408 * @sa InternalCF::ilog2(), InternalInteger::ilog2(), ::ilog2()
1409 *
1410**/
1411int
1412CanonicalForm::ilog2 () const
1413{
1414    if ( is_imm( value ) )
1415    {
1416        ASSERT( is_imm( value ) == INTMARK, "ilog2() not implemented" );
1417        long a = imm2int( value );
1418        ASSERT( a > 0, "arg to ilog2() less or equal zero" );
1419        return SI_LOG2_LONG(a);
1420    }
1421    else
1422        return value->ilog2();
1423}
1424
1425/**
1426 *
1427 * operator ==() - compare canonical forms on
1428 *   (in)equality.
1429 *
1430 * operator ==() returns true iff lhs equals rhs.
1431 *
1432 * This is the point in factory where we essentially use that
1433 * CanonicalForms in fact are canonical.  There must not be two
1434 * different representations of the same mathematical object,
1435 * otherwise, such (in)equality will not be recognized by these
1436 * operators.  In other word, we rely on the fact that structural
1437 * different factory objects in any case represent different
1438 * mathematical objects.
1439 *
1440 * So we use the following procedure to test on equality (and
1441 * analogously on inequality).  First, we check whether lhs.value
1442 * equals rhs.value.  If so we are ready and return true.
1443 * Second, if one of the operands is immediate, but the other one
1444 * not, we return false.  Third, if the operand's levels differ
1445 * we return false.  Fourth, if the operand's levelcoeffs differ
1446 * we return false.  At last, we call the corresponding internal
1447 * method to compare both operands.
1448 *
1449 * Both operands should have coefficients from the same base domain.
1450 *
1451 * Note: To compare with the zero or the unit of the current domain,
1452 * you better use the methods `CanonicalForm::isZero()' or
1453 * `CanonicalForm::isOne()', resp., than something like `f == 0',
1454 * since the latter is quite a lot slower.
1455 *
1456 * @sa CanonicalForm::operator !=(), InternalCF::comparesame(),
1457 * InternalInteger::comparesame(), InternalRational::comparesame(),
1458 * InternalPoly::comparesame()
1459 *
1460**/
1461bool
1462operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1463{
1464    if ( lhs.value == rhs.value )
1465        return true;
1466    else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
1467        ASSERT( ! is_imm( rhs.value ) ||
1468                ! is_imm( lhs.value ) ||
1469                is_imm( rhs.value ) == is_imm( lhs.value ),
1470                "incompatible operands" );
1471        return false;
1472    }
1473    else  if ( lhs.value->level() != rhs.value->level() )
1474        return false;
1475    else  if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
1476        return false;
1477    else
1478        return rhs.value->comparesame( lhs.value ) == 0;
1479}
1480
1481/**
1482 * operator !=() returns true iff lhs does not equal rhs.
1483 *
1484 * @sa CanonicalForm::operator ==()
1485**/
1486bool
1487operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1488{
1489    if ( lhs.value == rhs.value )
1490        return false;
1491    else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
1492        ASSERT( ! is_imm( rhs.value ) ||
1493                ! is_imm( lhs.value ) ||
1494                is_imm( rhs.value ) == is_imm( lhs.value ),
1495                "incompatible operands" );
1496        return true;
1497    }
1498    else  if ( lhs.value->level() != rhs.value->level() )
1499        return true;
1500    else  if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
1501        return true;
1502    else        return rhs.value->comparesame( lhs.value ) != 0;
1503}
1504
1505/**
1506 *
1507 * operator >() - compare canonical forms. on size or
1508 *   level.
1509 *
1510 * The most common and most useful application of these operators
1511 * is to compare two integers or rationals, of course.  However,
1512 * these operators are defined on all other base domains and on
1513 * polynomials, too.  From a mathematical point of view this may
1514 * seem meaningless, since there is no ordering on finite fields
1515 * or on polynomials respecting the algebraic structure.
1516 * Nevertheless, from a programmer's point of view it may be
1517 * sensible to order these objects, e.g. to sort them.
1518 *
1519 * Therefore, the ordering defined by these operators in any case
1520 * is a total ordering which fulfills the law of trichotomy.
1521 *
1522 * It is clear how this is done in the case of the integers and
1523 * the rationals.  For finite fields, all you can say is that
1524 * zero is the minimal element w.r.t. the ordering, the other
1525 * elements are ordered in an arbitrary (but total!)  way.  For
1526 * polynomials, you have an ordering derived from the
1527 * lexicographical ordering of monomials.  E.g. if lm(f) < lm(g)
1528 * w.r.t. lexicographic ordering, then f < g.  For more details,
1529 * refer to the documentation of `InternalPoly::operator <()'.
1530 *
1531 * Both operands should have coefficients from the same base domain.
1532 *
1533 * The scheme how both operators are implemented is allmost the
1534 * same as for the assignment operators (check for immediates,
1535 * then check levels, then check levelcoeffs, then call the
1536 * appropriate internal comparesame()/comparecoeff() method).
1537 * For more information, confer to the overview for the
1538 * arithmetic operators.
1539 *
1540 * @sa CanonicalForm::operator <(), InternalCF::comparesame(),
1541 * InternalInteger::comparesame(), InternalRational::comparesame(),
1542 * InternalPoly::comparesame(),
1543 * InternalCF::comparecoeff(), InternalInteger::comparecoeff(),
1544 * InternalRational::comparecoeff(),
1545 * InternalPoly::comparecoeff(),
1546 * imm_cmp(), imm_cmp_p(), imm_cmp_gf()
1547 *
1548**/
1549bool
1550operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1551{
1552    int what = is_imm( rhs.value );
1553    if ( is_imm( lhs.value ) ) {
1554        ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
1555        if ( what == 0 )
1556            return rhs.value->comparecoeff( lhs.value ) < 0;
1557        else if ( what == INTMARK )
1558            return imm_cmp( lhs.value, rhs.value ) > 0;
1559        else if ( what == FFMARK )
1560            return imm_cmp_p( lhs.value, rhs.value ) > 0;
1561        else
1562            return imm_cmp_gf( lhs.value, rhs.value ) > 0;
1563    }
1564    else  if ( what )
1565        return lhs.value->comparecoeff( rhs.value ) > 0;
1566    else  if ( lhs.value->level() == rhs.value->level() )
1567        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
1568            return lhs.value->comparesame( rhs.value ) > 0;
1569        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
1570            return lhs.value->comparecoeff( rhs.value ) > 0;
1571        else
1572            return rhs.value->comparecoeff( lhs.value ) < 0;
1573    else
1574        return lhs.value->level() > rhs.value->level();
1575}
1576
1577/**
1578 * @sa CanonicalForm::operator >()
1579**/
1580bool
1581operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1582{
1583    int what = is_imm( rhs.value );
1584    if ( is_imm( lhs.value ) ) {
1585        ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
1586        if ( what == 0 )
1587            return rhs.value->comparecoeff( lhs.value ) > 0;
1588        else if ( what == INTMARK )
1589            return imm_cmp( lhs.value, rhs.value ) < 0;
1590        else if ( what == FFMARK )
1591            return imm_cmp_p( lhs.value, rhs.value ) < 0;
1592        else
1593            return imm_cmp_gf( lhs.value, rhs.value ) < 0;
1594    }
1595    else  if ( what )
1596        return lhs.value->comparecoeff( rhs.value ) < 0;
1597    else  if ( lhs.value->level() == rhs.value->level() )
1598        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
1599            return lhs.value->comparesame( rhs.value ) < 0;
1600        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
1601            return lhs.value->comparecoeff( rhs.value ) < 0;
1602        else
1603            return rhs.value->comparecoeff( lhs.value ) > 0;
1604    else
1605        return lhs.value->level() < rhs.value->level();
1606}
1607
1608/** CanonicalForm bgcd ( const CanonicalForm & f, const CanonicalForm & g )
1609 *
1610 * bgcd() - return base coefficient gcd.
1611 *
1612 * If both f and g are integers and `SW_RATIONAL' is off the
1613 * positive greatest common divisor of f and g is returned.
1614 * Otherwise, if `SW_RATIONAL' is on or one of f and g is not an
1615 * integer, the greatest common divisor is trivial: either zero
1616 * if f and g equal zero or one (both from the current domain).
1617 *
1618 * f and g should come from one base domain which should be not
1619 * the prime power domain.
1620 *
1621 * Implementation:
1622 *
1623 * CanonicalForm::bgcd() handles the immediate case with a
1624 *   standard euclidean algorithm.  For the non-immediate cases
1625 *   `InternalCF::bgcdsame()' or `InternalCF::bgcdcoeff()', resp. are
1626 *   called following the usual level/levelcoeff approach.
1627 *
1628 * InternalCF::bgcdsame() and
1629 * InternalCF::bgcdcoeff() throw an assertion ("not implemented")
1630 *
1631 * InternalInteger::bgcdsame() is a wrapper around `mpz_gcd()'
1632 *   which takes some care about immediate results and the sign
1633 *   of the result
1634 * InternalInteger::bgcdcoeff() is a wrapper around
1635 *   `mpz_gcd_ui()' which takes some care about the sign
1636 *   of the result
1637 *
1638 * InternalRational::bgcdsame() and
1639 * InternalRational::bgcdcoeff() always return one
1640 *
1641**/
1642CanonicalForm
1643bgcd ( const CanonicalForm & f, const CanonicalForm & g )
1644{
1645    // check immediate cases
1646    int what = is_imm( g.value );
1647    if ( is_imm( f.value ) )
1648    {
1649        ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
1650        if ( what == 0 )
1651            return g.value->bgcdcoeff( f.value );
1652        else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) )
1653        {
1654            // calculate gcd using standard integer
1655            // arithmetic
1656            long fInt = imm2int( f.value );
1657            long gInt = imm2int( g.value );
1658
1659            if ( fInt < 0 ) fInt = -fInt;
1660            if ( gInt < 0 ) gInt = -gInt;
1661            // swap fInt and gInt
1662            if ( gInt > fInt )
1663            {
1664                long swap = gInt;
1665                gInt = fInt;
1666                fInt = swap;
1667            }
1668
1669            // now, 0 <= gInt <= fInt.  Start the loop.
1670            while ( gInt )
1671            {
1672                // calculate (fInt, gInt) = (gInt, fInt%gInt)
1673                long r = fInt % gInt;
1674                fInt = gInt;
1675                gInt = r;
1676            }
1677
1678            return CanonicalForm( fInt );
1679        }
1680        else
1681            // we do not go for maximal speed for these stupid
1682            // special cases
1683            return CanonicalForm( f.isZero() && g.isZero() ? 0 : 1 );
1684    }
1685    else if ( what )
1686        return f.value->bgcdcoeff( g.value );
1687
1688    int fLevel = f.value->level();
1689    int gLevel = g.value->level();
1690
1691    // check levels
1692    if ( fLevel == gLevel )
1693    {
1694        fLevel = f.value->levelcoeff();
1695        gLevel = g.value->levelcoeff();
1696
1697        // check levelcoeffs
1698        if ( fLevel == gLevel )
1699            return f.value->bgcdsame( g.value );
1700        else if ( fLevel < gLevel )
1701            return g.value->bgcdcoeff( f.value );
1702        else
1703            return f.value->bgcdcoeff( g.value );
1704    }
1705    else if ( fLevel < gLevel )
1706        return g.value->bgcdcoeff( f.value );
1707    else
1708        return f.value->bgcdcoeff( g.value );
1709}
1710
1711/** CanonicalForm bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
1712 *
1713 * bextgcd() - return base coefficient extended gcd.
1714 *
1715**/
1716CanonicalForm
1717bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
1718{
1719    // check immediate cases
1720    int what = is_imm( g.value );
1721    if ( is_imm( f.value ) ) {
1722        ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
1723        if ( what == 0 )
1724            return g.value->bextgcdcoeff( f.value, b, a );
1725        else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) ) {
1726            // calculate extended gcd using standard integer
1727            // arithmetic
1728            long fInt = imm2int( f.value );
1729            long gInt = imm2int( g.value );
1730
1731            // to avoid any system dpendencies with `%', we work
1732            // with positive numbers only.  To a pity, we have to
1733            // redo all the checks when assigning to a and b.
1734            if ( fInt < 0 ) fInt = -fInt;
1735            if ( gInt < 0 ) gInt = -gInt;
1736            // swap fInt and gInt
1737            if ( gInt > fInt ) {
1738                long swap = gInt;
1739                gInt = fInt;
1740                fInt = swap;
1741            }
1742
1743            long u = 1; long v = 0;
1744            long uNext = 0; long vNext = 1;
1745
1746            // at any step, we have:
1747            // fInt_0 * u + gInt_0 * v = fInt
1748            // fInt_0 * uNext + gInt_0 * vNext = gInt
1749            // where fInt_0 and gInt_0 denote the values of fint
1750            // and gInt, resp., at the beginning
1751            while ( gInt ) {
1752                long r = fInt % gInt;
1753                long q = fInt / gInt;
1754                long uSwap = u - q * uNext;
1755                long vSwap = v - q * vNext;
1756
1757                // update variables
1758                fInt = gInt;
1759                gInt = r;
1760                u = uNext; v = vNext;
1761                uNext = uSwap; vNext = vSwap;
1762            }
1763
1764            // now, assign to a and b
1765            long fTest = imm2int( f.value );
1766            long gTest = imm2int( g.value );
1767            if ( gTest > fTest ) {
1768                a = v; b = u;
1769            } else {
1770                a = u; b = v;
1771            }
1772            if ( fTest < 0 ) a = -a;
1773            if ( gTest < 0 ) b = -b;
1774            return CanonicalForm( fInt );
1775        } else
1776            // stupid special cases
1777            if ( ! f.isZero() ) {
1778                a = 1/f; b = 0; return CanonicalForm( 1L );
1779            } else if ( ! g.isZero() ) {
1780                a = 0; b = 1/g; return CanonicalForm( 1L );
1781            } else {
1782                a = 0; b = 0; return CanonicalForm( 0L );
1783            }
1784    }
1785    else if ( what )
1786        return f.value->bextgcdcoeff( g.value, a, b );
1787
1788    int fLevel = f.value->level();
1789    int gLevel = g.value->level();
1790
1791    // check levels
1792    if ( fLevel == gLevel ) {
1793        fLevel = f.value->levelcoeff();
1794        gLevel = g.value->levelcoeff();
1795
1796        // check levelcoeffs
1797        if ( fLevel == gLevel )
1798            return f.value->bextgcdsame( g.value, a, b );
1799        else if ( fLevel < gLevel )
1800            return g.value->bextgcdcoeff( f.value, b, a );
1801        else
1802            return f.value->bextgcdcoeff( g.value, a, b );
1803    }
1804    else if ( fLevel < gLevel )
1805        return g.value->bextgcdcoeff( f.value, b, a );
1806    else
1807        return f.value->bextgcdcoeff( g.value, a, b );
1808}
1809
1810CanonicalForm
1811blcm ( const CanonicalForm & f, const CanonicalForm & g )
1812{
1813    if ( f.isZero() || g.isZero() )
1814        return CanonicalForm( 0L );
1815/*
1816    else if (f.isOne())
1817        return g;
1818    else if (g.isOne())
1819        return f;
1820*/
1821    else
1822        return (f / bgcd( f, g )) * g;
1823}
1824
1825/** input/output **/
1826#ifndef NOSTREAMIO
1827void
1828CanonicalForm::print( OSTREAM & os, char * str ) const
1829{
1830    if ( is_imm( value ) )
1831        imm_print( os, value, str );
1832    else
1833        value->print( os, str );
1834}
1835
1836void
1837CanonicalForm::print( OSTREAM & os ) const
1838{
1839    if ( is_imm( value ) )
1840        imm_print( os, value, "" );
1841    else
1842        value->print( os, "" );
1843}
1844
1845OSTREAM&
1846operator << ( OSTREAM & os, const CanonicalForm & cf )
1847{
1848    cf.print( os, "" );
1849    return os;
1850}
1851
1852ISTREAM&
1853operator >> ( ISTREAM & is, CanonicalForm & cf )
1854{
1855    cf = readCF( is );
1856    return is;
1857}
1858#endif /* NOSTREAMIO */
1859
1860/** genOne(), genZero() **/
1861CanonicalForm
1862CanonicalForm::genZero() const
1863{
1864    int what = is_imm( value );
1865    if ( what == FFMARK )
1866        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0L ) );
1867    else  if ( what == GFMARK )
1868        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0L ) );
1869    else  if ( what )
1870        return CanonicalForm( CFFactory::basic( IntegerDomain, 0L ) );
1871    else
1872        return CanonicalForm( value->genZero() );
1873}
1874
1875CanonicalForm
1876CanonicalForm::genOne() const
1877{
1878    int what = is_imm( value );
1879    if ( what == FFMARK )
1880        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1L ) );
1881    else  if ( what == GFMARK )
1882        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1L ) );
1883    else  if ( what )
1884        return CanonicalForm( CFFactory::basic( IntegerDomain, 1L ) );
1885    else
1886        return CanonicalForm( value->genOne() );
1887}
1888
1889/** exponentiation **/
1890CanonicalForm
1891power ( const CanonicalForm & f, int n )
1892{
1893  ASSERT( n >= 0, "illegal exponent" );
1894  if ( f.isZero() )
1895    return CanonicalForm(0L);
1896  else  if ( f.isOne() )
1897    return f;
1898  else  if ( f == -1 )
1899  {
1900    if ( n % 2 == 0 )
1901      return CanonicalForm(1L);
1902    else
1903      return CanonicalForm(-1L);
1904  }
1905  else  if ( n == 0 )
1906    return CanonicalForm(1L);
1907
1908  //else if (f.inGF())
1909  //{
1910  //}
1911  else
1912  {
1913    CanonicalForm g,h;
1914    h=f;
1915    while(n%2==0)
1916    {
1917      h*=h;
1918      n/=2;
1919    }
1920    g=h;
1921    while(1)
1922    {
1923      n/=2;
1924      if(n==0)
1925        return g;
1926      h*=h;
1927      if(n%2!=0) g*=h;
1928    }
1929  }
1930}
1931
1932/** exponentiation **/
1933CanonicalForm
1934power ( const Variable & v, int n )
1935{
1936    //ASSERT( n >= 0, "illegal exponent" );
1937    if ( n == 0 )
1938        return 1;
1939    else  if ( n == 1 )
1940        return v;
1941    else  if (( v.level() < 0 ) && (hasMipo(v)))
1942    {
1943        CanonicalForm result( v, n-1 );
1944        return result * v;
1945    }
1946    else
1947        return CanonicalForm( v, n );
1948}
1949
1950/** switches **/
1951void
1952On( int sw )
1953{
1954    cf_glob_switches.On( sw );
1955}
1956
1957/** switches **/
1958void
1959Off( int sw )
1960{
1961    cf_glob_switches.Off( sw );
1962}
1963
1964/** switches **/
1965bool
1966isOn( int sw )
1967{
1968    return cf_glob_switches.isOn( sw );
1969}
1970
Note: See TracBrowser for help on using the repository browser.