Loading...
Searching...
No Matches
canonicalform.cc
Go to the documentation of this file.
/* emacs edit mode for this file is -*- C++ -*- */
#include "config.h"
#include "cf_assert.h"
#include "cf_factory.h"
#include "cf_defs.h"
#include "cf_globals.h"
#include "canonicalform.h"
#include "cf_iter.h"
#include "int_cf.h"
#include "cf_algorithm.h"
#include "imm.h"
#include "int_pp.h"
#include "gfops.h"
#include "facMul.h"
#include "facAlgFuncUtil.h"
#include "FLINTconvert.h"
#include "cf_binom.h"
#ifndef NOSTREAMIO
CanonicalForm readCF( ISTREAM& );
#endif /* NOSTREAMIO */
/** constructors, destructors, selectors **/
CanonicalForm::CanonicalForm( const char * str, const int base ) : value( CFFactory::basic( str, base ) )
{
}
InternalCF*
CanonicalForm::getval() const
{
if ( is_imm( value ) )
return value;
else
return value->copyObject();
}
CanonicalForm
CanonicalForm::deepCopy() const
{
if ( is_imm( value ) )
return *this;
else
return CanonicalForm( value->deepCopyObject() );
}
void
CanonicalForm::mpzval(mpz_t val) const
{
ASSERT (!is_imm (value) && value->levelcoeff() == IntegerDomain, "non-immediate integer expected");
getmpi (value, val);
}
/** predicates **/
#if 0
bool
CanonicalForm::isImm() const
{
return is_imm( value );
}
#endif
bool
CanonicalForm::inZ() const
{
if ( is_imm( value ) == INTMARK )
return true;
else if ( is_imm( value ) )
return false;
else
return value->levelcoeff() == IntegerDomain;
}
bool
CanonicalForm::inQ() const
{
if ( is_imm( value ) == INTMARK )
return true;
else if ( is_imm( value ) )
return false;
else
return value->levelcoeff() == IntegerDomain ||
value->levelcoeff() == RationalDomain;
}
bool
CanonicalForm::inFF() const
{
return is_imm( value ) == FFMARK;
}
bool
CanonicalForm::inGF() const
{
return is_imm( value ) == GFMARK;
}
bool
CanonicalForm::inBaseDomain() const
{
if ( is_imm( value ) )
return true;
else
return value->inBaseDomain();
}
bool
CanonicalForm::inExtension() const
{
if ( is_imm( value ) )
return false;
else
return value->inExtension();
}
bool
CanonicalForm::inCoeffDomain() const
{
if ( is_imm( value ) )
return true;
else
return value->inCoeffDomain();
}
bool
CanonicalForm::inPolyDomain() const
{
if ( is_imm( value ) )
return false;
else
return value->inPolyDomain();
}
bool
CanonicalForm::inQuotDomain() const
{
if ( is_imm( value ) )
return false;
else
return value->inQuotDomain();
}
bool
CanonicalForm::isFFinGF() const
{
return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
}
bool
CanonicalForm::isUnivariate() const
{
if ( is_imm( value ) )
return false;
else
return value->isUnivariate();
}
// is_homogeneous returns 1 iff f is homogeneous, 0 otherwise//
bool
CanonicalForm::isHomogeneous() const
{
if (this->isZero()) return true;
else if (this->inCoeffDomain()) return true;
else
{
#if 0
CFIterator i;
int cdeg = -2, dummy;
for ( i = *this; i.hasTerms(); i++ )
{
if (!(i.coeff().isHomogeneous())) return false;
if ( (dummy = totaldegree( i.coeff() ) + i.exp()) != cdeg )
{
if (cdeg == -2) cdeg = dummy;
else return false;
}
}
return true;
#else
CFList termlist= get_Terms(*this);
CFListIterator i;
int deg= totaldegree(termlist.getFirst());
for ( i=termlist; i.hasItem(); i++ )
if ( totaldegree(i.getItem()) != deg ) return false;
return true;
#endif
}
}
/** conversion functions **/
long
CanonicalForm::intval() const
{
if ( is_imm( value ) )
return imm_intval( value );
else
return value->intval();
}
CanonicalForm
CanonicalForm::mapinto () const
{
//ASSERT( is_imm( value ) || ! value->inExtension(), "cannot map into different Extension" );
int ch=getCharacteristic();
if ( is_imm( value ) )
if ( ch == 0 )
if ( is_imm( value ) == FFMARK )
return CanonicalForm( int2imm( ff_symmetric( imm2int( value ) ) ) );
else if ( is_imm( value ) == GFMARK )
return CanonicalForm( int2imm( ff_symmetric( gf_gf2ff( imm2int( value ) ) ) ) );
else
return *this;
else if ( CFFactory::gettype() == PrimePowerDomain )
return CanonicalForm( CFFactory::basic( imm2int( value ) ) );
else if ( getGFDegree() == 1 )
return CanonicalForm( int2imm_p( ff_norm( imm2int( value ) ) ) );
else
return CanonicalForm( int2imm_gf( gf_int2gf( imm2int( value ) ) ) );
else if ( value->inBaseDomain() )
if ( ch == 0 )
#ifndef HAVE_NTL
if ( value->levelcoeff() == PrimePowerDomain )
{
mpz_t d;
getmpi( value,d);
if ( mpz_cmp( InternalPrimePower::primepowhalf, d ) < 0 )
mpz_sub( d, d, InternalPrimePower::primepow );
return CFFactory::basic( d );
}
else
#endif
return *this;
#ifndef HAVE_NTL
else if ( CFFactory::gettype() == PrimePowerDomain )
{
ASSERT( value->levelcoeff() == PrimePowerDomain || value->levelcoeff() == IntegerDomain, "no proper map defined" );
if ( value->levelcoeff() == PrimePowerDomain )
return *this;
else
{
mpz_t d;
getmpi(value,d);
if ( mpz_cmp( InternalPrimePower::primepowhalf, d ) < 0 )
mpz_sub( d, d, InternalPrimePower::primepow );
return CFFactory::basic( d );
}
}
#endif
else
{
int val;
if ( value->levelcoeff() == IntegerDomain )
val = value->intmod( ff_prime );
else if ( value->levelcoeff() == RationalDomain )
return num().mapinto() / den().mapinto();
else {
ASSERT( 0, "illegal domain" );
return 0;
}
if ( getGFDegree() > 1 )
return CanonicalForm( int2imm_gf( gf_int2gf( val ) ) );
else
return CanonicalForm( int2imm_p( val ) );
}
else
{
Variable x = value->variable();
CanonicalForm result;
for ( CFIterator i = *this; i.hasTerms(); i++ )
result += (power( x, i.exp() ) * i.coeff().mapinto());
return result;
}
}
/** CanonicalForm CanonicalForm::lc (), Lc (), LC (), LC ( v ) const
*
* lc(), Lc(), LC() - leading coefficient functions.
*
* All methods return CO if CO is in a base domain.
*
* lc() returns the leading coefficient of CO with respect to
* lexicographic ordering. Elements in an algebraic extension
* are considered polynomials so lc() always returns a leading
* coefficient in a base domain. This method is useful to get
* the base domain over which CO is defined.
*
* Lc() returns the leading coefficient of CO with respect to
* lexicographic ordering. In contrast to lc() elements in an
* algebraic extension are considered coefficients so Lc() always
* returns a leading coefficient in a coefficient domain.
*
* LC() returns the leading coefficient of CO where CO is
* considered a univariate polynomial in its main variable. An
* element of an algebraic extension is considered an univariate
* polynomial, too.
*
* LC( v ) returns the leading coefficient of CO where CO is
* considered an univariate polynomial in the polynomial variable
* v.
* Note: If v is less than the main variable of CO we have to
* swap variables which may be quite expensive.
*
* Examples:
* > Let x < y be polynomial variables, a an algebraic variable.
*
* > (3*a*x*y^2+y+x).lc() = 3
*
* > (3*a*x*y^2+y+x).Lc() = 3*a
*
* > (3*a*x*y^2+y+x).LC() = 3*a*x
*
* > (3*a*x*y^2+y+x).LC( x ) = 3*a*y^2+1
*
*
* > (3*a^2+4*a).lc() = 3
*
* > (3*a^2+4*a).Lc() = 3*a^2+4*a
*
* > (3*a^2+4*a).LC() = 3
*
* > (3*a^2+4*a).LC( x ) = 3*a^2+4*a
*
* @sa InternalCF::lc(), InternalCF::Lc(), InternalCF::LC(),
* InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
* ::lc(), ::Lc(), ::LC(), ::LC( v )
*
**/
CanonicalForm
CanonicalForm::lc () const
{
if ( is_imm( value ) )
return *this;
else
return value->lc();
}
/**
* @sa CanonicalForm::lc(), CanonicalForm::LC(), InternalCF::lc(),
* InternalCF::Lc(), InternalCF::LC(),
* InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
* ::lc(), ::Lc(), ::LC(), ::LC( v )
**/
CanonicalForm
CanonicalForm::Lc () const
{
if ( is_imm( value ) || value->inCoeffDomain() )
return *this;
else
return value->Lc();
}
/**
* @sa CanonicalForm::lc(), CanonicalForm::Lc(), InternalCF::lc(),
* InternalCF::Lc(), InternalCF::LC(),
* InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
* ::lc(), ::Lc(), ::LC(), ::LC( v )
**/
CanonicalForm
CanonicalForm::LC () const
{
if ( is_imm( value ) )
return *this;
else
return value->LC();
}
/**
* @sa CanonicalForm::lc(), CanonicalForm::Lc(), InternalCF::lc(),
* InternalCF::Lc(), InternalCF::LC(),
* InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
* ::lc(), ::Lc(), ::LC(), ::LC( v )
**/
CanonicalForm
CanonicalForm::LC ( const Variable & v ) const
{
if ( is_imm( value ) || value->inCoeffDomain() )
return *this;
Variable x = value->variable();
if ( v > x )
return *this;
else if ( v == x )
return value->LC();
else {
CanonicalForm f = swapvar( *this, v, x );
if ( f.mvar() == x )
return swapvar( f.value->LC(), v, x );
else
// v did not occur in f
return *this;
}
}
/**
* Returns -1 for the zero polynomial and 0 if
* CO is in a base domain.
*
* degree() returns the degree of CO in its main variable.
* Elements in an algebraic extension are considered polynomials.
*
* @sa InternalCF::degree(), InternalPoly::degree(),
* ::degree(), ::degree( v )
*
**/
int
CanonicalForm::degree() const
{
int what = is_imm( value );
if ( what )
if ( what == FFMARK )
return imm_iszero_p( value ) ? -1 : 0;
else if ( what == INTMARK )
return imm_iszero( value ) ? -1 : 0;
else
return imm_iszero_gf( value ) ? -1 : 0;
else
return value->degree();
}
/**
* returns -1 for the zero polynomial and 0 if
* CO is in a base domain.
*
* degree( v ) returns the degree of CO with respect to v.
* Elements in an algebraic extension are considered polynomials,
* and v may be algebraic.
*
* @sa InternalCF::degree(), InternalPoly::degree(),
* ::degree(), ::degree( v )
**/
int
CanonicalForm::degree( const Variable & v ) const
{
int what = is_imm( value );
#if 0
if ( what )
if ( what == FFMARK )
return imm_iszero_p( value ) ? -1 : 0;
else if ( what == INTMARK )
return imm_iszero( value ) ? -1 : 0;
else
return imm_iszero_gf( value ) ? -1 : 0;
else if ( value->inBaseDomain() )
return value->degree();
#else
switch(what)
{
case FFMARK: return imm_iszero_p( value ) ? -1 : 0;
case INTMARK: return imm_iszero( value ) ? -1 : 0;
case GFMARK: return imm_iszero_gf( value ) ? -1 : 0;
case 0: if ( value->inBaseDomain() )
return value->degree();
break;
}
#endif
Variable x = value->variable();
if ( v == x )
return value->degree();
else if ( v > x )
// relatively to v, f is in a coefficient ring
return 0;
else {
int coeffdeg, result = 0;
// search for maximum of coefficient degree
for ( CFIterator i = *this; i.hasTerms(); i++ ) {
coeffdeg = i.coeff().degree( v );
if ( coeffdeg > result )
result = coeffdeg;
}
return result;
}
}
/**
*
* tailcoeff() - return least coefficient
*
* tailcoeff() returns the coefficient of the term with the least
* degree in CO where CO is considered an univariate polynomial
* in its main variable. Elements in an algebraic extension are
* considered coefficients.
*
* @sa CanonicalForm::taildegree(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
* InternalPoly::tailcoeff(), InternalPoly::taildegree,
* ::tailcoeff(), ::taildegree()
*
**/
CanonicalForm
CanonicalForm::tailcoeff () const
{
if ( is_imm( value ) || value->inCoeffDomain() )
return *this;
else
return value->tailcoeff();
}
/**
* tailcoeff( v ) returns the tail coefficient of CO where CO is
* considered an univariate polynomial in the polynomial variable
* v.
* Note: If v is less than the main variable of CO we have to
* swap variables which may be quite expensive.
*
* @sa CanonicalForm::taildegree(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
* InternalPoly::tailcoeff(), InternalPoly::taildegree,
* ::tailcoeff(), ::taildegree()
**/
CanonicalForm
CanonicalForm::tailcoeff (const Variable& v) const
{
if ( is_imm( value ) || value->inCoeffDomain() )
return *this;
Variable x = value->variable();
if ( v > x )
return *this;
else if ( v == x )
return value->tailcoeff();
else {
CanonicalForm f = swapvar( *this, v, x );
if ( f.mvar() == x )
return swapvar( f.value->tailcoeff(), v, x );
else
// v did not occur in f
return *this;
}
}
/**
* taildegree() returns -1 for the zero polynomial, 0 if CO is in
* a base domain, otherwise the least degree of CO where CO is
* considered a univariate polynomial in its main variable. In
* contrast to tailcoeff(), elements in an algebraic extension
* are considered polynomials, not coefficients, and such may
* have a taildegree larger than zero.
*
* @sa CanonicalForm::tailcoeff(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
* InternalPoly::tailcoeff(), InternalPoly::taildegree,
* ::tailcoeff(), ::taildegree()
**/
int
CanonicalForm::taildegree () const
{
int what = is_imm( value );
if ( what )
if ( what == FFMARK )
return imm_iszero_p( value ) ? -1 : 0;
else if ( what == INTMARK )
return imm_iszero( value ) ? -1 : 0;
else
return imm_iszero_gf( value ) ? -1 : 0;
else
return value->taildegree();
}
/**
* level() returns the level of CO. For a list of the levels and
* their meanings, see cf_defs.h.
*
* @sa InternalCF::level(), InternalCF::variable(),
* InternalPoly::level(), InternalPoly::variable(), ::level(),
* ::mvar()
*
**/
int
CanonicalForm::level () const
{
if ( is_imm( value ) )
return LEVELBASE;
else
return value->level();
}
/**
* mvar() returns the main variable of CO or Variable() if CO is
* in a base domain.
*
* @sa InternalCF::level(), InternalCF::variable(),
* InternalPoly::level(), InternalPoly::variable(), ::level(),
* ::mvar()
**/
Variable
CanonicalForm::mvar () const
{
if ( is_imm( value ) )
return Variable();
else
return value->variable();
}
/**
* num() returns the numerator of CO if CO is a rational number,
* CO itself otherwise.
*
* @sa InternalCF::num(), InternalCF::den(),
* InternalRational::num(), InternalRational::den(), ::num(),
* ::den()
*
**/
CanonicalForm
CanonicalForm::num () const
{
if ( is_imm( value ) )
return *this;
else
return CanonicalForm( value->num() );
}
/**
* den() returns the denominator of CO if CO is a rational
* number, 1 (from the current domain!) otherwise.
*
* @sa InternalCF::num(), InternalCF::den(),
* InternalRational::num(), InternalRational::den(), ::num(),
* ::den()
**/
CanonicalForm
CanonicalForm::den () const
{
if ( is_imm( value ) )
return CanonicalForm( 1 );
else
return CanonicalForm( value->den() );
}
/** assignment operators **/
CanonicalForm &
CanonicalForm::operator += ( const CanonicalForm & cf )
{
int what = is_imm( value );
int lv,cf_lv;
if ( what )
{
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_add_p( value, cf.value );
else if ( what == GFMARK )
value = imm_add_gf( value, cf.value );
else if ( what )
value = imm_add( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->addcoeff( value );
}
}
else if ( is_imm( cf.value ) )
value = value->addcoeff( cf.value );
else if ( (lv=value->level()) == (cf_lv=cf.value->level()) )
{
if ( value->levelcoeff() == cf.value->levelcoeff() )
value = value->addsame( cf.value );
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->addcoeff( cf.value );
else
{
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->addcoeff( value );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( lv > cf_lv /*level() > cf.level()*/ )
value = value->addcoeff( cf.value );
else
{
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->addcoeff( value );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
CanonicalForm &
CanonicalForm::operator -= ( const CanonicalForm & cf )
{
int what = is_imm( value );
if ( what ) {
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_sub_p( value, cf.value );
else if ( what == GFMARK )
value = imm_sub_gf( value, cf.value );
else if ( what )
value = imm_sub( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->subcoeff( value, true );
}
}
else if ( is_imm( cf.value ) )
value = value->subcoeff( cf.value, false );
else if ( value->level() == cf.value->level() ) {
if ( value->levelcoeff() == cf.value->levelcoeff() )
value = value->subsame( cf.value );
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->subcoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->subcoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( level() > cf.level() )
value = value->subcoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->subcoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
CanonicalForm &
CanonicalForm::operator *= ( const CanonicalForm & cf )
{
int what = is_imm( value );
if ( what ) {
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_mul_p( value, cf.value );
else if ( what == GFMARK )
value = imm_mul_gf( value, cf.value );
else if ( what )
value = imm_mul( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->mulcoeff( value );
}
}
else if ( is_imm( cf.value ) )
value = value->mulcoeff( cf.value );
else if ( value->level() == cf.value->level() ) {
#if (HAVE_NTL && HAVE_FLINT && __FLINT_RELEASE >= 20400)
#if (__FLINT_RELEASE >= 20503)
int ch=getCharacteristic();
int l_this,l_cf,m=1;
if ((ch>0)
&& (CFFactory::gettype() != GaloisFieldDomain)
&&(!hasAlgVar(*this))
&&(!hasAlgVar(cf))
&&((l_cf=size_maxexp(cf,m))>10)
&&((l_this=size_maxexp(*this,m))>10)
)
{
*this=mulFlintMP_Zp(*this,l_this,cf,l_cf,m);
}
else
/*-----------------------------------------------------*/
if ((ch==0)
&&(!hasAlgVar(*this))
&&(!hasAlgVar(cf))
&&((l_cf=size_maxexp(cf,m))>10)
&&((l_this=size_maxexp(*this,m))>10)
)
{
*this=mulFlintMP_QQ(*this,l_this,cf,l_cf,m);
}
else
#endif
if (value->levelcoeff() == cf.value->levelcoeff() && cf.isUnivariate() && (*this).isUnivariate())
{
if (value->level() < 0 || CFFactory::gettype() == GaloisFieldDomain || (size (cf) <= 10 || size (*this) <= 10) )
value = value->mulsame( cf.value );
else
*this= mulNTL (*this, cf);
}
else if (value->levelcoeff() == cf.value->levelcoeff() && (!cf.isUnivariate() || !(*this).isUnivariate()))
value = value->mulsame( cf.value );
#else
if ( value->levelcoeff() == cf.value->levelcoeff() )
value = value->mulsame( cf.value );
#endif
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->mulcoeff( cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->mulcoeff( value );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( level() > cf.level() )
value = value->mulcoeff( cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->mulcoeff( value );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
CanonicalForm &
CanonicalForm::operator /= ( const CanonicalForm & cf )
{
int what = is_imm( value );
if ( what ) {
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_div_p( value, cf.value );
else if ( what == GFMARK )
value = imm_div_gf( value, cf.value );
else if ( what )
value = imm_divrat( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->dividecoeff( value, true );
}
}
else if ( is_imm( cf.value ) )
value = value->dividecoeff( cf.value, false );
else if ( value->level() == cf.value->level() ) {
#if (HAVE_NTL && HAVE_FLINT && __FLINT_RELEASE >= 20400)
if ( value->levelcoeff() == cf.value->levelcoeff() && (*this).isUnivariate() && cf.isUnivariate())
{
if (value->level() < 0 || CFFactory::gettype() == GaloisFieldDomain)
value = value->dividesame( cf.value );
else
*this= divNTL (*this, cf);
}
else if (value->levelcoeff() == cf.value->levelcoeff() && (!cf.isUnivariate() || !(*this).isUnivariate()))
value = value->dividesame( cf.value );
#else
if (value->levelcoeff() == cf.value->levelcoeff() )
value = value->dividesame( cf.value );
#endif
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->dividecoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->dividecoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( level() > cf.level() )
value = value->dividecoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->dividecoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
CanonicalForm &
CanonicalForm::div ( const CanonicalForm & cf )
{
int what = is_imm( value );
if ( what ) {
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_div_p( value, cf.value );
else if ( what == GFMARK )
value = imm_div_gf( value, cf.value );
else if ( what )
value = imm_div( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->divcoeff( value, true );
}
}
else if ( is_imm( cf.value ) )
value = value->divcoeff( cf.value, false );
else if ( value->level() == cf.value->level() ) {
if ( value->levelcoeff() == cf.value->levelcoeff() )
value = value->divsame( cf.value );
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->divcoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->divcoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( level() > cf.level() )
value = value->divcoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->divcoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
///same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
CanonicalForm &
CanonicalForm::tryDiv ( const CanonicalForm & cf, const CanonicalForm& M, bool& fail )
{
ASSERT (getCharacteristic() > 0, "expected positive characteristic");
ASSERT (!getReduce (M.mvar()), "do not reduce modulo M");
fail= false;
int what = is_imm( value );
if ( what ) {
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_div_p( value, cf.value );
else if ( what == GFMARK )
value = imm_div_gf( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->divcoeff( value, true );
}
}
else if ( is_imm( cf.value ) )
value = value->tryDivcoeff (cf.value, false, M, fail);
else if ( value->level() == cf.value->level() ) {
if ( value->levelcoeff() == cf.value->levelcoeff() )
value = value->tryDivsame( cf.value, M, fail );
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->tryDivcoeff( cf.value, false, M, fail );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->tryDivcoeff( value, true, M, fail );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( level() > cf.level() )
value = value->tryDivcoeff( cf.value, false, M, fail );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->tryDivcoeff( value, true, M, fail );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
CanonicalForm &
CanonicalForm::operator %= ( const CanonicalForm & cf )
{
int what = is_imm( value );
if ( what ) {
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_mod_p( value, cf.value );
else if ( what == GFMARK )
value = imm_mod_gf( value, cf.value );
else if ( what )
value = imm_mod( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->modulocoeff( value, true );
}
}
else if ( is_imm( cf.value ) )
value = value->modulocoeff( cf.value, false );
else if ( value->level() == cf.value->level() ) {
if ( value->levelcoeff() == cf.value->levelcoeff() )
value = value->modulosame( cf.value );
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->modulocoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->modulocoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( level() > cf.level() )
value = value->modulocoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->modulocoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
CanonicalForm &
CanonicalForm::mod ( const CanonicalForm & cf )
{
int what = is_imm( value );
if ( what ) {
ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
if ( (what = is_imm( cf.value )) == FFMARK )
value = imm_mod_p( value, cf.value );
else if ( what == GFMARK )
value = imm_mod_gf( value, cf.value );
else if ( what )
value = imm_mod( value, cf.value );
else {
InternalCF * dummy = cf.value->copyObject();
value = dummy->modcoeff( value, true );
}
}
else if ( is_imm( cf.value ) )
value = value->modcoeff( cf.value, false );
else if ( value->level() == cf.value->level() ) {
if ( value->levelcoeff() == cf.value->levelcoeff() )
value = value->modsame( cf.value );
else if ( value->levelcoeff() > cf.value->levelcoeff() )
value = value->modcoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->modcoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
}
else if ( level() > cf.level() )
value = value->modcoeff( cf.value, false );
else {
InternalCF * dummy = cf.value->copyObject();
dummy = dummy->modcoeff( value, true );
if ( value->deleteObject() ) delete value;
value = dummy;
}
return *this;
}
void
divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
{
InternalCF * qq = 0, * rr = 0;
int what = is_imm( f.value );
if ( what )
if ( is_imm( g.value ) ) {
if ( what == FFMARK )
imm_divrem_p( f.value, g.value, qq, rr );
else if ( what == GFMARK )
imm_divrem_gf( f.value, g.value, qq, rr );
else
imm_divrem( f.value, g.value, qq, rr );
}
else
g.value->divremcoeff( f.value, qq, rr, true );
else if ( (what=is_imm( g.value )) )
f.value->divremcoeff( g.value, qq, rr, false );
else if ( f.value->level() == g.value->level() )
if ( f.value->levelcoeff() == g.value->levelcoeff() )
f.value->divremsame( g.value, qq, rr );
else if ( f.value->levelcoeff() > g.value->levelcoeff() )
f.value->divremcoeff( g.value, qq, rr, false );
else
g.value->divremcoeff( f.value, qq, rr, true );
else if ( f.value->level() > g.value->level() )
f.value->divremcoeff( g.value, qq, rr, false );
else
g.value->divremcoeff( f.value, qq, rr, true );
ASSERT( qq != 0 && rr != 0, "error in divrem" );
q = CanonicalForm( qq );
r = CanonicalForm( rr );
}
bool
divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
{
InternalCF * qq = 0, * rr = 0;
int what = is_imm( f.value );
bool result = true;
if ( what )
if ( is_imm( g.value ) ) {
if ( what == FFMARK )
imm_divrem_p( f.value, g.value, qq, rr );
else if ( what == GFMARK )
imm_divrem_gf( f.value, g.value, qq, rr );
else
imm_divrem( f.value, g.value, qq, rr );
}
else
result = g.value->divremcoefft( f.value, qq, rr, true );
else if ( (what=is_imm( g.value )) )
result = f.value->divremcoefft( g.value, qq, rr, false );
else if ( f.value->level() == g.value->level() )
if ( f.value->levelcoeff() == g.value->levelcoeff() )
result = f.value->divremsamet( g.value, qq, rr );
else if ( f.value->levelcoeff() > g.value->levelcoeff() )
result = f.value->divremcoefft( g.value, qq, rr, false );
else
result = g.value->divremcoefft( f.value, qq, rr, true );
else if ( f.value->level() > g.value->level() )
result = f.value->divremcoefft( g.value, qq, rr, false );
else
result = g.value->divremcoefft( f.value, qq, rr, true );
if ( result ) {
ASSERT( qq != 0 && rr != 0, "error in divrem" );
q = CanonicalForm( qq );
r = CanonicalForm( rr );
}
else {
q = 0; r = 0;
}
return result;
}
///same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
bool
tryDivremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const CanonicalForm& M, bool& fail )
{
ASSERT (getCharacteristic() > 0, "expected positive characteristic");
ASSERT (!getReduce (M.mvar()), "do not reduce modulo M");
fail= false;
InternalCF * qq = 0, * rr = 0;
int what = is_imm( f.value );
bool result = true;
if ( what )
if ( is_imm( g.value ) ) {
if ( what == FFMARK )
imm_divrem_p( f.value, g.value, qq, rr );
else if ( what == GFMARK )
imm_divrem_gf( f.value, g.value, qq, rr );
}
else
result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
else if ( (what=is_imm( g.value )) )
result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
else if ( f.value->level() == g.value->level() )
if ( f.value->levelcoeff() == g.value->levelcoeff() )
result = f.value->tryDivremsamet( g.value, qq, rr, M, fail );
else if ( f.value->levelcoeff() > g.value->levelcoeff() )
result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
else
result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
else if ( f.value->level() > g.value->level() )
result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
else
result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
if (fail)
{
q= 0;
r= 0;
return false;
}
if ( result ) {
ASSERT( qq != 0 && rr != 0, "error in divrem" );
q = CanonicalForm( qq );
r = CanonicalForm( rr );
q= reduce (q, M);
r= reduce (r, M);
}
else {
q = 0; r = 0;
}
return result;
}
/**
*
* operator ()() - evaluation operator.
*
* Returns CO if CO is in a base domain.
*
* operator () ( f ) returns CO with f inserted for the main
* variable. Elements in an algebraic extension are considered
* polynomials.
*
**/
CanonicalForm
CanonicalForm::operator () ( const CanonicalForm & f ) const
{
if ( is_imm( value ) || value->inBaseDomain() )
return *this;
else {
#if 0
CFIterator i = *this;
int lastExp = i.exp();
CanonicalForm result = i.coeff();
i++;
while ( i.hasTerms() ) {
if ( (lastExp - i.exp()) == 1 )
result *= f;
else
result *= power( f, lastExp - i.exp() );
result += i.coeff();
lastExp = i.exp();
i++;
}
if ( lastExp != 0 )
result *= power( f, lastExp );
#else
CFIterator i = *this;
int lastExp = i.exp();
CanonicalForm result = i.coeff();
i++;
while ( i.hasTerms() )
{
int i_exp=i.exp();
if ( (lastExp - i_exp /* i.exp()*/) == 1 )
result *= f;
else
result *= power( f, lastExp - i_exp /*i.exp()*/ );
result += i.coeff();
lastExp = i_exp /*i.exp()*/;
i++;
}
if ( lastExp != 0 )
result *= power( f, lastExp );
#endif
return result;
}
}
/**
* Returns CO if CO is in a base domain.
*
* operator () ( f, v ) returns CO with f inserted for v.
* Elements in an algebraic extension are considered polynomials
* and v may be an algebraic variable.
**/
CanonicalForm
CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
{
if ( is_imm( value ) || value->inBaseDomain() )
return *this;
Variable x = value->variable();
if ( v > x )
return *this;
else if ( v == x )
return (*this)( f );
else {
// v is less than main variable of f
CanonicalForm result = 0;
for ( CFIterator i = *this; i.hasTerms(); i++ )
result += i.coeff()( f, v ) * power( x, i.exp() );
return result;
}
}
/**
*
* operator []() - return i'th coefficient from CO.
*
* Returns CO if CO is in a base domain and i equals zero.
* Returns zero (from the current domain) if CO is in a base
* domain and i is larger than zero. Otherwise, returns the
* coefficient to x^i in CO (if x denotes the main variable of
* CO) or zero if CO does not contain x^i. Elements in an
* algebraic extension are considered polynomials. i should be
* larger or equal zero.
*
* Note: Never use a loop like
*
~~~~~~~~~~~~~~~~~~~~~{.c}
for ( int i = degree( f ); i >= 0; i-- )
foo( i, f[ i ] );
~~~~~~~~~~~~~~~~~~~~~
*
* which is much slower than
*
~~~~~~~~~~~~~~~~~~~~~{.c}
* for ( int i = degree( f ), CFIterator I = f; I.hasTerms(); I++ ) {
* // fill gap with zeroes
* for ( ; i > I.exp(); i-- )
* foo( i, 0 );
* // at this point, i == I.exp()
* foo( i, i.coeff() );
* i--;
* }
* // work through trailing zeroes
* for ( ; i >= 0; i-- )
* foo( i, 0 );
~~~~~~~~~~~~~~~~~~~~~
*
**/
CanonicalForm
CanonicalForm::operator [] ( int i ) const
{
ASSERT( i >= 0, "index to operator [] less than zero" );
if ( is_imm( value ) )
if ( i == 0 )
return *this;
else
return CanonicalForm( 0 );
else
return value->coeff( i );
}
/**
*
* deriv() - return the formal derivation of CO.
*
* deriv() derives CO with respect to its main variable. Returns
* zero from the current domain if f is in a coefficient domain.
*
* @sa CanonicalForm::deriv ( const Variable & x )
*
**/
CanonicalForm
CanonicalForm::deriv () const
{
if ( is_imm( value ) || value->inCoeffDomain() )
return CanonicalForm( 0 );
else {
CanonicalForm result = 0;
Variable x = value->variable();
for ( CFIterator i = *this; i.hasTerms(); i++ )
if ( i.exp() > 0 )
result += power( x, i.exp()-1 ) * i.coeff() * i.exp();
return result;
}
}
/**
* deriv( x ) derives CO with respect to x. x should be a
* polynomial variable. Returns zero from the current domain if
* f is in a coefficient domain.
**/
CanonicalForm
CanonicalForm::deriv ( const Variable & x ) const
{
ASSERT( x.level() > 0, "cannot derive with respect to algebraic variables" );
if ( is_imm( value ) || value->inCoeffDomain() )
return CanonicalForm( 0 );
Variable y = value->variable();
if ( x > y )
return CanonicalForm( 0 );
else if ( x == y )
return deriv();
else {
CanonicalForm result = 0;
for ( CFIterator i = *this; i.hasTerms(); i++ )
result += i.coeff().deriv( x ) * power( y, i.exp() );
return result;
}
}
/** int CanonicalForm::sign () const
*
* sign() - return sign of CO.
*
* If CO is an integer or a rational number, the sign is defined
* as usual. If CO is an element of a prime power domain or of
* FF(p) and SW_SYMMETRIC_FF is on, the sign of CO is the sign of
* the symmetric representation of CO. If CO is in GF(q) or in
* FF(p) and SW_SYMMETRIC_FF is off, the sign of CO is zero iff
* CO is zero, otherwise the sign is one.
*
* If CO is a polynomial or in an extension of one of the base
* domains, the sign of CO is the sign of its leading
* coefficient.
*
* @sa InternalCF::sign(), InternalInteger::sign(),
* InternalRational::sign(),
* InternalPoly::sign(), imm_sign(), gf_sign()
*
**/
int
CanonicalForm::sign () const
{
if ( is_imm( value ) )
return imm_sign( value );
else
return value->sign();
}
/** CanonicalForm CanonicalForm::sqrt () const
*
* sqrt() - calculate integer square root.
*
* CO has to be an integer greater or equal zero. Returns the
* largest integer less or equal sqrt(CO).
*
* In the immediate case, we use the newton method to find the
* root. The algorithm is from H. Cohen - 'A Course in
* Computational Algebraic Number Theory', ch. 1.7.1.
*
* @sa InternalCF::sqrt(), InternalInteger::sqrt(), ::sqrt()
*
**/
CanonicalForm
CanonicalForm::sqrt () const
{
if ( is_imm( value ) ) {
ASSERT( is_imm( value ) == INTMARK, "sqrt() not implemented" );
long n = imm2int( value );
ASSERT( n >= 0, "arg to sqrt() less than zero" );
if ( n == 0 || n == 1 )
return CanonicalForm( n );
else {
long x, y = n;
do {
x = y;
// the intermediate result may not fit into an
// integer, but the result does
y = (unsigned long)(x + n/x)/2;
} while ( y < x );
return CanonicalForm( x );
}
}
else
return CanonicalForm( value->sqrt() );
}
/** int CanonicalForm::ilog2 () const
*
* ilog2() - integer logarithm to base 2.
*
* Returns the largest integer less or equal logarithm of CO to
* base 2. CO should be a positive integer.
*
* @sa InternalCF::ilog2(), InternalInteger::ilog2(), ::ilog2()
*
**/
int
CanonicalForm::ilog2 () const
{
if ( is_imm( value ) )
{
ASSERT( is_imm( value ) == INTMARK, "ilog2() not implemented" );
long a = imm2int( value );
ASSERT( a > 0, "arg to ilog2() less or equal zero" );
return SI_LOG2_LONG(a);
}
else
return value->ilog2();
}
/**
*
* operator ==() - compare canonical forms on
* (in)equality.
*
* operator ==() returns true iff lhs equals rhs.
*
* This is the point in factory where we essentially use that
* CanonicalForms in fact are canonical. There must not be two
* different representations of the same mathematical object,
* otherwise, such (in)equality will not be recognized by these
* operators. In other word, we rely on the fact that structural
* different factory objects in any case represent different
* mathematical objects.
*
* So we use the following procedure to test on equality (and
* analogously on inequality). First, we check whether lhs.value
* equals rhs.value. If so we are ready and return true.
* Second, if one of the operands is immediate, but the other one
* not, we return false. Third, if the operand's levels differ
* we return false. Fourth, if the operand's levelcoeffs differ
* we return false. At last, we call the corresponding internal
* method to compare both operands.
*
* Both operands should have coefficients from the same base domain.
*
* Note: To compare with the zero or the unit of the current domain,
* you better use the methods `CanonicalForm::isZero()' or
* `CanonicalForm::isOne()', resp., than something like `f == 0',
* since the latter is quite a lot slower.
*
* @sa CanonicalForm::operator !=(), InternalCF::comparesame(),
* InternalInteger::comparesame(), InternalRational::comparesame(),
* InternalPoly::comparesame()
*
**/
bool
operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
{
if ( lhs.value == rhs.value )
return true;
else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
ASSERT( ! is_imm( rhs.value ) ||
! is_imm( lhs.value ) ||
is_imm( rhs.value ) == is_imm( lhs.value ),
"incompatible operands" );
return false;
}
else if ( lhs.value->level() != rhs.value->level() )
return false;
else if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
return false;
else
return rhs.value->comparesame( lhs.value ) == 0;
}
/**
* operator !=() returns true iff lhs does not equal rhs.
*
* @sa CanonicalForm::operator ==()
**/
bool
operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
{
if ( lhs.value == rhs.value )
return false;
else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
ASSERT( ! is_imm( rhs.value ) ||
! is_imm( lhs.value ) ||
is_imm( rhs.value ) == is_imm( lhs.value ),
"incompatible operands" );
return true;
}
else if ( lhs.value->level() != rhs.value->level() )
return true;
else if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
return true;
else return rhs.value->comparesame( lhs.value ) != 0;
}
/**
*
* operator >() - compare canonical forms. on size or
* level.
*
* The most common and most useful application of these operators
* is to compare two integers or rationals, of course. However,
* these operators are defined on all other base domains and on
* polynomials, too. From a mathematical point of view this may
* seem meaningless, since there is no ordering on finite fields
* or on polynomials respecting the algebraic structure.
* Nevertheless, from a programmer's point of view it may be
* sensible to order these objects, e.g. to sort them.
*
* Therefore, the ordering defined by these operators in any case
* is a total ordering which fulfills the law of trichotomy.
*
* It is clear how this is done in the case of the integers and
* the rationals. For finite fields, all you can say is that
* zero is the minimal element w.r.t. the ordering, the other
* elements are ordered in an arbitrary (but total!) way. For
* polynomials, you have an ordering derived from the
* lexicographical ordering of monomials. E.g. if lm(f) < lm(g)
* w.r.t. lexicographic ordering, then f < g. For more details,
* refer to the documentation of `InternalPoly::operator <()'.
*
* Both operands should have coefficients from the same base domain.
*
* The scheme how both operators are implemented is almost the
* same as for the assignment operators (check for immediates,
* then check levels, then check levelcoeffs, then call the
* appropriate internal comparesame()/comparecoeff() method).
* For more information, confer to the overview for the
* arithmetic operators.
*
* @sa CanonicalForm::operator <(), InternalCF::comparesame(),
* InternalInteger::comparesame(), InternalRational::comparesame(),
* InternalPoly::comparesame(),
* InternalCF::comparecoeff(), InternalInteger::comparecoeff(),
* InternalRational::comparecoeff(),
* InternalPoly::comparecoeff(),
* imm_cmp(), imm_cmp_p(), imm_cmp_gf()
*
**/
bool
operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
{
int what = is_imm( rhs.value );
if ( is_imm( lhs.value ) ) {
ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
if ( what == 0 )
return rhs.value->comparecoeff( lhs.value ) < 0;
else if ( what == INTMARK )
return imm_cmp( lhs.value, rhs.value ) > 0;
else if ( what == FFMARK )
return imm_cmp_p( lhs.value, rhs.value ) > 0;
else
return imm_cmp_gf( lhs.value, rhs.value ) > 0;
}
else if ( what )
return lhs.value->comparecoeff( rhs.value ) > 0;
else if ( lhs.value->level() == rhs.value->level() )
if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
return lhs.value->comparesame( rhs.value ) > 0;
else if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
return lhs.value->comparecoeff( rhs.value ) > 0;
else
return rhs.value->comparecoeff( lhs.value ) < 0;
else
return lhs.value->level() > rhs.value->level();
}
/**
* @sa CanonicalForm::operator >()
**/
bool
operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
{
int what = is_imm( rhs.value );
if ( is_imm( lhs.value ) ) {
ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
if ( what == 0 )
return rhs.value->comparecoeff( lhs.value ) > 0;
else if ( what == INTMARK )
return imm_cmp( lhs.value, rhs.value ) < 0;
else if ( what == FFMARK )
return imm_cmp_p( lhs.value, rhs.value ) < 0;
else
return imm_cmp_gf( lhs.value, rhs.value ) < 0;
}
else if ( what )
return lhs.value->comparecoeff( rhs.value ) < 0;
else if ( lhs.value->level() == rhs.value->level() )
if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
return lhs.value->comparesame( rhs.value ) < 0;
else if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
return lhs.value->comparecoeff( rhs.value ) < 0;
else
return rhs.value->comparecoeff( lhs.value ) > 0;
else
return lhs.value->level() < rhs.value->level();
}
/** CanonicalForm bgcd ( const CanonicalForm & f, const CanonicalForm & g )
*
* bgcd() - return base coefficient gcd.
*
* If both f and g are integers and `SW_RATIONAL' is off the
* positive greatest common divisor of f and g is returned.
* Otherwise, if `SW_RATIONAL' is on or one of f and g is not an
* integer, the greatest common divisor is trivial: either zero
* if f and g equal zero or one (both from the current domain).
*
* f and g should come from one base domain which should be not
* the prime power domain.
*
* Implementation:
*
* CanonicalForm::bgcd() handles the immediate case with a
* standard euclidean algorithm. For the non-immediate cases
* `InternalCF::bgcdsame()' or `InternalCF::bgcdcoeff()', resp. are
* called following the usual level/levelcoeff approach.
*
* InternalCF::bgcdsame() and
* InternalCF::bgcdcoeff() throw an assertion ("not implemented")
*
* InternalInteger::bgcdsame() is a wrapper around `mpz_gcd()'
* which takes some care about immediate results and the sign
* of the result
* InternalInteger::bgcdcoeff() is a wrapper around
* `mpz_gcd_ui()' which takes some care about the sign
* of the result
*
* InternalRational::bgcdsame() and
* InternalRational::bgcdcoeff() always return one
*
**/
CanonicalForm
bgcd ( const CanonicalForm & f, const CanonicalForm & g )
{
// check immediate cases
int what = is_imm( g.value );
if ( is_imm( f.value ) )
{
ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
if ( what == 0 )
return g.value->bgcdcoeff( f.value );
else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) )
{
// calculate gcd using standard integer
// arithmetic
long fInt = imm2int( f.value );
long gInt = imm2int( g.value );
if ( fInt < 0 ) fInt = -fInt;
if ( gInt < 0 ) gInt = -gInt;
// swap fInt and gInt
if ( gInt > fInt )
{
long swap = gInt;
gInt = fInt;
fInt = swap;
}
// now, 0 <= gInt <= fInt. Start the loop.
while ( gInt )
{
// calculate (fInt, gInt) = (gInt, fInt%gInt)
long r = fInt % gInt;
fInt = gInt;
gInt = r;
}
return CanonicalForm( fInt );
}
else
// we do not go for maximal speed for these stupid
// special cases
return CanonicalForm( f.isZero() && g.isZero() ? 0 : 1 );
}
else if ( what )
return f.value->bgcdcoeff( g.value );
int fLevel = f.value->level();
int gLevel = g.value->level();
// check levels
if ( fLevel == gLevel )
{
fLevel = f.value->levelcoeff();
gLevel = g.value->levelcoeff();
// check levelcoeffs
if ( fLevel == gLevel )
return f.value->bgcdsame( g.value );
else if ( fLevel < gLevel )
return g.value->bgcdcoeff( f.value );
else
return f.value->bgcdcoeff( g.value );
}
else if ( fLevel < gLevel )
return g.value->bgcdcoeff( f.value );
else
return f.value->bgcdcoeff( g.value );
}
/** CanonicalForm bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
*
* bextgcd() - return base coefficient extended gcd.
*
**/
CanonicalForm
bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
{
// check immediate cases
int what = is_imm( g.value );
if ( is_imm( f.value ) ) {
ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
if ( what == 0 )
return g.value->bextgcdcoeff( f.value, b, a );
else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) ) {
// calculate extended gcd using standard integer
// arithmetic
long fInt = imm2int( f.value );
long gInt = imm2int( g.value );
// to avoid any system dpendencies with `%', we work
// with positive numbers only. To a pity, we have to
// redo all the checks when assigning to a and b.
if ( fInt < 0 ) fInt = -fInt;
if ( gInt < 0 ) gInt = -gInt;
// swap fInt and gInt
if ( gInt > fInt ) {
long swap = gInt;
gInt = fInt;
fInt = swap;
}
long u = 1; long v = 0;
long uNext = 0; long vNext = 1;
// at any step, we have:
// fInt_0 * u + gInt_0 * v = fInt
// fInt_0 * uNext + gInt_0 * vNext = gInt
// where fInt_0 and gInt_0 denote the values of fint
// and gInt, resp., at the beginning
while ( gInt ) {
long r = fInt % gInt;
long q = fInt / gInt;
long uSwap = u - q * uNext;
long vSwap = v - q * vNext;
// update variables
fInt = gInt;
gInt = r;
u = uNext; v = vNext;
uNext = uSwap; vNext = vSwap;
}
// now, assign to a and b
long fTest = imm2int( f.value );
long gTest = imm2int( g.value );
if ( gTest > fTest ) {
a = v; b = u;
} else {
a = u; b = v;
}
if ( fTest < 0 ) a = -a;
if ( gTest < 0 ) b = -b;
return CanonicalForm( fInt );
} else
// stupid special cases
if ( ! f.isZero() ) {
a = 1/f; b = 0; return CanonicalForm( 1L );
} else if ( ! g.isZero() ) {
a = 0; b = 1/g; return CanonicalForm( 1L );
} else {
a = 0; b = 0; return CanonicalForm( 0L );
}
}
else if ( what )
return f.value->bextgcdcoeff( g.value, a, b );
int fLevel = f.value->level();
int gLevel = g.value->level();
// check levels
if ( fLevel == gLevel ) {
fLevel = f.value->levelcoeff();
gLevel = g.value->levelcoeff();
// check levelcoeffs
if ( fLevel == gLevel )
return f.value->bextgcdsame( g.value, a, b );
else if ( fLevel < gLevel )
return g.value->bextgcdcoeff( f.value, b, a );
else
return f.value->bextgcdcoeff( g.value, a, b );
}
else if ( fLevel < gLevel )
return g.value->bextgcdcoeff( f.value, b, a );
else
return f.value->bextgcdcoeff( g.value, a, b );
}
CanonicalForm
blcm ( const CanonicalForm & f, const CanonicalForm & g )
{
if ( f.isZero() || g.isZero() )
return CanonicalForm( 0L );
/*
else if (f.isOne())
return g;
else if (g.isOne())
return f;
*/
else
return (f / bgcd( f, g )) * g;
}
/** input/output **/
#ifndef NOSTREAMIO
void
CanonicalForm::print( OSTREAM & os, char * str ) const
{
if ( is_imm( value ) )
imm_print( os, value, str );
else
value->print( os, str );
}
void
CanonicalForm::print( OSTREAM & os ) const
{
if ( is_imm( value ) )
imm_print( os, value, "" );
else
value->print( os, "" );
}
OSTREAM&
operator << ( OSTREAM & os, const CanonicalForm & cf )
{
cf.print( os, "" );
return os;
}
ISTREAM&
operator >> ( ISTREAM & is, CanonicalForm & cf )
{
cf = readCF( is );
return is;
}
#endif /* NOSTREAMIO */
/** genOne(), genZero() **/
CanonicalForm
CanonicalForm::genZero() const
{
int what = is_imm( value );
if ( what == FFMARK )
return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0L ) );
else if ( what == GFMARK )
return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0L ) );
else if ( what )
return CanonicalForm( CFFactory::basic( IntegerDomain, 0L ) );
else
return CanonicalForm( value->genZero() );
}
CanonicalForm
CanonicalForm::genOne() const
{
int what = is_imm( value );
if ( what == FFMARK )
return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1L ) );
else if ( what == GFMARK )
return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1L ) );
else if ( what )
return CanonicalForm( CFFactory::basic( IntegerDomain, 1L ) );
else
return CanonicalForm( value->genOne() );
}
/** exponentiation **/
CanonicalForm
power ( const CanonicalForm & f, int n )
{
ASSERT( n >= 0, "illegal exponent" );
if ( f.isZero() )
return CanonicalForm(0L);
else if ( f.isOne() )
return f;
else if ( f == -1 )
{
if ( n % 2 == 0 )
return CanonicalForm(1L);
else
return CanonicalForm(-1L);
}
else if ( n == 0 )
return CanonicalForm(1L);
//else if (f.inGF())
//{
//}
else
{
CanonicalForm g,h;
h=f;
while(n%2==0)
{
h*=h;
n/=2;
}
g=h;
while(1)
{
n/=2;
if(n==0)
return g;
h*=h;
if(n%2!=0) g*=h;
}
}
}
/** exponentiation **/
CanonicalForm
power ( const Variable & v, int n )
{
//ASSERT( n >= 0, "illegal exponent" );
if ( n == 0 )
return 1;
else if ( n == 1 )
return v;
else if (( v.level() < 0 ) && (hasMipo(v)))
{
CanonicalForm result( v, n-1 );
return result * v;
}
else
return CanonicalForm( v, n );
}
/** switches **/
void
On( int sw )
{
cf_glob_switches.On( sw );
}
/** switches **/
void
Off( int sw )
{
cf_glob_switches.Off( sw );
}
/** switches **/
bool
isOn( int sw )
{
return cf_glob_switches.isOn( sw );
}
FLINTconvert.h
This file defines functions for conversion to FLINT (www.flintlib.org) and back.
operator==
bool operator==(const Rational &a, const Rational &b)
Definition GMPrat.cc:312
operator>
bool operator>(const Rational &a, const Rational &b)
Definition GMPrat.cc:300
swap
#define swap(_i, _j)
bgcd
CanonicalForm bgcd(const CanonicalForm &f, const CanonicalForm &g)
CanonicalForm bgcd ( const CanonicalForm & f, const CanonicalForm & g ).
Definition canonicalform.cc:1648
divrem
void divrem(const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r)
Definition canonicalform.cc:1032
operator!=
bool operator!=(const CanonicalForm &lhs, const CanonicalForm &rhs)
operator ==() - compare canonical forms on (in)equality.
Definition canonicalform.cc:1492
operator>>
ISTREAM & operator>>(ISTREAM &is, CanonicalForm &cf)
Definition canonicalform.cc:1858
readCF
CanonicalForm readCF(ISTREAM &)
Definition readcf.cc:1499
isOn
bool isOn(int sw)
switches
Definition canonicalform.cc:1971
tryDivremt
bool tryDivremt(const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r, const CanonicalForm &M, bool &fail)
same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
Definition canonicalform.cc:1108
On
void On(int sw)
switches
Definition canonicalform.cc:1957
blcm
CanonicalForm blcm(const CanonicalForm &f, const CanonicalForm &g)
Definition canonicalform.cc:1816
divremt
bool divremt(const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r)
Definition canonicalform.cc:1066
operator<<
OSTREAM & operator<<(OSTREAM &os, const CanonicalForm &cf)
Definition canonicalform.cc:1851
Off
void Off(int sw)
switches
Definition canonicalform.cc:1964
bextgcd
CanonicalForm bextgcd(const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &a, CanonicalForm &b)
CanonicalForm bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a,...
Definition canonicalform.cc:1722
power
CanonicalForm power(const CanonicalForm &f, int n)
exponentiation
Definition canonicalform.cc:1896
operator<
bool operator<(const CanonicalForm &lhs, const CanonicalForm &rhs)
operator >() - compare canonical forms.
Definition canonicalform.cc:1586
canonicalform.h
Header for factory's main class CanonicalForm.
is_imm
int is_imm(const InternalCF *const ptr)
Definition canonicalform.h:65
ISTREAM
#define ISTREAM
Definition canonicalform.h:17
reduce
CanonicalForm reduce(const CanonicalForm &f, const CanonicalForm &M)
polynomials in M.mvar() are considered coefficients M univariate monic polynomial the coefficients of...
Definition cf_ops.cc:660
getCharacteristic
int FACTORY_PUBLIC getCharacteristic()
Definition cf_char.cc:70
m
int m
Definition cfEzgcd.cc:128
i
int i
Definition cfEzgcd.cc:132
x
Variable x
Definition cfModGcd.cc:4090
g
g
Definition cfModGcd.cc:4098
cf
CanonicalForm cf
Definition cfModGcd.cc:4091
b
CanonicalForm b
Definition cfModGcd.cc:4111
cf_algorithm.h
declarations of higher level algorithms.
cf_assert.h
assertions for Factory
ASSERT
#define ASSERT(expression, message)
Definition cf_assert.h:99
cf_binom.h
cf_defs.h
factory switches.
PrimePowerDomain
#define PrimePowerDomain
Definition cf_defs.h:17
FiniteFieldDomain
#define FiniteFieldDomain
Definition cf_defs.h:19
RationalDomain
#define RationalDomain
Definition cf_defs.h:20
IntegerDomain
#define IntegerDomain
Definition cf_defs.h:21
GaloisFieldDomain
#define GaloisFieldDomain
Definition cf_defs.h:18
getmpi
void getmpi(InternalCF *value, mpz_t mpi)
Definition cf_factory.cc:303
cf_factory.h
Interface to generate InternalCF's over various domains from intrinsic types or mpz_t's.
cf_globals.h
cf_iter.h
Iterators for CanonicalForm's.
cf_glob_switches
INST_VAR CFSwitches cf_glob_switches
Definition cf_switches.cc:54
f
FILE * f
Definition checklibs.c:9
CFFactory
Definition cf_factory.h:24
CFFactory::basic
static InternalCF * basic(int value)
Definition cf_factory.cc:61
CFFactory::gettype
static int gettype()
Definition cf_factory.h:28
CanonicalForm
factory's main class
Definition canonicalform.h:86
CanonicalForm::den
CanonicalForm den() const
den() returns the denominator of CO if CO is a rational number, 1 (from the current domain!...
Definition canonicalform.cc:628
CanonicalForm::genOne
CanonicalForm genOne() const
Definition canonicalform.cc:1881
CanonicalForm::operator()
CanonicalForm operator()(const CanonicalForm &f) const
operator ()() - evaluation operator.
Definition canonicalform.cc:1169
CanonicalForm::LC
CanonicalForm LC() const
Definition canonicalform.cc:367
CanonicalForm::inGF
bool inGF() const
Definition canonicalform.cc:98
CanonicalForm::value
InternalCF * value
Definition canonicalform.h:88
CanonicalForm::isZero
CF_NO_INLINE bool isZero() const
CanonicalForm::isHomogeneous
bool isHomogeneous() const
Definition canonicalform.cc:165
CanonicalForm::isFFinGF
bool isFFinGF() const
Definition canonicalform.cc:149
CanonicalForm::inFF
bool inFF() const
Definition canonicalform.cc:92
CanonicalForm::degree
int degree() const
Returns -1 for the zero polynomial and 0 if CO is in a base domain.
Definition canonicalform.cc:414
CanonicalForm::inExtension
bool inExtension() const
Definition canonicalform.cc:113
CanonicalForm::sign
int sign() const
int CanonicalForm::sign () const
Definition canonicalform.cc:1360
CanonicalForm::deepCopy
CanonicalForm deepCopy() const
Definition canonicalform.cc:43
CanonicalForm::inQuotDomain
bool inQuotDomain() const
Definition canonicalform.cc:140
CanonicalForm::inPolyDomain
bool inPolyDomain() const
Definition canonicalform.cc:131
CanonicalForm::CanonicalForm
CF_INLINE CanonicalForm()
CF_INLINE CanonicalForm::CanonicalForm ().
Definition cf_inline.cc:127
CanonicalForm::Lc
CanonicalForm Lc() const
Definition canonicalform.cc:352
CanonicalForm::mvar
Variable mvar() const
mvar() returns the main variable of CO or Variable() if CO is in a base domain.
Definition canonicalform.cc:593
CanonicalForm::inQ
bool inQ() const
Definition canonicalform.cc:80
CanonicalForm::operator%=
CanonicalForm & operator%=(const CanonicalForm &)
Definition canonicalform.cc:948
CanonicalForm::getval
InternalCF * getval() const
Definition canonicalform.cc:34
CanonicalForm::tailcoeff
CanonicalForm tailcoeff() const
tailcoeff() - return least coefficient
Definition canonicalform.cc:498
CanonicalForm::intval
long intval() const
conversion functions
Definition canonicalform.cc:200
CanonicalForm::genZero
CanonicalForm genZero() const
genOne(), genZero()
Definition canonicalform.cc:1867
CanonicalForm::operator[]
CanonicalForm operator[](int i) const
operator []() - return i'th coefficient from CO.
Definition canonicalform.cc:1277
CanonicalForm::deriv
CanonicalForm deriv() const
deriv() - return the formal derivation of CO.
Definition canonicalform.cc:1300
CanonicalForm::operator+=
CanonicalForm & operator+=(const CanonicalForm &)
assignment operators
Definition canonicalform.cc:638
CanonicalForm::CFIterator
friend class CFIterator
Definition canonicalform.h:202
CanonicalForm::inCoeffDomain
bool inCoeffDomain() const
Definition canonicalform.cc:122
CanonicalForm::inZ
bool inZ() const
predicates
Definition canonicalform.cc:69
CanonicalForm::operator*=
CanonicalForm & operator*=(const CanonicalForm &)
Definition canonicalform.cc:727
CanonicalForm::level
int level() const
level() returns the level of CO.
Definition canonicalform.cc:576
CanonicalForm::tryDiv
CanonicalForm & tryDiv(const CanonicalForm &, const CanonicalForm &, bool &)
same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
Definition canonicalform.cc:905
CanonicalForm::sqrt
CanonicalForm sqrt() const
CanonicalForm CanonicalForm::sqrt () const.
Definition canonicalform.cc:1383
CanonicalForm::inBaseDomain
bool inBaseDomain() const
Definition canonicalform.cc:104
CanonicalForm::isImm
bool isImm() const
Definition canonicalform.h:110
CanonicalForm::mod
CanonicalForm & mod(const CanonicalForm &)
Definition canonicalform.cc:990
CanonicalForm::mapinto
CanonicalForm mapinto() const
Definition canonicalform.cc:210
CanonicalForm::ilog2
int ilog2() const
int CanonicalForm::ilog2 () const
Definition canonicalform.cc:1417
CanonicalForm::lc
CanonicalForm lc() const
CanonicalForm CanonicalForm::lc (), Lc (), LC (), LC ( v ) const.
Definition canonicalform.cc:337
CanonicalForm::mpzval
void mpzval(mpz_t val) const
Definition canonicalform.cc:52
CanonicalForm::operator-=
CanonicalForm & operator-=(const CanonicalForm &)
Definition canonicalform.cc:685
CanonicalForm::num
CanonicalForm num() const
num() returns the numerator of CO if CO is a rational number, CO itself otherwise.
Definition canonicalform.cc:611
CanonicalForm::print
void print(OSTREAM &, char *) const
input/output
Definition canonicalform.cc:1833
CanonicalForm::taildegree
int taildegree() const
taildegree() returns -1 for the zero polynomial, 0 if CO is in a base domain, otherwise the least deg...
Definition canonicalform.cc:552
CanonicalForm::isUnivariate
bool isUnivariate() const
Definition canonicalform.cc:155
CanonicalForm::div
CanonicalForm & div(const CanonicalForm &)
Definition canonicalform.cc:862
CanonicalForm::operator/=
CanonicalForm & operator/=(const CanonicalForm &)
Definition canonicalform.cc:808
InternalCF
virtual class for internal CanonicalForm's
Definition int_cf.h:47
InternalCF::addcoeff
virtual InternalCF * addcoeff(InternalCF *) PVIRT_INTCF("addcoeff")
InternalCF::tryDivcoeff
virtual InternalCF * tryDivcoeff(InternalCF *, bool, const CanonicalForm &, bool &)
Definition int_cf.cc:214
InternalCF::mulcoeff
virtual InternalCF * mulcoeff(InternalCF *) PVIRT_INTCF("mulcoeff")
InternalCF::divcoeff
virtual InternalCF * divcoeff(InternalCF *, bool) PVIRT_INTCF("divcoeff")
InternalCF::subcoeff
virtual InternalCF * subcoeff(InternalCF *, bool) PVIRT_INTCF("subcoeff")
InternalCF::dividecoeff
virtual InternalCF * dividecoeff(InternalCF *, bool) PVIRT_INTCF("dividecoeff")
InternalCF::levelcoeff
virtual int levelcoeff() const
Definition int_cf.h:68
InternalCF::comparesame
virtual int comparesame(InternalCF *) PVIRT_INT("comparesame")
InternalCF::comparecoeff
virtual int comparecoeff(InternalCF *) PVIRT_INT("comparecoeff")
InternalCF::modulocoeff
virtual InternalCF * modulocoeff(InternalCF *, bool) PVIRT_INTCF("dividecoeff")
InternalCF::level
virtual int level() const
Definition int_cf.h:67
InternalCF::modcoeff
virtual InternalCF * modcoeff(InternalCF *, bool) PVIRT_INTCF("modcoeff")
InternalPrimePower::primepowhalf
STATIC_VAR mpz_t primepowhalf
Definition int_pp.h:37
InternalPrimePower::primepow
STATIC_VAR mpz_t primepow
Definition int_pp.h:36
List::getFirst
T getFirst() const
Definition ftmpl_list.cc:279
Variable
factory's class for variables
Definition factory.h:127
result
return result
Definition facAbsBiFact.cc:76
y
const CanonicalForm int const CFList const Variable & y
Definition facAbsFact.cc:53
hasAlgVar
int hasAlgVar(const CanonicalForm &f, const Variable &v)
Definition facAlgFuncUtil.cc:322
facAlgFuncUtil.h
Utility functions for factorization over algebraic function fields.
v
const Variable & v
< [in] a sqrfree bivariate poly
Definition facBivar.h:39
mulNTL
CanonicalForm mulNTL(const CanonicalForm &F, const CanonicalForm &G, const modpk &b)
multiplication of univariate polys using FLINT/NTL over F_p, F_q, Z/p^k, Z/p^k[t]/(f),...
Definition facMul.cc:417
divNTL
CanonicalForm divNTL(const CanonicalForm &F, const CanonicalForm &G, const modpk &b)
division of univariate polys using FLINT/NTL over F_p, F_q, Z/p^k, Z/p^k[t]/(f), Z,...
Definition facMul.cc:942
facMul.h
This file defines functions for fast multiplication and division with remainder.
hasMipo
bool hasMipo(const Variable &alpha)
Definition variable.cc:226
ff_prime
VAR int ff_prime
Definition ffops.cc:23
ff_norm
int ff_norm(const int a)
Definition ffops.h:39
ff_symmetric
int ff_symmetric(const int a)
Definition ffops.h:67
gInt
static long gInt(number &a, const coeffs)
Definition generics.cc:143
gfops.h
Operations in GF, where GF is a finite field of size less than 2^16 represented by a root of Conway p...
gf_int2gf
int gf_int2gf(int i)
Definition gfops.h:65
imm.h
operations on immediates, that is elements of F_p, GF, Z, Q that fit into intrinsic int,...
imm2int
static long imm2int(const InternalCF *const imm)
Definition imm.h:70
int2imm_p
InternalCF * int2imm_p(long i)
Definition imm.h:101
imm_sign
int imm_sign(const InternalCF *const op)
imm_sign() - return sign of immediate object.
Definition imm.h:200
imm_iszero
int imm_iszero(const InternalCF *const ptr)
Definition imm.h:145
imm_iszero_gf
int imm_iszero_gf(const InternalCF *const ptr)
Definition imm.h:157
imm_intval
long imm_intval(const InternalCF *const op)
Definition imm.h:164
FFMARK
const long FFMARK
Definition imm.h:38
imm_iszero_p
int imm_iszero_p(const InternalCF *const ptr)
Definition imm.h:151
INTMARK
const long INTMARK
Definition imm.h:37
int2imm_gf
InternalCF * int2imm_gf(long i)
Definition imm.h:106
int2imm
static InternalCF * int2imm(long i)
Definition imm.h:75
GFMARK
const long GFMARK
Definition imm.h:39
LEVELBASE
#define LEVELBASE
Definition factory.h:82
size
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition cf_ops.cc:600
OSTREAM
#define OSTREAM
get_Terms
CFList get_Terms(const CanonicalForm &f)
Definition cf_factor.cc:293
size_maxexp
int size_maxexp(const CanonicalForm &f, int &maxexp)
Definition cf_ops.cc:641
getGFDegree
int getGFDegree()
Definition cf_char.cc:75
is_imm
int is_imm(const InternalCF *const ptr)
Definition factory.h:215
SW_RATIONAL
static const int SW_RATIONAL
set to 1 for computations over Q
Definition factory.h:88
swapvar
CanonicalForm FACTORY_PUBLIC swapvar(const CanonicalForm &, const Variable &, const Variable &)
swapvar() - swap variables x1 and x2 in f.
Definition cf_ops.cc:168
CFListIterator
ListIterator< CanonicalForm > CFListIterator
Definition factory.h:537
totaldegree
int totaldegree(const CanonicalForm &f)
int totaldegree ( const CanonicalForm & f )
Definition cf_ops.cc:523
gf_gf2ff
long gf_gf2ff(long a)
Definition gfops.cc:209
ISTREAM
#define ISTREAM
power
CanonicalForm FACTORY_PUBLIC power(const CanonicalForm &f, int n)
exponentiation
Definition canonicalform.cc:1896
CFList
List< CanonicalForm > CFList
Definition factory.h:536
getCharacteristic
int FACTORY_PUBLIC getCharacteristic()
Definition cf_char.cc:70
gf_isff
bool gf_isff(long a)
Definition gfops.cc:253
int_cf.h
Factory's internal CanonicalForm's.
int_pp.h
h
STATIC_VAR Poly * h
Definition janet.cc:971
SI_LOG2_LONG
static int SI_LOG2_LONG(long v)
Definition si_log2.h:22
M
#define M
Definition sirandom.c:25
getReduce
bool getReduce(const Variable &alpha)
Definition variable.cc:232