Changeset b60ef7 in git


Ignore:
Timestamp:
Oct 10, 1997, 12:40:17 PM (27 years ago)
Author:
Jens Schmidt <schmidt@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
24725be4e952e9877b5415819b58210ed69fae34
Parents:
bbe7bc4d7a630981554453c6e36683b9d34502a9
Message:
	* canonicalform.cc (LC, degree( v ), tailcoeff, deriv): slightly
	  speeded up

	* canonicalform.cc (Lc): new method.  Declaration added.


git-svn-id: file:///usr/local/Singular/svn/trunk@800 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • factory/canonicalform.cc

    rbbe7bc rb60ef7  
    11/* emacs edit mode for this file is -*- C++ -*- */
    2 /* $Id: canonicalform.cc,v 1.19 1997-09-24 10:52:23 schmidt Exp $ */
     2/* $Id: canonicalform.cc,v 1.20 1997-10-10 10:40:17 schmidt Exp $ */
    33
    44#include <config.h>
     
    2323#endif /* NOSTREAMIO */
    2424
     25//{{{ initialization
     26int initializeGMP();
     27int initializeCharacteristic();
     28#ifdef SINGULAR
     29int mmInit(void);
     30#endif
     31
     32int
     33initCanonicalForm( void )
     34{
     35    static bool initialized = false;
     36    if ( ! initialized ) {
     37#if (defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)) || defined (SINGULAR)
     38        (void)mmInit();
     39#endif
     40
     41        (void)initializeCharacteristic();
     42        (void)initializeGMP();
     43        initPT();
     44        initialized = true;
     45    }
     46    return 1;
     47}
     48//}}}
     49
     50//{{{ constructors, destructors, selectors
    2551CanonicalForm::CanonicalForm() : value( CFFactory::basic( (int)0 ) )
    2652{
     
    6692}
    6793
     94CanonicalForm
     95CanonicalForm::deepCopy() const
     96{
     97    if ( is_imm( value ) )
     98        return *this;
     99    else
     100        return CanonicalForm( value->deepCopyObject() );
     101}
     102//}}}
     103
     104//{{{ predicates
    68105bool
    69106CanonicalForm::isOne() const
     
    184221}
    185222
     223bool
     224CanonicalForm::isFFinGF() const
     225{
     226    return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
     227}
     228
     229bool
     230CanonicalForm::isUnivariate() const
     231{
     232    if ( is_imm( value ) )
     233        return false;
     234    else
     235        return value->isUnivariate();
     236}
     237//}}}
     238
     239//{{{ conversion functions
    186240int
    187241CanonicalForm::intval() const
     
    192246        return value->intval();
    193247}
    194 
    195 CanonicalForm
    196 CanonicalForm::lc() const
    197 {
    198     if ( is_imm( value ) )
    199         return *this;
    200     else
    201         return value->lc();
    202 }
    203 
    204 CanonicalForm
    205 CanonicalForm::LC() const
    206 {
    207     if ( inBaseDomain() )
    208         return *this;
    209     else
    210         return value->LC();
    211 }
    212 
    213 CanonicalForm
    214 CanonicalForm::LC( const Variable & v ) const
    215 {
    216     if ( inBaseDomain() )
    217         return *this;
    218     else  if ( v == mvar() )
    219         return value->LC();
    220     else {
    221         CanonicalForm f = swapvar( *this, v, mvar() );
    222         if ( f.mvar() == mvar() )
    223             return swapvar( f.value->LC(), v, mvar() );
    224         else
    225             return *this;
    226     }
    227 }
    228 
    229 //{{{ int CanonicalForm::degree() const
    230 //{{{ docu
    231 //
    232 // degree() - return degree in main variable.
    233 //
    234 // Returns -1 for the zero polynomial.
    235 //
    236 //}}}
    237 int
    238 CanonicalForm::degree() const
    239 {
    240     if ( isZero() )
    241         return -1;
    242     else  if ( is_imm( value ) )
    243         return 0;
    244     else
    245         return value->degree();
    246 }
    247 //}}}
    248 
    249 //{{{ int CanonicalForm::degree( const Variable & v ) const
    250 //{{{ docu
    251 //
    252 // degree() - return degree in variable v.
    253 //
    254 // Returns -1 for the zero polynomial.
    255 //
    256 // Note: If v is less than the main variable of CO we have to swap
    257 // variables which may be quite expensive.  Calculating the degree in
    258 // respect to an algebraic variable may fail.
    259 //
    260 //}}}
    261 int
    262 CanonicalForm::degree( const Variable & v ) const
    263 {
    264     if ( isZero() )
    265         return -1;
    266     else  if ( is_imm( value ) )
    267         return 0;
    268     else  if ( inBaseDomain() )
    269         return 0;
    270 
    271     Variable x = mvar();
    272     if ( v == x )
    273         return value->degree();
    274     else  if ( v > x )
    275         // relatively to v, f is in a coefficient ring
    276         return 0;
    277     else {
    278         // v < mvar(), make v main variable
    279         CanonicalForm f = swapvar( *this, v, x );
    280         if ( f.mvar() == x )
    281             return f.value->degree();
    282         else
    283             // in this case, we lost our main variable because
    284             // v did not occur in CO
    285             return 0;
    286     }
    287 }
    288 //}}}
    289 
    290 int
    291 CanonicalForm::taildegree() const
    292 {
    293     if ( isZero() )
    294         return -1;
    295     else  if ( is_imm( value ) )
    296         return 0;
    297     else
    298         return value->taildegree();
    299 }
    300 
    301 CanonicalForm
    302 CanonicalForm::tailcoeff() const
    303 {
    304     if ( inCoeffDomain() )
    305         return *this;
    306     else
    307         return value->tailcoeff();
    308 }
    309 
    310 int
    311 CanonicalForm::level() const
    312 {
    313     if ( is_imm( value ) )
    314         return LEVELBASE;
    315     else
    316         return value->level();
    317 }
    318 
    319 Variable
    320 CanonicalForm::mvar() const
    321 {
    322     if ( is_imm( value ) || value->inBaseDomain() )
    323         return Variable();
    324     else
    325         return value->variable();
    326 }
    327 
    328 CanonicalForm
    329 CanonicalForm::num() const
    330 {
    331     if ( is_imm( value ) )
    332         return *this;
    333     else
    334         return CanonicalForm( value->num() );
    335 }
    336 
    337 CanonicalForm
    338 CanonicalForm::den() const
    339 {
    340     if ( is_imm( value ) )
    341         return 1;
    342     else
    343         return CanonicalForm( value->den() );
    344 }
    345 
    346 CanonicalForm
    347 CanonicalForm::deepCopy() const
    348 {
    349     if ( is_imm( value ) )
    350         return *this;
    351     else
    352         return CanonicalForm( value->deepCopyObject() );
    353 }
    354 
    355 CanonicalForm
    356 CanonicalForm::gcd( const CanonicalForm & ) const
    357 {
    358 //    return ::gcd( *this, f );
    359     return 1;
    360 }
    361 
    362 //{{{ CanonicalForm CanonicalForm::deriv () const
    363 //{{{ docu
    364 //
    365 // deriv() - return the formal derivation of CO.
    366 //
    367 // Derives CO with respect to its main variable.  Returns zero if
    368 // f is in a coefficient domain.
    369 //
    370 //}}}
    371 CanonicalForm
    372 CanonicalForm::deriv () const
    373 {
    374     if ( inCoeffDomain() )
    375         return 0;
    376     else {
    377         CanonicalForm res = 0;
    378         Variable x = mvar();
    379         for ( CFIterator i = *this; i.hasTerms(); i++ )
    380             if ( i.exp() > 0 )
    381                 res += power( x, i.exp()-1 ) * i.coeff() * i.exp();
    382         return res;
    383     }
    384 }
    385 //}}}
    386 
    387 //{{{ CanonicalForm CanonicalForm::deriv ( const Variable & x ) const
    388 //{{{ docu
    389 //
    390 // deriv() - return the formal derivation of CO with respect to x.
    391 //
    392 // x should be a polynomial variable.  Returns zero if f is in a
    393 // coefficient domain.
    394 //
    395 // Timing Note (for the developer): I tried the same without
    396 // 'Variable y = mvar()', replacing each occurence of y directly
    397 // with 'mvar()'.  It turned out that this version is slower in all
    398 // cases.
    399 //
    400 //}}}
    401 CanonicalForm
    402 CanonicalForm::deriv ( const Variable & x ) const
    403 {
    404     ASSERT( x.level() > 0, "cannot derive with respect to algebraic variables" );
    405     if ( inCoeffDomain() )
    406         return 0;
    407 
    408     Variable y = mvar();
    409     if ( x > y )
    410         return 0;
    411     else if ( x == y )
    412         return deriv();
    413     else {
    414         CanonicalForm result;
    415         CFIterator i;
    416         for ( i = *this; i.hasTerms(); i++ )
    417             result += i.coeff().deriv( x ) * power( y, i.exp() );
    418         return result;
    419     }
    420 }
    421 //}}}
    422 
    423 CanonicalForm
    424 CanonicalForm::genCoeff( int type, int i )
    425 {
    426     return CanonicalForm( CFFactory::basic( type, i ) );
    427 }
    428 
    429 CanonicalForm
    430 CanonicalForm::genZero() const
    431 {
    432     int what = is_imm( value );
    433     if ( what == FFMARK )
    434         return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0 ) );
    435     else  if ( what == GFMARK )
    436         return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0 ) );
    437     else  if ( what )
    438         return CanonicalForm( CFFactory::basic( IntegerDomain, 0 ) );
    439     else
    440         return CanonicalForm( value->genZero() );
    441 }
    442 
    443 CanonicalForm
    444 CanonicalForm::genOne() const
    445 {
    446     int what = is_imm( value );
    447     if ( what == FFMARK )
    448         return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1 ) );
    449     else  if ( what == GFMARK )
    450         return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1 ) );
    451     else  if ( what )
    452         return CanonicalForm( CFFactory::basic( IntegerDomain, 1 ) );
    453     else
    454         return CanonicalForm( value->genOne() );
    455 }
    456 
    457 bool
    458 CanonicalForm::isUnivariate() const
    459 {
    460     if ( is_imm( value ) )
    461         return false;
    462     else
    463         return value->isUnivariate();
    464 }
    465 
    466 #ifndef NOSTREAMIO
    467 void
    468 CanonicalForm::print( ostream & os, char * str ) const
    469 {
    470     if ( is_imm( value ) )
    471         imm_print( os, value, str );
    472     else
    473         value->print( os, str );
    474 }
    475 #endif /* NOSTREAMIO */
    476 
    477 bool
    478 operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
    479 {
    480     int what = is_imm( lhs.value );
    481     if ( what )
    482         if ( what == is_imm( rhs.value ) )
    483             return lhs.value == rhs.value;
    484         else
    485             return false;
    486     else  if ( is_imm( rhs.value ) )
    487         return false;
    488     else  if ( lhs.level() == rhs.level() )
    489         if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
    490             return lhs.value->comparesame( rhs.value ) == 0;
    491         else
    492             return rhs.value->comparesame( lhs.value ) == 0;
    493     else
    494         return false;
    495 }
    496 
    497 bool
    498 operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
    499 {
    500     int what = is_imm( lhs.value );
    501     if ( what )
    502         if ( what == is_imm( rhs.value ) )
    503             return lhs.value != rhs.value;
    504         else
    505             return true;
    506     else  if ( is_imm( rhs.value ) )
    507         return true;
    508     else  if ( lhs.level() == rhs.level() )
    509         if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
    510             return lhs.value->comparesame( rhs.value ) != 0;
    511         else
    512             return rhs.value->comparesame( lhs.value ) != 0;
    513     else
    514         return true;
    515 }
    516 
    517 bool
    518 operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
    519 {
    520     int what = is_imm( lhs.value );
    521     if ( what ) {
    522         ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
    523         if ( what == INTMARK ) {
    524             if ( what == is_imm( rhs.value ) )
    525                 return imm_cmp( lhs.value, rhs.value ) > 0;
    526             else
    527                 return rhs.value->comparecoeff( lhs.value ) < 0;
    528         }
    529         else  if ( what == FFMARK ) {
    530             if ( what == is_imm( rhs.value ) )
    531                 return imm_cmp_p( lhs.value, rhs.value ) > 0;
    532             else
    533                 return rhs.value->comparecoeff( lhs.value ) < 0;
    534         }
    535         else {
    536             if ( what == is_imm( rhs.value ) )
    537                 return imm_cmp_gf( lhs.value, rhs.value ) > 0;
    538             else
    539                 return rhs.value->comparecoeff( lhs.value ) < 0;
    540         }
    541     }
    542     else  if ( is_imm( rhs.value ) )
    543         return lhs.value->comparecoeff( rhs.value ) > 0;
    544     else  if ( lhs.level() == rhs.level() )
    545         if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
    546             return lhs.value->comparesame( rhs.value ) > 0;
    547         else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
    548             return lhs.value->comparecoeff( lhs.value ) > 0;
    549         else
    550             return rhs.value->comparecoeff( lhs.value ) < 0;
    551     else
    552         return lhs.value->level() > rhs.value->level();
    553 }
    554 
    555 bool
    556 operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
    557 {
    558     int what = is_imm( lhs.value );
    559     if ( what ) {
    560         ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
    561         if ( what == INTMARK ) {
    562             if ( what == is_imm( rhs.value ) )
    563                 return imm_cmp( lhs.value, rhs.value ) < 0;
    564             else
    565                 return rhs.value->comparecoeff( lhs.value ) > 0;
    566         }
    567         else  if ( what == FFMARK ) {
    568             if ( what == is_imm( rhs.value ) )
    569                 return imm_cmp( lhs.value, rhs.value ) < 0;
    570             else
    571                 return rhs.value->comparecoeff( lhs.value ) > 0;
    572         }
    573         else {
    574             if ( what == is_imm( rhs.value ) )
    575                 return imm_cmp( lhs.value, rhs.value ) < 0;
    576             else
    577                 return rhs.value->comparecoeff( lhs.value ) > 0;
    578         }
    579     }
    580     else  if ( is_imm( rhs.value ) )
    581         return lhs.value->comparecoeff( rhs.value ) < 0;
    582     else  if ( lhs.level() == rhs.level() )
    583         if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
    584             return lhs.value->comparesame( rhs.value ) < 0;
    585         else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
    586             return lhs.value->comparecoeff( lhs.value ) < 0;
    587         else
    588             return rhs.value->comparecoeff( lhs.value ) > 0;
    589     else
    590         return lhs.value->level() < rhs.value->level();
    591 }
    592 
    593 CanonicalForm&
    594 CanonicalForm::operator = ( const CanonicalForm & cf )
    595 {
    596     if ( this != &cf ) {
    597         if ( (! is_imm( value )) && value->deleteObject() )
    598             delete value;
    599         value = (is_imm( cf.value )) ? cf.value : cf.value->copyObject();
    600     }
    601     return *this;
    602 }
    603 
    604 CanonicalForm&
    605 CanonicalForm::operator = ( const int cf )
    606 {
    607     if ( (! is_imm( value )) && value->deleteObject() )
    608         delete value;
    609     value = CFFactory::basic( cf );
    610     return *this;
    611 }
    612 
    613 CanonicalForm&
    614 CanonicalForm::operator += ( const CanonicalForm & cf )
    615 {
    616     int what = is_imm( value );
    617     if ( what ) {
    618         ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
    619         if ( (what = is_imm( cf.value )) == FFMARK )
    620             value = imm_add_p( value, cf.value );
    621         else  if ( what == GFMARK )
    622             value = imm_add_gf( value, cf.value );
    623         else  if ( what )
    624             value = imm_add( value, cf.value );
    625         else {
    626             InternalCF * dummy = cf.value->copyObject();
    627             value = dummy->addcoeff( value );
    628         }
    629     }
    630     else  if ( is_imm( cf.value ) )
    631         value = value->addcoeff( cf.value );
    632     else  if ( value->level() == cf.value->level() ) {
    633         if ( value->levelcoeff() == cf.value->levelcoeff() )
    634             value = value->addsame( cf.value );
    635         else  if ( value->levelcoeff() > cf.value->levelcoeff() )
    636             value = value->addcoeff( cf.value );
    637         else {
    638             InternalCF * dummy = cf.value->copyObject();
    639             dummy = dummy->addcoeff( value );
    640             if ( value->deleteObject() ) delete value;
    641             value = dummy;
    642         }
    643     }
    644     else  if ( level() > cf.level() )
    645         value = value->addcoeff( cf.value );
    646     else {
    647         InternalCF * dummy = cf.value->copyObject();
    648         dummy = dummy->addcoeff( value );
    649         if ( value->deleteObject() ) delete value;
    650         value = dummy;
    651     }
    652     return *this;
    653 }
    654 
    655 CanonicalForm&
    656 CanonicalForm::operator -= ( const CanonicalForm & cf )
    657 {
    658     int what = is_imm( value );
    659     if ( what ) {
    660         ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
    661         if ( (what = is_imm( cf.value )) == FFMARK )
    662             value = imm_sub_p( value, cf.value );
    663         else  if ( what == GFMARK )
    664             value = imm_sub_gf( value, cf.value );
    665         else  if ( what )
    666             value = imm_sub( value, cf.value );
    667         else {
    668             InternalCF * dummy = cf.value->copyObject();
    669             value = dummy->subcoeff( value, true );
    670         }
    671     }
    672     else  if ( is_imm( cf.value ) )
    673         value = value->subcoeff( cf.value, false );
    674     else  if ( value->level() == cf.value->level() ) {
    675         if ( value->levelcoeff() == cf.value->levelcoeff() )
    676             value = value->subsame( cf.value );
    677         else  if ( value->levelcoeff() > cf.value->levelcoeff() )
    678             value = value->subcoeff( cf.value, false );
    679         else {
    680             InternalCF * dummy = cf.value->copyObject();
    681             dummy = dummy->subcoeff( value, true );
    682             if ( value->deleteObject() ) delete value;
    683             value = dummy;
    684         }
    685     }
    686     else  if ( level() > cf.level() )
    687         value = value->subcoeff( cf.value, false );
    688     else {
    689         InternalCF * dummy = cf.value->copyObject();
    690         dummy = dummy->subcoeff( value, true );
    691         if ( value->deleteObject() ) delete value;
    692         value = dummy;
    693     }
    694     return *this;
    695 }
    696 
    697 CanonicalForm&
    698 CanonicalForm::operator *= ( const CanonicalForm & cf )
    699 {
    700     int what = is_imm( value );
    701     if ( what ) {
    702         ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
    703         if ( (what = is_imm( cf.value )) == FFMARK )
    704             value = imm_mul_p( value, cf.value );
    705         else  if ( what == GFMARK )
    706             value = imm_mul_gf( value, cf.value );
    707         else  if ( what )
    708             value = imm_mul( value, cf.value );
    709         else {
    710             InternalCF * dummy = cf.value->copyObject();
    711             value = dummy->mulcoeff( value );
    712         }
    713     }
    714     else  if ( is_imm( cf.value ) )
    715         value = value->mulcoeff( cf.value );
    716     else  if ( value->level() == cf.value->level() ) {
    717         if ( value->levelcoeff() == cf.value->levelcoeff() )
    718             value = value->mulsame( cf.value );
    719         else  if ( value->levelcoeff() > cf.value->levelcoeff() )
    720             value = value->mulcoeff( cf.value );
    721         else {
    722             InternalCF * dummy = cf.value->copyObject();
    723             dummy = dummy->mulcoeff( value );
    724             if ( value->deleteObject() ) delete value;
    725             value = dummy;
    726         }
    727     }
    728     else  if ( level() > cf.level() )
    729         value = value->mulcoeff( cf.value );
    730     else {
    731         InternalCF * dummy = cf.value->copyObject();
    732         dummy = dummy->mulcoeff( value );
    733         if ( value->deleteObject() ) delete value;
    734         value = dummy;
    735     }
    736     return *this;
    737 }
    738 
    739 CanonicalForm&
    740 CanonicalForm::operator /= ( const CanonicalForm & cf )
    741 {
    742     int what = is_imm( value );
    743     if ( what ) {
    744         ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
    745         if ( (what = is_imm( cf.value )) == FFMARK )
    746             value = imm_div_p( value, cf.value );
    747         else  if ( what == GFMARK )
    748             value = imm_div_gf( value, cf.value );
    749         else  if ( what )
    750             value = imm_divrat( value, cf.value );
    751         else {
    752             InternalCF * dummy = cf.value->copyObject();
    753             value = dummy->dividecoeff( value, true );
    754         }
    755     }
    756     else  if ( is_imm( cf.value ) )
    757         value = value->dividecoeff( cf.value, false );
    758     else  if ( value->level() == cf.value->level() ) {
    759         if ( value->levelcoeff() == cf.value->levelcoeff() )
    760             value = value->dividesame( cf.value );
    761         else  if ( value->levelcoeff() > cf.value->levelcoeff() )
    762             value = value->dividecoeff( cf.value, false );
    763         else {
    764             InternalCF * dummy = cf.value->copyObject();
    765             dummy = dummy->dividecoeff( value, true );
    766             if ( value->deleteObject() ) delete value;
    767             value = dummy;
    768         }
    769     }
    770     else  if ( level() > cf.level() )
    771         value = value->dividecoeff( cf.value, false );
    772     else {
    773         InternalCF * dummy = cf.value->copyObject();
    774         dummy = dummy->dividecoeff( value, true );
    775         if ( value->deleteObject() ) delete value;
    776         value = dummy;
    777     }
    778     return *this;
    779 }
    780 
    781 CanonicalForm&
    782 CanonicalForm::div ( const CanonicalForm & cf )
    783 {
    784     int what = is_imm( value );
    785     if ( what ) {
    786         ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
    787         if ( (what = is_imm( cf.value )) == FFMARK )
    788             value = imm_div_p( value, cf.value );
    789         else  if ( what == GFMARK )
    790             value = imm_div_gf( value, cf.value );
    791         else  if ( what )
    792             value = imm_div( value, cf.value );
    793         else {
    794             InternalCF * dummy = cf.value->copyObject();
    795             value = dummy->divcoeff( value, true );
    796         }
    797     }
    798     else  if ( is_imm( cf.value ) )
    799         value = value->divcoeff( cf.value, false );
    800     else  if ( value->level() == cf.value->level() ) {
    801         if ( value->levelcoeff() == cf.value->levelcoeff() )
    802             value = value->divsame( cf.value );
    803         else  if ( value->levelcoeff() > cf.value->levelcoeff() )
    804             value = value->divcoeff( cf.value, false );
    805         else {
    806             InternalCF * dummy = cf.value->copyObject();
    807             dummy = dummy->divcoeff( value, true );
    808             if ( value->deleteObject() ) delete value;
    809             value = dummy;
    810         }
    811     }
    812     else  if ( level() > cf.level() )
    813         value = value->divcoeff( cf.value, false );
    814     else {
    815         InternalCF * dummy = cf.value->copyObject();
    816         dummy = dummy->divcoeff( value, true );
    817         if ( value->deleteObject() ) delete value;
    818         value = dummy;
    819     }
    820     return *this;
    821 }
    822 
    823 CanonicalForm&
    824 CanonicalForm::operator %= ( const CanonicalForm& cf )
    825 {
    826     int what = is_imm( value );
    827     if ( what ) {
    828         ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
    829         if ( (what = is_imm( cf.value )) == FFMARK )
    830             value = imm_mod_p( value, cf.value );
    831         else  if ( what == GFMARK )
    832             value = imm_mod_gf( value, cf.value );
    833         else  if ( what )
    834             value = imm_mod( value, cf.value );
    835         else {
    836             InternalCF * dummy = cf.value->copyObject();
    837             value = dummy->modulocoeff( value, true );
    838         }
    839     }
    840     else  if ( is_imm( cf.value ) )
    841         value = value->modulocoeff( cf.value, false );
    842     else  if ( value->level() == cf.value->level() ) {
    843         if ( value->levelcoeff() == cf.value->levelcoeff() )
    844             value = value->modulosame( cf.value );
    845         else  if ( value->levelcoeff() > cf.value->levelcoeff() )
    846             value = value->modulocoeff( cf.value, false );
    847         else {
    848             InternalCF * dummy = cf.value->copyObject();
    849             dummy = dummy->modulocoeff( value, true );
    850             if ( value->deleteObject() ) delete value;
    851             value = dummy;
    852         }
    853     }
    854     else  if ( level() > cf.level() )
    855         value = value->modulocoeff( cf.value, false );
    856     else {
    857         InternalCF * dummy = cf.value->copyObject();
    858         dummy = dummy->modulocoeff( value, true );
    859         if ( value->deleteObject() ) delete value;
    860         value = dummy;
    861     }
    862     return *this;
    863 }
    864 
    865 CanonicalForm&
    866 CanonicalForm::mod( const CanonicalForm & cf )
    867 {
    868     int what = is_imm( value );
    869     if ( what ) {
    870         ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
    871         if ( (what = is_imm( cf.value )) == FFMARK )
    872             value = imm_mod_p( value, cf.value );
    873         else  if ( what == GFMARK )
    874             value = imm_mod_gf( value, cf.value );
    875         else  if ( what )
    876             value = imm_mod( value, cf.value );
    877         else {
    878             InternalCF * dummy = cf.value->copyObject();
    879             value = dummy->modcoeff( value, true );
    880         }
    881     }
    882     else  if ( is_imm( cf.value ) )
    883         value = value->modcoeff( cf.value, false );
    884     else  if ( value->level() == cf.value->level() ) {
    885         if ( value->levelcoeff() == cf.value->levelcoeff() )
    886             value = value->modsame( cf.value );
    887         else  if ( value->levelcoeff() > cf.value->levelcoeff() )
    888             value = value->modcoeff( cf.value, false );
    889         else {
    890             InternalCF * dummy = cf.value->copyObject();
    891             dummy = dummy->modcoeff( value, true );
    892             if ( value->deleteObject() ) delete value;
    893             value = dummy;
    894         }
    895     }
    896     else  if ( level() > cf.level() )
    897         value = value->modcoeff( cf.value, false );
    898     else {
    899         InternalCF * dummy = cf.value->copyObject();
    900         dummy = dummy->modcoeff( value, true );
    901         if ( value->deleteObject() ) delete value;
    902         value = dummy;
    903     }
    904     return *this;
    905 }
    906 
    907 CanonicalForm
    908 operator - ( const CanonicalForm & cf )
    909 {
    910     CanonicalForm result( cf );
    911     int what = is_imm( result.value );
    912     if ( what == FFMARK )
    913         result.value = imm_neg_p( result.value );
    914     else  if ( what == GFMARK )
    915         result.value = imm_neg_gf( result.value );
    916     else  if ( what )
    917         result.value = imm_neg( result.value );
    918     else
    919         result.value = result.value->neg();
    920     return result;
    921 }
    922 
    923 CanonicalForm
    924 operator + ( const CanonicalForm &c1, const CanonicalForm &c2 )
    925 {
    926     CanonicalForm result( c1 );
    927     result += c2;
    928     return result;
    929 }
    930 
    931 CanonicalForm
    932 operator - ( const CanonicalForm &c1, const CanonicalForm &c2 )
    933 {
    934     CanonicalForm result( c1 );
    935     result -= c2;
    936     return result;
    937 }
    938 
    939 CanonicalForm
    940 operator * ( const CanonicalForm &c1, const CanonicalForm &c2 )
    941 {
    942     CanonicalForm result( c1 );
    943     result *= c2;
    944     return result;
    945 }
    946 
    947 CanonicalForm
    948 operator / ( const CanonicalForm &c1, const CanonicalForm &c2 )
    949 {
    950     CanonicalForm result( c1 );
    951     result /= c2;
    952     return result;
    953 }
    954 
    955 CanonicalForm
    956 div ( const CanonicalForm &c1, const CanonicalForm &c2 )
    957 {
    958     CanonicalForm result( c1 );
    959     result.div( c2 );
    960     return result;
    961 }
    962 
    963 CanonicalForm
    964 mod ( const CanonicalForm &c1, const CanonicalForm &c2 )
    965 {
    966     CanonicalForm result( c1 );
    967     result.mod( c2 );
    968     return result;
    969 }
    970 
    971 CanonicalForm
    972 operator % ( const CanonicalForm &c1, const CanonicalForm &c2 )
    973 {
    974     CanonicalForm result( c1 );
    975     result %= c2;
    976     return result;
    977 }
    978 
    979 void
    980 divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
    981 {
    982     InternalCF * qq = 0, * rr = 0;
    983     int what = is_imm( f.value );
    984     if ( what )
    985         if ( is_imm( g.value ) ) {
    986             if ( what == FFMARK )
    987                 imm_divrem_p( f.value, g.value, qq, rr );
    988             else  if ( what == GFMARK )
    989                 imm_divrem_gf( f.value, g.value, qq, rr );
    990             else
    991                 imm_divrem( f.value, g.value, qq, rr );
    992         }
    993         else
    994             g.value->divremcoeff( f.value, qq, rr, true );
    995     else  if ( (what=is_imm( g.value )) )
    996         f.value->divremcoeff( g.value, qq, rr, false );
    997     else  if ( f.value->level() == g.value->level() )
    998         if ( f.value->levelcoeff() == g.value->levelcoeff() )
    999             f.value->divremsame( g.value, qq, rr );
    1000         else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
    1001             f.value->divremcoeff( g.value, qq, rr, false );
    1002         else
    1003             g.value->divremcoeff( f.value, qq, rr, true );
    1004     else  if ( f.value->level() > g.value->level() )
    1005         f.value->divremcoeff( g.value, qq, rr, false );
    1006     else
    1007         g.value->divremcoeff( f.value, qq, rr, true );
    1008     ASSERT( qq != 0 && rr != 0, "error in divrem" );
    1009     q = CanonicalForm( qq );
    1010     r = CanonicalForm( rr );
    1011 }
    1012 
    1013 bool
    1014 divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
    1015 {
    1016     InternalCF * qq = 0, * rr = 0;
    1017     int what = is_imm( f.value );
    1018     bool result = true;
    1019     if ( what )
    1020         if ( is_imm( g.value ) ) {
    1021             if ( what == FFMARK )
    1022                 imm_divrem_p( f.value, g.value, qq, rr );
    1023             else  if ( what == GFMARK )
    1024                 imm_divrem_gf( f.value, g.value, qq, rr );
    1025             else
    1026                 imm_divrem( f.value, g.value, qq, rr );
    1027         }
    1028         else
    1029             result = g.value->divremcoefft( f.value, qq, rr, true );
    1030     else  if ( (what=is_imm( g.value )) )
    1031         result = f.value->divremcoefft( g.value, qq, rr, false );
    1032     else  if ( f.value->level() == g.value->level() )
    1033         if ( f.value->levelcoeff() == g.value->levelcoeff() )
    1034             result = f.value->divremsamet( g.value, qq, rr );
    1035         else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
    1036             result = f.value->divremcoefft( g.value, qq, rr, false );
    1037         else
    1038             result = g.value->divremcoefft( f.value, qq, rr, true );
    1039     else  if ( f.value->level() > g.value->level() )
    1040         result = f.value->divremcoefft( g.value, qq, rr, false );
    1041     else
    1042         result = g.value->divremcoefft( f.value, qq, rr, true );
    1043     if ( result ) {
    1044         ASSERT( qq != 0 && rr != 0, "error in divrem" );
    1045         q = CanonicalForm( qq );
    1046         r = CanonicalForm( rr );
    1047     }
    1048     else {
    1049         q = 0; r = 0;
    1050     }
    1051     return result;
    1052 }
    1053 
    1054 #ifndef NOSTREAMIO
    1055 ostream&
    1056 operator << ( ostream & os, const CanonicalForm & cf )
    1057 {
    1058     cf.print( os, "" );
    1059     return os;
    1060 }
    1061 #endif /* NOSTREAMIO */
    1062 
    1063 #ifndef NOSTREAMIO
    1064 istream&
    1065 operator >> ( istream & is, CanonicalForm & cf )
    1066 {
    1067 #ifndef SINGULAR
    1068     cf = readCF( is );
    1069     return is;
    1070 #else /* SINGULAR */
    1071     return 0;
    1072 #endif /* SINGULAR */
    1073 }
    1074 #endif /* NOSTREAMIO */
    1075 
    1076 CanonicalForm
    1077 CanonicalForm::operator () ( const CanonicalForm & f ) const
    1078 {
    1079     if ( inBaseDomain() )
    1080         return *this;
    1081     else {
    1082         CanonicalForm result = 0;
    1083         for ( CFIterator i = *this; i.hasTerms(); i++ )
    1084             if ( i.exp() == 0 )
    1085                 result += i.coeff();
    1086             else
    1087                 result += power( f, i.exp() ) * i.coeff();
    1088         return result;
    1089     }
    1090 }
    1091 
    1092 CanonicalForm
    1093 CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
    1094 {
    1095     if ( inBaseDomain() || v > mvar() )
    1096         return *this;
    1097     else  if ( v == mvar() ) {
    1098         CanonicalForm result = 0;
    1099         for ( CFIterator i = *this; i.hasTerms(); i++ )
    1100             if ( i.exp() == 0 )
    1101                 result += i.coeff();
    1102             else
    1103                 result += power( f, i.exp() ) * i.coeff();
    1104         return result;
    1105     }
    1106     else {
    1107         CanonicalForm G = swapvar( *this, v, Variable::highest() );
    1108         if ( G.mvar() != Variable::highest() )
    1109             return *this;
    1110         CanonicalForm result = 0;
    1111         for ( CFIterator i = G; i.hasTerms(); ++i )
    1112             if ( i.exp() == 0 )
    1113                 result += i.coeff();
    1114             else
    1115                 result += power( f, i.exp() ) * i.coeff();
    1116         return result;
    1117     }
    1118 }
    1119 
    1120 CanonicalForm
    1121 CanonicalForm::operator[] ( int i ) const
    1122 {
    1123     return value->coeff( i );
    1124 }
    1125 
    1126 //{{{ int CanonicalForm::sign () const
    1127 //{{{ docu
    1128 //
    1129 // sign() - return sign of CO.
    1130 //
    1131 // If CO is an integer or a rational number, the sign is defined
    1132 // as usual.  If CO is an element of a prime power domain or in a
    1133 // finite field and SW_SYMMETRIC_FF is on the sign of CO is the
    1134 // sign of the symmetric representation of CO.  If CO is in GF(q)
    1135 // or in a finite field and SW_SYMMETRIC_FF is off, the sign of
    1136 // CO is zero iff CO is zero, otherwise the sign is one.
    1137 //
    1138 // If CO is a polynomial or in an extension of one of the base
    1139 // domains, the sign of CO is the sign of its leading
    1140 // coefficient.
    1141 //
    1142 // See also: InternalCF::sign(), InternalInteger::sign(),
    1143 // InternalPrimePower::sign(), InternalRational::sign(),
    1144 // InternalPoly::sign(), imm_sign(), gf_sign()
    1145 //
    1146 //}}}
    1147 int
    1148 CanonicalForm::sign () const
    1149 {
    1150     if ( is_imm( value ) )
    1151         return imm_sign( value );
    1152     else
    1153         return value->sign();
    1154 }
    1155 //}}}
    1156 
    1157 CanonicalForm
    1158 power ( const CanonicalForm & f, int n )
    1159 {
    1160     ASSERT( n >= 0, "illegal exponent" );
    1161     if ( f == 0 )
    1162         return 0;
    1163     else  if ( f == 1 )
    1164         return f;
    1165     else  if ( f == -1 ) {
    1166         if ( n % 2 == 0 )
    1167             return 1;
    1168         else
    1169             return -1;
    1170     }
    1171     else  if ( n == 0 )
    1172         return 1;
    1173     else {
    1174         CanonicalForm result = f;
    1175         for ( int i = 1; i < n; i++ )
    1176             result *= f;
    1177         return result;
    1178     }
    1179 }
    1180 
    1181 CanonicalForm
    1182 power ( const Variable & v, int n )
    1183 {
    1184     ASSERT( n >= 0, "illegal exponent" );
    1185     if ( n == 0 )
    1186         return 1;
    1187     else  if ( n == 1 )
    1188         return v;
    1189     else  if ( v.level() < 0 ) {
    1190         CanonicalForm result( v, n-1 );
    1191         return result * v;
    1192     }
    1193     else
    1194         return CanonicalForm( v, n );
    1195 }
    1196 
    1197 
    1198 int initializeGMP();
    1199 int initializeCharacteristic();
    1200 #ifdef SINGULAR
    1201 int mmInit(void);
    1202 #endif
    1203 
    1204 int
    1205 initCanonicalForm( void )
    1206 {
    1207     static bool initialized = false;
    1208     if ( ! initialized ) {
    1209 #if (defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)) || defined (SINGULAR)
    1210         (void)mmInit();
    1211 #endif
    1212 
    1213         (void)initializeCharacteristic();
    1214         (void)initializeGMP();
    1215         initPT();
    1216         initialized = true;
    1217     }
    1218     return 1;
    1219 }
    1220 
    1221248
    1222249CanonicalForm
     
    1274301    }
    1275302}
    1276 
    1277 void
    1278 On( int sw )
    1279 {
    1280     cf_glob_switches.On( sw );
    1281 }
    1282 
    1283 void
    1284 Off( int sw )
    1285 {
    1286     cf_glob_switches.Off( sw );
    1287 }
    1288 
    1289 bool
    1290 isOn( int sw )
    1291 {
    1292     return cf_glob_switches.isOn( sw );
    1293 }
    1294 
    1295 bool
    1296 CanonicalForm::isFFinGF() const
    1297 {
    1298     return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
    1299 }
     303//}}}
     304
     305//{{{ CanonicalForm CanonicalForm::lc (), Lc (), LC (), LC ( v ) const
     306//{{{ docu
     307//
     308// lc(), Lc(), LC() - leading coefficient functions.
     309//
     310// All methods return CO if CO is in a base domain.
     311//
     312// lc() returns the leading coefficient of CO with respect to
     313// lexicographic ordering.  Elements in an algebraic extension
     314// are considered polynomials so lc() always returns a leading
     315// coefficient in a base domain.  This method is useful to get
     316// the base domain over which CO is defined.
     317//
     318// Lc() returns the leading coefficient of CO with respect to
     319// lexicographic ordering.  In contrast to lc() elements in an
     320// algebraic extension are considered coefficients so Lc() always
     321// returns a leading coefficient in a coefficient domain.
     322//
     323// LC() returns the leading coefficient of CO where CO is
     324// considered a univariate polynomial in its main variable.  An
     325// element of an algebraic extension is considered an univariate
     326// polynomial, too.
     327//
     328// LC( v ) returns the leading coefficient of CO where CO is
     329// considered an univariate polynomial in the polynomial variable
     330// v.
     331// Note: If v is less than the main variable of CO we have to
     332// swap variables which may be quite expensive.
     333//
     334// Examples:
     335// Let x < y be polynomial variables, a an algebraic variable.
     336//
     337// (3*a*x*y^2+y+x).lc() = 3
     338// (3*a*x*y^2+y+x).Lc() = 3*a
     339// (3*a*x*y^2+y+x).LC() = 3*a*x
     340// (3*a*x*y^2+y+x).LC( x ) = 3*a*y^2+1
     341//
     342// (3*a^2+4*a).lc() = 3
     343// (3*a^2+4*a).Lc() = 3*a^2+4*a
     344// (3*a^2+4*a).LC() = 3
     345// (3*a^2+4*a).LC( x ) = 3*a^2+4*a
     346//
     347// See also: InternalCF::lc(), InternalCF::Lc(), InternalCF::LC(),
     348// InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
     349// ::lc(), ::Lc(), ::LC(), ::LC( v )
     350//
     351//}}}
     352CanonicalForm
     353CanonicalForm::lc () const
     354{
     355    if ( is_imm( value ) )
     356        return *this;
     357    else
     358        return value->lc();
     359}
     360
     361CanonicalForm
     362CanonicalForm::Lc () const
     363{
     364    if ( is_imm( value ) || value->inCoeffDomain() )
     365        return *this;
     366    else
     367        return value->Lc();
     368}
     369
     370CanonicalForm
     371CanonicalForm::LC () const
     372{
     373    if ( is_imm( value ) )
     374        return *this;
     375    else
     376        return value->LC();
     377}
     378
     379CanonicalForm
     380CanonicalForm::LC ( const Variable & v ) const
     381{
     382    if ( is_imm( value ) || value->inCoeffDomain() )
     383        return *this;
     384
     385    Variable x = value->variable();
     386    if ( v > x )
     387        return *this;
     388    else if ( v == x )
     389        return value->LC();
     390    else {
     391        CanonicalForm f = swapvar( *this, v, x );
     392        if ( f.mvar() == x )
     393            return swapvar( f.value->LC(), v, x );
     394        else
     395            // v did not occur in f
     396            return *this;
     397    }
     398}
     399//}}}
     400
     401//{{{ int CanonicalForm::degree (), degree ( v ) const
     402//{{{ docu
     403//
     404// degree() - degree methods.
     405//
     406// Both methods returns -1 for the zero polynomial and 0 if
     407// CO is in a base domain.
     408//
     409// degree() returns the degree of CO in its main variable.
     410// Elements in an algebraic extension are considered polynomials.
     411// degree( v ) returns the degree of CO with respect to v.
     412// Elements in an algebraic extension are considered polynomials,
     413// and v may be algebraic.
     414//
     415// See also: InternalCf::degree(), InternalPoly::degree(),
     416// ::degree(), ::degree( v )
     417//
     418//}}}
     419int
     420CanonicalForm::degree() const
     421{
     422    if ( isZero() )
     423        return -1;
     424    else  if ( is_imm( value ) )
     425        return 0;
     426    else
     427        return value->degree();
     428}
     429
     430int
     431CanonicalForm::degree( const Variable & v ) const
     432{
     433    if ( isZero() )
     434        return -1;
     435    else  if ( is_imm( value ) || value->inBaseDomain() )
     436        return 0;
     437
     438    Variable x = value->variable();
     439    if ( v == x )
     440        return value->degree();
     441    else  if ( v > x )
     442        // relatively to v, f is in a coefficient ring
     443        return 0;
     444    else {
     445        int coeffdeg, result = 0;
     446        // search for maximum of coefficient degree
     447        for ( CFIterator i = *this; i.hasTerms(); i++ ) {
     448            coeffdeg = i.coeff().degree( v );
     449            if ( coeffdeg > result )
     450                result = coeffdeg;
     451        }
     452        return result;
     453    }
     454}
     455//}}}
     456
     457//{{{ CanonicalForm CanonicalForm::tailcoeff (), int CanonicalForm::taildegree () const
     458//{{{ docu
     459//
     460// tailcoeff(), taildegree() - return last coefficient and
     461//   degree, resp.
     462//
     463// tailcoeff() returns the coefficient of the term with the least
     464// degree in CO.  Elements in an algebraic extension are
     465// considered coefficients.
     466//
     467// taildegree() returns -1 for the zero polynomial, 0 if CO is in
     468// a base domain, the least degree of all terms occuring in CO
     469// otherwise.  In contrast to tailcoeff(), elements in an
     470// algebraic extension are considered polynomials, not
     471// coefficients, and such may have a taildegree larger than
     472// zero.
     473//
     474// See also: InternalCF::tailcoeff(), InternalCF::tailcoeff(),
     475// InternalPoly::tailcoeff(), InternalPoly::taildegree,
     476// ::tailcoeff(), ::taildegree()
     477//
     478//}}}
     479CanonicalForm
     480CanonicalForm::tailcoeff () const
     481{
     482    if ( is_imm( value ) || value->inCoeffDomain() )
     483        return *this;
     484    else
     485        return value->tailcoeff();
     486}
     487
     488int
     489CanonicalForm::taildegree () const
     490{
     491    if ( isZero() )
     492        return -1;
     493    else  if ( is_imm( value ) )
     494        return 0;
     495    else
     496        return value->taildegree();
     497}
     498//}}}
     499
     500//{{{ int CanonicalForm::level (), Variable CanonicalForm::mvar () const
     501//{{{ docu
     502//
     503// level(), mvar() - return level and main variable of CO.
     504//
     505// level() returns the level of CO.  For a list of the levels,
     506// see cf_defs.h.
     507//
     508// mvar() returns the main variable of CO or Variable() if CO is
     509// in a base domain.
     510//
     511// See also: InternalCF::level(), InternalCF::variable(),
     512// InternalPoly::level(), InternalPoly::variable(), ::level(),
     513// ::mvar()
     514//
     515//}}}
     516int
     517CanonicalForm::level () const
     518{
     519    if ( is_imm( value ) )
     520        return LEVELBASE;
     521    else
     522        return value->level();
     523}
     524
     525Variable
     526CanonicalForm::mvar () const
     527{
     528    if ( is_imm( value ) || value->inBaseDomain() )
     529        return Variable();
     530    else
     531        return value->variable();
     532}
     533//}}}
     534
     535//{{{ CanonicalForm CanonicalForm::num (), den () const
     536//{{{ docu
     537//
     538// num(), den() - return numinator and denominator of CO.
     539//
     540// num() returns the numinator of CO if CO is a rational number,
     541// CO itself otherwise.
     542//
     543// den() returns the denominator of CO if CO is a rational
     544// number, 1 (from the current domain!) otherwise.
     545//
     546// See also: InternalCF::num(), InternalCF::den(),
     547// InternalRational::num(), InternalRational::den(), ::num(),
     548// ::den()
     549//
     550//}}}
     551CanonicalForm
     552CanonicalForm::num () const
     553{
     554    if ( is_imm( value ) )
     555        return *this;
     556    else
     557        return CanonicalForm( value->num() );
     558}
     559
     560CanonicalForm
     561CanonicalForm::den () const
     562{
     563    if ( is_imm( value ) )
     564        return 1;
     565    else
     566        return CanonicalForm( value->den() );
     567}
     568//}}}
     569
     570//{{{ assignment operators
     571CanonicalForm&
     572CanonicalForm::operator = ( const CanonicalForm & cf )
     573{
     574    if ( this != &cf ) {
     575        if ( (! is_imm( value )) && value->deleteObject() )
     576            delete value;
     577        value = (is_imm( cf.value )) ? cf.value : cf.value->copyObject();
     578    }
     579    return *this;
     580}
     581
     582CanonicalForm&
     583CanonicalForm::operator = ( const int cf )
     584{
     585    if ( (! is_imm( value )) && value->deleteObject() )
     586        delete value;
     587    value = CFFactory::basic( cf );
     588    return *this;
     589}
     590
     591CanonicalForm&
     592CanonicalForm::operator += ( const CanonicalForm & cf )
     593{
     594    int what = is_imm( value );
     595    if ( what ) {
     596        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
     597        if ( (what = is_imm( cf.value )) == FFMARK )
     598            value = imm_add_p( value, cf.value );
     599        else  if ( what == GFMARK )
     600            value = imm_add_gf( value, cf.value );
     601        else  if ( what )
     602            value = imm_add( value, cf.value );
     603        else {
     604            InternalCF * dummy = cf.value->copyObject();
     605            value = dummy->addcoeff( value );
     606        }
     607    }
     608    else  if ( is_imm( cf.value ) )
     609        value = value->addcoeff( cf.value );
     610    else  if ( value->level() == cf.value->level() ) {
     611        if ( value->levelcoeff() == cf.value->levelcoeff() )
     612            value = value->addsame( cf.value );
     613        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
     614            value = value->addcoeff( cf.value );
     615        else {
     616            InternalCF * dummy = cf.value->copyObject();
     617            dummy = dummy->addcoeff( value );
     618            if ( value->deleteObject() ) delete value;
     619            value = dummy;
     620        }
     621    }
     622    else  if ( level() > cf.level() )
     623        value = value->addcoeff( cf.value );
     624    else {
     625        InternalCF * dummy = cf.value->copyObject();
     626        dummy = dummy->addcoeff( value );
     627        if ( value->deleteObject() ) delete value;
     628        value = dummy;
     629    }
     630    return *this;
     631}
     632
     633CanonicalForm&
     634CanonicalForm::operator -= ( const CanonicalForm & cf )
     635{
     636    int what = is_imm( value );
     637    if ( what ) {
     638        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
     639        if ( (what = is_imm( cf.value )) == FFMARK )
     640            value = imm_sub_p( value, cf.value );
     641        else  if ( what == GFMARK )
     642            value = imm_sub_gf( value, cf.value );
     643        else  if ( what )
     644            value = imm_sub( value, cf.value );
     645        else {
     646            InternalCF * dummy = cf.value->copyObject();
     647            value = dummy->subcoeff( value, true );
     648        }
     649    }
     650    else  if ( is_imm( cf.value ) )
     651        value = value->subcoeff( cf.value, false );
     652    else  if ( value->level() == cf.value->level() ) {
     653        if ( value->levelcoeff() == cf.value->levelcoeff() )
     654            value = value->subsame( cf.value );
     655        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
     656            value = value->subcoeff( cf.value, false );
     657        else {
     658            InternalCF * dummy = cf.value->copyObject();
     659            dummy = dummy->subcoeff( value, true );
     660            if ( value->deleteObject() ) delete value;
     661            value = dummy;
     662        }
     663    }
     664    else  if ( level() > cf.level() )
     665        value = value->subcoeff( cf.value, false );
     666    else {
     667        InternalCF * dummy = cf.value->copyObject();
     668        dummy = dummy->subcoeff( value, true );
     669        if ( value->deleteObject() ) delete value;
     670        value = dummy;
     671    }
     672    return *this;
     673}
     674
     675CanonicalForm&
     676CanonicalForm::operator *= ( const CanonicalForm & cf )
     677{
     678    int what = is_imm( value );
     679    if ( what ) {
     680        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
     681        if ( (what = is_imm( cf.value )) == FFMARK )
     682            value = imm_mul_p( value, cf.value );
     683        else  if ( what == GFMARK )
     684            value = imm_mul_gf( value, cf.value );
     685        else  if ( what )
     686            value = imm_mul( value, cf.value );
     687        else {
     688            InternalCF * dummy = cf.value->copyObject();
     689            value = dummy->mulcoeff( value );
     690        }
     691    }
     692    else  if ( is_imm( cf.value ) )
     693        value = value->mulcoeff( cf.value );
     694    else  if ( value->level() == cf.value->level() ) {
     695        if ( value->levelcoeff() == cf.value->levelcoeff() )
     696            value = value->mulsame( cf.value );
     697        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
     698            value = value->mulcoeff( cf.value );
     699        else {
     700            InternalCF * dummy = cf.value->copyObject();
     701            dummy = dummy->mulcoeff( value );
     702            if ( value->deleteObject() ) delete value;
     703            value = dummy;
     704        }
     705    }
     706    else  if ( level() > cf.level() )
     707        value = value->mulcoeff( cf.value );
     708    else {
     709        InternalCF * dummy = cf.value->copyObject();
     710        dummy = dummy->mulcoeff( value );
     711        if ( value->deleteObject() ) delete value;
     712        value = dummy;
     713    }
     714    return *this;
     715}
     716
     717CanonicalForm&
     718CanonicalForm::operator /= ( const CanonicalForm & cf )
     719{
     720    int what = is_imm( value );
     721    if ( what ) {
     722        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
     723        if ( (what = is_imm( cf.value )) == FFMARK )
     724            value = imm_div_p( value, cf.value );
     725        else  if ( what == GFMARK )
     726            value = imm_div_gf( value, cf.value );
     727        else  if ( what )
     728            value = imm_divrat( value, cf.value );
     729        else {
     730            InternalCF * dummy = cf.value->copyObject();
     731            value = dummy->dividecoeff( value, true );
     732        }
     733    }
     734    else  if ( is_imm( cf.value ) )
     735        value = value->dividecoeff( cf.value, false );
     736    else  if ( value->level() == cf.value->level() ) {
     737        if ( value->levelcoeff() == cf.value->levelcoeff() )
     738            value = value->dividesame( cf.value );
     739        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
     740            value = value->dividecoeff( cf.value, false );
     741        else {
     742            InternalCF * dummy = cf.value->copyObject();
     743            dummy = dummy->dividecoeff( value, true );
     744            if ( value->deleteObject() ) delete value;
     745            value = dummy;
     746        }
     747    }
     748    else  if ( level() > cf.level() )
     749        value = value->dividecoeff( cf.value, false );
     750    else {
     751        InternalCF * dummy = cf.value->copyObject();
     752        dummy = dummy->dividecoeff( value, true );
     753        if ( value->deleteObject() ) delete value;
     754        value = dummy;
     755    }
     756    return *this;
     757}
     758
     759CanonicalForm&
     760CanonicalForm::div ( const CanonicalForm & cf )
     761{
     762    int what = is_imm( value );
     763    if ( what ) {
     764        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
     765        if ( (what = is_imm( cf.value )) == FFMARK )
     766            value = imm_div_p( value, cf.value );
     767        else  if ( what == GFMARK )
     768            value = imm_div_gf( value, cf.value );
     769        else  if ( what )
     770            value = imm_div( value, cf.value );
     771        else {
     772            InternalCF * dummy = cf.value->copyObject();
     773            value = dummy->divcoeff( value, true );
     774        }
     775    }
     776    else  if ( is_imm( cf.value ) )
     777        value = value->divcoeff( cf.value, false );
     778    else  if ( value->level() == cf.value->level() ) {
     779        if ( value->levelcoeff() == cf.value->levelcoeff() )
     780            value = value->divsame( cf.value );
     781        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
     782            value = value->divcoeff( cf.value, false );
     783        else {
     784            InternalCF * dummy = cf.value->copyObject();
     785            dummy = dummy->divcoeff( value, true );
     786            if ( value->deleteObject() ) delete value;
     787            value = dummy;
     788        }
     789    }
     790    else  if ( level() > cf.level() )
     791        value = value->divcoeff( cf.value, false );
     792    else {
     793        InternalCF * dummy = cf.value->copyObject();
     794        dummy = dummy->divcoeff( value, true );
     795        if ( value->deleteObject() ) delete value;
     796        value = dummy;
     797    }
     798    return *this;
     799}
     800
     801CanonicalForm&
     802CanonicalForm::operator %= ( const CanonicalForm& cf )
     803{
     804    int what = is_imm( value );
     805    if ( what ) {
     806        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
     807        if ( (what = is_imm( cf.value )) == FFMARK )
     808            value = imm_mod_p( value, cf.value );
     809        else  if ( what == GFMARK )
     810            value = imm_mod_gf( value, cf.value );
     811        else  if ( what )
     812            value = imm_mod( value, cf.value );
     813        else {
     814            InternalCF * dummy = cf.value->copyObject();
     815            value = dummy->modulocoeff( value, true );
     816        }
     817    }
     818    else  if ( is_imm( cf.value ) )
     819        value = value->modulocoeff( cf.value, false );
     820    else  if ( value->level() == cf.value->level() ) {
     821        if ( value->levelcoeff() == cf.value->levelcoeff() )
     822            value = value->modulosame( cf.value );
     823        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
     824            value = value->modulocoeff( cf.value, false );
     825        else {
     826            InternalCF * dummy = cf.value->copyObject();
     827            dummy = dummy->modulocoeff( value, true );
     828            if ( value->deleteObject() ) delete value;
     829            value = dummy;
     830        }
     831    }
     832    else  if ( level() > cf.level() )
     833        value = value->modulocoeff( cf.value, false );
     834    else {
     835        InternalCF * dummy = cf.value->copyObject();
     836        dummy = dummy->modulocoeff( value, true );
     837        if ( value->deleteObject() ) delete value;
     838        value = dummy;
     839    }
     840    return *this;
     841}
     842
     843CanonicalForm&
     844CanonicalForm::mod( const CanonicalForm & cf )
     845{
     846    int what = is_imm( value );
     847    if ( what ) {
     848        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
     849        if ( (what = is_imm( cf.value )) == FFMARK )
     850            value = imm_mod_p( value, cf.value );
     851        else  if ( what == GFMARK )
     852            value = imm_mod_gf( value, cf.value );
     853        else  if ( what )
     854            value = imm_mod( value, cf.value );
     855        else {
     856            InternalCF * dummy = cf.value->copyObject();
     857            value = dummy->modcoeff( value, true );
     858        }
     859    }
     860    else  if ( is_imm( cf.value ) )
     861        value = value->modcoeff( cf.value, false );
     862    else  if ( value->level() == cf.value->level() ) {
     863        if ( value->levelcoeff() == cf.value->levelcoeff() )
     864            value = value->modsame( cf.value );
     865        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
     866            value = value->modcoeff( cf.value, false );
     867        else {
     868            InternalCF * dummy = cf.value->copyObject();
     869            dummy = dummy->modcoeff( value, true );
     870            if ( value->deleteObject() ) delete value;
     871            value = dummy;
     872        }
     873    }
     874    else  if ( level() > cf.level() )
     875        value = value->modcoeff( cf.value, false );
     876    else {
     877        InternalCF * dummy = cf.value->copyObject();
     878        dummy = dummy->modcoeff( value, true );
     879        if ( value->deleteObject() ) delete value;
     880        value = dummy;
     881    }
     882    return *this;
     883}
     884//}}}
     885
     886//{{{ evaluation operators
     887CanonicalForm
     888CanonicalForm::operator () ( const CanonicalForm & f ) const
     889{
     890    if ( inBaseDomain() )
     891        return *this;
     892    else {
     893        CanonicalForm result = 0;
     894        for ( CFIterator i = *this; i.hasTerms(); i++ )
     895            if ( i.exp() == 0 )
     896                result += i.coeff();
     897            else
     898                result += power( f, i.exp() ) * i.coeff();
     899        return result;
     900    }
     901}
     902
     903CanonicalForm
     904CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
     905{
     906    if ( inBaseDomain() || v > mvar() )
     907        return *this;
     908    else  if ( v == mvar() ) {
     909        CanonicalForm result = 0;
     910        for ( CFIterator i = *this; i.hasTerms(); i++ )
     911            if ( i.exp() == 0 )
     912                result += i.coeff();
     913            else
     914                result += power( f, i.exp() ) * i.coeff();
     915        return result;
     916    }
     917    else {
     918        CanonicalForm G = swapvar( *this, v, Variable::highest() );
     919        if ( G.mvar() != Variable::highest() )
     920            return *this;
     921        CanonicalForm result = 0;
     922        for ( CFIterator i = G; i.hasTerms(); ++i )
     923            if ( i.exp() == 0 )
     924                result += i.coeff();
     925            else
     926                result += power( f, i.exp() ) * i.coeff();
     927        return result;
     928    }
     929}
     930//}}}
     931
     932//{{{ CanonicalForm CanonicalForm::operator[] ( int i ) const
     933CanonicalForm
     934CanonicalForm::operator[] ( int i ) const
     935{
     936    return value->coeff( i );
     937}
     938//}}}
     939
     940//{{{ CanonicalForm CanonicalForm::deriv (), deriv ( x )
     941//{{{ docu
     942//
     943// deriv() - return the formal derivation of CO.
     944//
     945// deriv() derives CO with respect to its main variable.  Returns
     946// zero if f is in a coefficient domain.
     947//
     948// deriv( x ) derives CO with respect to x.  x should be a
     949// polynomial variable.  Returns zero if f is in a coefficient
     950// domain.
     951//
     952// See also: ::deriv()
     953//
     954//}}}
     955CanonicalForm
     956CanonicalForm::deriv () const
     957{
     958    if ( is_imm( value ) || value->inCoeffDomain() )
     959        return 0;
     960    else {
     961        CanonicalForm result = 0;
     962        Variable x = value->variable();
     963        for ( CFIterator i = *this; i.hasTerms(); i++ )
     964            if ( i.exp() > 0 )
     965                result += power( x, i.exp()-1 ) * i.coeff() * i.exp();
     966        return result;
     967    }
     968}
     969
     970CanonicalForm
     971CanonicalForm::deriv ( const Variable & x ) const
     972{
     973    ASSERT( x.level() > 0, "cannot derive with respect to algebraic variables" );
     974    if ( is_imm( value ) || value->inCoeffDomain() )
     975        return 0;
     976
     977    Variable y = value->variable();
     978    if ( x > y )
     979        return 0;
     980    else if ( x == y )
     981        return deriv();
     982    else {
     983        CanonicalForm result = 0;
     984        for ( CFIterator i = *this; i.hasTerms(); i++ )
     985            result += i.coeff().deriv( x ) * power( y, i.exp() );
     986        return result;
     987    }
     988}
     989//}}}
     990
     991//{{{ int CanonicalForm::sign () const
     992//{{{ docu
     993//
     994// sign() - return sign of CO.
     995//
     996// If CO is an integer or a rational number, the sign is defined
     997// as usual.  If CO is an element of a prime power domain or in a
     998// finite field and SW_SYMMETRIC_FF is on the sign of CO is the
     999// sign of the symmetric representation of CO.  If CO is in GF(q)
     1000// or in a finite field and SW_SYMMETRIC_FF is off, the sign of
     1001// CO is zero iff CO is zero, otherwise the sign is one.
     1002//
     1003// If CO is a polynomial or in an extension of one of the base
     1004// domains, the sign of CO is the sign of its leading
     1005// coefficient.
     1006//
     1007// See also: InternalCF::sign(), InternalInteger::sign(),
     1008// InternalPrimePower::sign(), InternalRational::sign(),
     1009// InternalPoly::sign(), imm_sign(), gf_sign()
     1010//
     1011//}}}
     1012int
     1013CanonicalForm::sign () const
     1014{
     1015    if ( is_imm( value ) )
     1016        return imm_sign( value );
     1017    else
     1018        return value->sign();
     1019}
     1020//}}}
    13001021
    13011022//{{{ CanonicalForm CanonicalForm::sqrt () const
     
    13691090//}}}
    13701091
    1371 bool
    1372 divides ( const CanonicalForm & f, const CanonicalForm & g )
    1373 {
    1374     if ( g.level() > 0 && g.level() == f.level() )
    1375         if ( divides( f.tailcoeff(), g.tailcoeff() ) && divides( f.LC(), g.LC() ) ) {
    1376             CanonicalForm q, r;
    1377             bool ok = divremt( g, f, q, r );
    1378             return ok && r == 0;
    1379         }
     1092//{{{ CanonicalForm CanonicalForm::gcd( const CanonicalForm & ) const
     1093CanonicalForm
     1094CanonicalForm::gcd( const CanonicalForm & ) const
     1095{
     1096//    return ::gcd( *this, f );
     1097    return 1;
     1098}
     1099//}}}
     1100
     1101//{{{ comparison operators
     1102bool
     1103operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
     1104{
     1105    int what = is_imm( lhs.value );
     1106    if ( what )
     1107        if ( what == is_imm( rhs.value ) )
     1108            return lhs.value == rhs.value;
    13801109        else
    13811110            return false;
    1382     else {
    1383         CanonicalForm q, r;
    1384         bool ok = divremt( g, f, q, r );
    1385         return ok && r == 0;
    1386     }
    1387 }
     1111    else  if ( is_imm( rhs.value ) )
     1112        return false;
     1113    else  if ( lhs.level() == rhs.level() )
     1114        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
     1115            return lhs.value->comparesame( rhs.value ) == 0;
     1116        else
     1117            return rhs.value->comparesame( lhs.value ) == 0;
     1118    else
     1119        return false;
     1120}
     1121
     1122bool
     1123operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
     1124{
     1125    int what = is_imm( lhs.value );
     1126    if ( what )
     1127        if ( what == is_imm( rhs.value ) )
     1128            return lhs.value != rhs.value;
     1129        else
     1130            return true;
     1131    else  if ( is_imm( rhs.value ) )
     1132        return true;
     1133    else  if ( lhs.level() == rhs.level() )
     1134        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
     1135            return lhs.value->comparesame( rhs.value ) != 0;
     1136        else
     1137            return rhs.value->comparesame( lhs.value ) != 0;
     1138    else
     1139        return true;
     1140}
     1141
     1142bool
     1143operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
     1144{
     1145    int what = is_imm( lhs.value );
     1146    if ( what ) {
     1147        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
     1148        if ( what == INTMARK ) {
     1149            if ( what == is_imm( rhs.value ) )
     1150                return imm_cmp( lhs.value, rhs.value ) > 0;
     1151            else
     1152                return rhs.value->comparecoeff( lhs.value ) < 0;
     1153        }
     1154        else  if ( what == FFMARK ) {
     1155            if ( what == is_imm( rhs.value ) )
     1156                return imm_cmp_p( lhs.value, rhs.value ) > 0;
     1157            else
     1158                return rhs.value->comparecoeff( lhs.value ) < 0;
     1159        }
     1160        else {
     1161            if ( what == is_imm( rhs.value ) )
     1162                return imm_cmp_gf( lhs.value, rhs.value ) > 0;
     1163            else
     1164                return rhs.value->comparecoeff( lhs.value ) < 0;
     1165        }
     1166    }
     1167    else  if ( is_imm( rhs.value ) )
     1168        return lhs.value->comparecoeff( rhs.value ) > 0;
     1169    else  if ( lhs.level() == rhs.level() )
     1170        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
     1171            return lhs.value->comparesame( rhs.value ) > 0;
     1172        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
     1173            return lhs.value->comparecoeff( lhs.value ) > 0;
     1174        else
     1175            return rhs.value->comparecoeff( lhs.value ) < 0;
     1176    else
     1177        return lhs.value->level() > rhs.value->level();
     1178}
     1179
     1180bool
     1181operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
     1182{
     1183    int what = is_imm( lhs.value );
     1184    if ( what ) {
     1185        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
     1186        if ( what == INTMARK ) {
     1187            if ( what == is_imm( rhs.value ) )
     1188                return imm_cmp( lhs.value, rhs.value ) < 0;
     1189            else
     1190                return rhs.value->comparecoeff( lhs.value ) > 0;
     1191        }
     1192        else  if ( what == FFMARK ) {
     1193            if ( what == is_imm( rhs.value ) )
     1194                return imm_cmp( lhs.value, rhs.value ) < 0;
     1195            else
     1196                return rhs.value->comparecoeff( lhs.value ) > 0;
     1197        }
     1198        else {
     1199            if ( what == is_imm( rhs.value ) )
     1200                return imm_cmp( lhs.value, rhs.value ) < 0;
     1201            else
     1202                return rhs.value->comparecoeff( lhs.value ) > 0;
     1203        }
     1204    }
     1205    else  if ( is_imm( rhs.value ) )
     1206        return lhs.value->comparecoeff( rhs.value ) < 0;
     1207    else  if ( lhs.level() == rhs.level() )
     1208        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
     1209            return lhs.value->comparesame( rhs.value ) < 0;
     1210        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
     1211            return lhs.value->comparecoeff( lhs.value ) < 0;
     1212        else
     1213            return rhs.value->comparecoeff( lhs.value ) > 0;
     1214    else
     1215        return lhs.value->level() < rhs.value->level();
     1216}
     1217//}}}
     1218
     1219//{{{ arithmetic operators
     1220CanonicalForm
     1221operator - ( const CanonicalForm & cf )
     1222{
     1223    CanonicalForm result( cf );
     1224    int what = is_imm( result.value );
     1225    if ( what == FFMARK )
     1226        result.value = imm_neg_p( result.value );
     1227    else  if ( what == GFMARK )
     1228        result.value = imm_neg_gf( result.value );
     1229    else  if ( what )
     1230        result.value = imm_neg( result.value );
     1231    else
     1232        result.value = result.value->neg();
     1233    return result;
     1234}
     1235
     1236CanonicalForm
     1237operator + ( const CanonicalForm &c1, const CanonicalForm &c2 )
     1238{
     1239    CanonicalForm result( c1 );
     1240    result += c2;
     1241    return result;
     1242}
     1243
     1244CanonicalForm
     1245operator - ( const CanonicalForm &c1, const CanonicalForm &c2 )
     1246{
     1247    CanonicalForm result( c1 );
     1248    result -= c2;
     1249    return result;
     1250}
     1251
     1252CanonicalForm
     1253operator * ( const CanonicalForm &c1, const CanonicalForm &c2 )
     1254{
     1255    CanonicalForm result( c1 );
     1256    result *= c2;
     1257    return result;
     1258}
     1259
     1260CanonicalForm
     1261operator / ( const CanonicalForm &c1, const CanonicalForm &c2 )
     1262{
     1263    CanonicalForm result( c1 );
     1264    result /= c2;
     1265    return result;
     1266}
     1267
     1268CanonicalForm
     1269div ( const CanonicalForm &c1, const CanonicalForm &c2 )
     1270{
     1271    CanonicalForm result( c1 );
     1272    result.div( c2 );
     1273    return result;
     1274}
     1275
     1276CanonicalForm
     1277mod ( const CanonicalForm &c1, const CanonicalForm &c2 )
     1278{
     1279    CanonicalForm result( c1 );
     1280    result.mod( c2 );
     1281    return result;
     1282}
     1283
     1284CanonicalForm
     1285operator % ( const CanonicalForm &c1, const CanonicalForm &c2 )
     1286{
     1287    CanonicalForm result( c1 );
     1288    result %= c2;
     1289    return result;
     1290}
     1291
     1292void
     1293divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
     1294{
     1295    InternalCF * qq = 0, * rr = 0;
     1296    int what = is_imm( f.value );
     1297    if ( what )
     1298        if ( is_imm( g.value ) ) {
     1299            if ( what == FFMARK )
     1300                imm_divrem_p( f.value, g.value, qq, rr );
     1301            else  if ( what == GFMARK )
     1302                imm_divrem_gf( f.value, g.value, qq, rr );
     1303            else
     1304                imm_divrem( f.value, g.value, qq, rr );
     1305        }
     1306        else
     1307            g.value->divremcoeff( f.value, qq, rr, true );
     1308    else  if ( (what=is_imm( g.value )) )
     1309        f.value->divremcoeff( g.value, qq, rr, false );
     1310    else  if ( f.value->level() == g.value->level() )
     1311        if ( f.value->levelcoeff() == g.value->levelcoeff() )
     1312            f.value->divremsame( g.value, qq, rr );
     1313        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
     1314            f.value->divremcoeff( g.value, qq, rr, false );
     1315        else
     1316            g.value->divremcoeff( f.value, qq, rr, true );
     1317    else  if ( f.value->level() > g.value->level() )
     1318        f.value->divremcoeff( g.value, qq, rr, false );
     1319    else
     1320        g.value->divremcoeff( f.value, qq, rr, true );
     1321    ASSERT( qq != 0 && rr != 0, "error in divrem" );
     1322    q = CanonicalForm( qq );
     1323    r = CanonicalForm( rr );
     1324}
     1325
     1326bool
     1327divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
     1328{
     1329    InternalCF * qq = 0, * rr = 0;
     1330    int what = is_imm( f.value );
     1331    bool result = true;
     1332    if ( what )
     1333        if ( is_imm( g.value ) ) {
     1334            if ( what == FFMARK )
     1335                imm_divrem_p( f.value, g.value, qq, rr );
     1336            else  if ( what == GFMARK )
     1337                imm_divrem_gf( f.value, g.value, qq, rr );
     1338            else
     1339                imm_divrem( f.value, g.value, qq, rr );
     1340        }
     1341        else
     1342            result = g.value->divremcoefft( f.value, qq, rr, true );
     1343    else  if ( (what=is_imm( g.value )) )
     1344        result = f.value->divremcoefft( g.value, qq, rr, false );
     1345    else  if ( f.value->level() == g.value->level() )
     1346        if ( f.value->levelcoeff() == g.value->levelcoeff() )
     1347            result = f.value->divremsamet( g.value, qq, rr );
     1348        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
     1349            result = f.value->divremcoefft( g.value, qq, rr, false );
     1350        else
     1351            result = g.value->divremcoefft( f.value, qq, rr, true );
     1352    else  if ( f.value->level() > g.value->level() )
     1353        result = f.value->divremcoefft( g.value, qq, rr, false );
     1354    else
     1355        result = g.value->divremcoefft( f.value, qq, rr, true );
     1356    if ( result ) {
     1357        ASSERT( qq != 0 && rr != 0, "error in divrem" );
     1358        q = CanonicalForm( qq );
     1359        r = CanonicalForm( rr );
     1360    }
     1361    else {
     1362        q = 0; r = 0;
     1363    }
     1364    return result;
     1365}
     1366//}}}
     1367
     1368//{{{ input/output
     1369#ifndef NOSTREAMIO
     1370void
     1371CanonicalForm::print( ostream & os, char * str ) const
     1372{
     1373    if ( is_imm( value ) )
     1374        imm_print( os, value, str );
     1375    else
     1376        value->print( os, str );
     1377}
     1378
     1379ostream&
     1380operator << ( ostream & os, const CanonicalForm & cf )
     1381{
     1382    cf.print( os, "" );
     1383    return os;
     1384}
     1385
     1386istream&
     1387operator >> ( istream & is, CanonicalForm & cf )
     1388{
     1389#ifndef SINGULAR
     1390    cf = readCF( is );
     1391    return is;
     1392#else /* SINGULAR */
     1393    return 0;
     1394#endif /* SINGULAR */
     1395}
     1396#endif /* NOSTREAMIO */
     1397//}}}
     1398
     1399//{{{ genCoeff(), genOne(), genZero()
     1400CanonicalForm
     1401CanonicalForm::genCoeff( int type, int i )
     1402{
     1403    return CanonicalForm( CFFactory::basic( type, i ) );
     1404}
     1405
     1406CanonicalForm
     1407CanonicalForm::genZero() const
     1408{
     1409    int what = is_imm( value );
     1410    if ( what == FFMARK )
     1411        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0 ) );
     1412    else  if ( what == GFMARK )
     1413        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0 ) );
     1414    else  if ( what )
     1415        return CanonicalForm( CFFactory::basic( IntegerDomain, 0 ) );
     1416    else
     1417        return CanonicalForm( value->genZero() );
     1418}
     1419
     1420CanonicalForm
     1421CanonicalForm::genOne() const
     1422{
     1423    int what = is_imm( value );
     1424    if ( what == FFMARK )
     1425        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1 ) );
     1426    else  if ( what == GFMARK )
     1427        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1 ) );
     1428    else  if ( what )
     1429        return CanonicalForm( CFFactory::basic( IntegerDomain, 1 ) );
     1430    else
     1431        return CanonicalForm( value->genOne() );
     1432}
     1433//}}}
     1434
     1435//{{{ exponentiation
     1436CanonicalForm
     1437power ( const CanonicalForm & f, int n )
     1438{
     1439    ASSERT( n >= 0, "illegal exponent" );
     1440    if ( f == 0 )
     1441        return 0;
     1442    else  if ( f == 1 )
     1443        return f;
     1444    else  if ( f == -1 ) {
     1445        if ( n % 2 == 0 )
     1446            return 1;
     1447        else
     1448            return -1;
     1449    }
     1450    else  if ( n == 0 )
     1451        return 1;
     1452    else {
     1453        CanonicalForm result = f;
     1454        for ( int i = 1; i < n; i++ )
     1455            result *= f;
     1456        return result;
     1457    }
     1458}
     1459
     1460CanonicalForm
     1461power ( const Variable & v, int n )
     1462{
     1463    ASSERT( n >= 0, "illegal exponent" );
     1464    if ( n == 0 )
     1465        return 1;
     1466    else  if ( n == 1 )
     1467        return v;
     1468    else  if ( v.level() < 0 ) {
     1469        CanonicalForm result( v, n-1 );
     1470        return result * v;
     1471    }
     1472    else
     1473        return CanonicalForm( v, n );
     1474}
     1475//}}}
     1476
     1477//{{{ switches
     1478void
     1479On( int sw )
     1480{
     1481    cf_glob_switches.On( sw );
     1482}
     1483
     1484void
     1485Off( int sw )
     1486{
     1487    cf_glob_switches.Off( sw );
     1488}
     1489
     1490bool
     1491isOn( int sw )
     1492{
     1493    return cf_glob_switches.isOn( sw );
     1494}
     1495//}}}
Note: See TracChangeset for help on using the changeset viewer.