![]() |
My Project
|
declarations of higher level algorithms. More...
Go to the source code of this file.
Variables | |
| EXTERN_VAR int | singular_homog_flag |
declarations of higher level algorithms.
Header file corresponds to: cf_algorithm.cc, cf_chinese.cc, cf_factor.cc, cf_linsys.cc, cf_resultant.cc
Hierarchy: mathematical algorithms on canonical forms
This header file collects declarations of most of the functions in Factory which implement higher level algorithms on canonical forms (factorization, gcd, etc.) and declarations of some low level mathematical functions, too (absolute value, euclidean norm, etc.).
Definition in file cf_algorithm.h.
| CanonicalForm FACTORY_PUBLIC bCommonDen | ( | const CanonicalForm & | f | ) |
void psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable & x )
psqr() - calculate pseudo quotient and remainder of f' and g' with respect to `x'.
Returns the pseudo quotient of f' and g' in q', the pseudo remainder in r'. `g' must not equal zero.
See `psr()' for more detailed information.
f, g: Current q, r: Anything x: Polynomial
This is not an optimal implementation. Better would have been an implementation in InternalPoly' avoiding the exponentiation of the leading coefficient of g'. It seemed not worth to do so.
**/ void psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable& x ) { ASSERT( x.level() > 0, "type error: polynomial variable expected" ); ASSERT( ! g.isZero(), "math error: division by zero" );
swap variables such that x's level is larger or equal than both f's and g's levels. Variable X = tmax( tmax( f.mvar(), g.mvar() ), x ); CanonicalForm F = swapvar( f, x, X ); CanonicalForm G = swapvar( g, x, X );
now, we have to calculate the pseudo remainder of F and G w.r.t. X int fDegree = degree( F, X ); int gDegree = degree( G, X ); if ( fDegree < 0 || fDegree < gDegree ) { q = 0; r = f; } else { divrem( power( LC( G, X ), fDegree-gDegree+1 ) * F, G, q, r ); q = swapvar( q, x, X ); r = swapvar( r, x, X ); } }
/** static CanonicalForm internalBCommonDen ( const CanonicalForm & f )
internalBCommonDen() - recursively calculate multivariate common denominator of coefficients of `f'.
Used by: bCommonDen()
f: Poly( Q ) Switches: isOff( SW_RATIONAL )
**/ static CanonicalForm internalBCommonDen ( const CanonicalForm & f ) { if ( f.inBaseDomain() ) return f.den(); else { CanonicalForm result = 1; for ( CFIterator i = f; i.hasTerms(); i++ ) result = blcm( result, internalBCommonDen( i.coeff() ) ); return result; } }
/** CanonicalForm bCommonDen ( const CanonicalForm & f )
bCommonDen() - calculate multivariate common denominator of coefficients of `f'.
The common denominator is calculated with respect to all coefficients of f' which are in a base domain. In other words, common_den( f' ) * `f' is guaranteed to have integer coefficients only. The common denominator of zero is one.
Returns something non-trivial iff the current domain is Q.
f: CurrentPP
Definition at line 293 of file cf_algorithm.cc.
| void FACTORY_PUBLIC chineseRemainder | ( | const CanonicalForm & | x1, |
| const CanonicalForm & | q1, | ||
| const CanonicalForm & | x2, | ||
| const CanonicalForm & | q2, | ||
| CanonicalForm & | xnew, | ||
| CanonicalForm & | qnew ) |
void chineseRemainder ( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2, const CanonicalForm & q2, CanonicalForm & xnew, CanonicalForm & qnew )
chineseRemainder - integer chinese remaindering.
Calculate xnew such that xnew=x1 (mod q1) and xnew=x2 (mod q2) and qnew = q1*q2. q1 and q2 should be positive integers, pairwise prime, x1 and x2 should be polynomials with integer coefficients. If x1 and x2 are polynomials with positive coefficients, the result is guaranteed to have positive coefficients, too.
Note: This algorithm is optimized for the case q1>>q2.
This is a standard algorithm. See, for example, Geddes/Czapor/Labahn - 'Algorithms for Computer Algebra', par. 5.6 and 5.8, or the article of M. Lauer - 'Computing by Homomorphic Images' in B. Buchberger - 'Computer Algebra - Symbolic and Algebraic Computation'.
Note: Be sure you are calculating in Z, and not in Q!
Definition at line 57 of file cf_chinese.cc.
| void FACTORY_PUBLIC chineseRemainder | ( | const CFArray & | x, |
| const CFArray & | q, | ||
| CanonicalForm & | xnew, | ||
| CanonicalForm & | qnew ) |
void chineseRemainder ( const CFArray & x, const CFArray & q, CanonicalForm & xnew, CanonicalForm & qnew )
chineseRemainder - integer chinese remaindering.
Calculate xnew such that xnew=x[i] (mod q[i]) and qnew is the product of all q[i]. q[i] should be positive integers, pairwise prime. x[i] should be polynomials with integer coefficients. If all coefficients of all x[i] are positive integers, the result is guaranteed to have positive coefficients, too.
This is a standard algorithm, too, except for the fact that we use a divide-and-conquer method instead of a linear approach to calculate the remainder.
Note: Be sure you are calculating in Z, and not in Q!
Definition at line 124 of file cf_chinese.cc.
| void FACTORY_PUBLIC chineseRemainderCached | ( | const CanonicalForm & | x1, |
| const CanonicalForm & | q1, | ||
| const CanonicalForm & | x2, | ||
| const CanonicalForm & | q2, | ||
| CanonicalForm & | xnew, | ||
| CanonicalForm & | qnew, | ||
| CFArray & | inv ) |
Definition at line 308 of file cf_chinese.cc.
| void FACTORY_PUBLIC chineseRemainderCached | ( | const CFArray & | a, |
| const CFArray & | n, | ||
| CanonicalForm & | xnew, | ||
| CanonicalForm & | prod, | ||
| CFArray & | inv ) |
Definition at line 290 of file cf_chinese.cc.
| CanonicalForm FACTORY_PUBLIC determinant | ( | const CFMatrix & | M, |
| int | n ) |
Definition at line 222 of file cf_linsys.cc.
| CanonicalForm euclideanNorm | ( | const CanonicalForm & | f | ) |
| CFFList FACTORY_PUBLIC factorize | ( | const CanonicalForm & | f, |
| bool | issqrfree = false ) |
factorization over 

Definition at line 411 of file cf_factor.cc.
| CFFList FACTORY_PUBLIC factorize | ( | const CanonicalForm & | f, |
| const Variable & | alpha ) |
factorization over 

Definition at line 780 of file cf_factor.cc.
| CanonicalForm Farey | ( | const CanonicalForm & | f, |
| const CanonicalForm & | q ) |
Farey rational reconstruction.
If NTL is available it uses the fast algorithm from NTL, i.e. Encarnacion, Collins.
Definition at line 202 of file cf_chinese.cc.
| bool fdivides | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g ) |
| bool fdivides | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g, | ||
| CanonicalForm & | quot ) |
| Variable get_max_degree_Variable | ( | const CanonicalForm & | f | ) |
get_max_degree_Variable returns Variable with highest degree.
We assume f is not a constant!
Definition at line 266 of file cf_factor.cc.
| CFList get_Terms | ( | const CanonicalForm & | f | ) |
Definition at line 295 of file cf_factor.cc.
| void getTerms | ( | const CanonicalForm & | f, |
| const CanonicalForm & | t, | ||
| CFList & | result ) |
get_Terms: Split the polynomial in the containing terms.
getTerms: the real work is done here.
Definition at line 285 of file cf_factor.cc.
| CanonicalForm homogenize | ( | const CanonicalForm & | f, |
| const Variable & | x ) |
homogenize homogenizes f with Variable x
Definition at line 319 of file cf_factor.cc.
| CanonicalForm homogenize | ( | const CanonicalForm & | f, |
| const Variable & | x, | ||
| const Variable & | v1, | ||
| const Variable & | v2 ) |
Definition at line 359 of file cf_factor.cc.
| bool isPurePoly | ( | const CanonicalForm & | f | ) |
Definition at line 250 of file cf_factor.cc.
| bool isPurePoly_m | ( | const CanonicalForm & | f | ) |
Definition at line 240 of file cf_factor.cc.
| bool linearSystemSolve | ( | CFMatrix & | M | ) |
Definition at line 78 of file cf_linsys.cc.
| CanonicalForm maxNorm | ( | const CanonicalForm & | f | ) |
bool fdivides ( const CanonicalForm & f, const CanonicalForm & g )
fdivides() - check whether f' divides g'.
Returns true iff f' divides g'. Uses some extra heuristic to avoid polynomial division. Without the heuristic, the test essentialy looks like `divremt(g, f, q, r) && r.isZero()'.
f, g: Current
Elements from prime power domains (or polynomials over such domains) are admissible if f' (or lc(f'), resp.) is not a zero divisor. This is a slightly stronger precondition than mathematically necessary since divisibility is a well-defined notion in arbitrary rings. Hence, we decided not to declare the weaker type `CurrentPP'.
One may consider the the test fdivides( f.LC(), g.LC() )' in the main if'-test superfluous since divremt()' in the if'-body repeats the test. However, `divremt()' does not use any heuristic to do so.
It seems not reasonable to call fdivides()' from divremt()' to check divisibility of leading coefficients. fdivides()' is on a relatively high level compared to divremt()'.
**/ bool fdivides ( const CanonicalForm & f, const CanonicalForm & g ) { trivial cases if ( g.isZero() ) return true; else if ( f.isZero() ) return false;
if ( (f.inCoeffDomain() || g.inCoeffDomain()) && ((getCharacteristic() == 0 && isOn( SW_RATIONAL )) || (getCharacteristic() > 0) )) { if we are in a field all elements not equal to zero are units if ( f.inCoeffDomain() ) return true; else g.inCoeffDomain() return false; }
we may assume now that both levels either equal LEVELBASE or are greater zero int fLevel = f.level(); int gLevel = g.level(); if ( (gLevel > 0) && (fLevel == gLevel) ) f and g are polynomials in the same main variable if ( degree( f ) <= degree( g ) && fdivides( f.tailcoeff(), g.tailcoeff() ) && fdivides( f.LC(), g.LC() ) ) { CanonicalForm q, r; return divremt( g, f, q, r ) && r.isZero(); } else return false; else if ( gLevel < fLevel ) g is a coefficient w.r.t. f return false; else { either f is a coefficient w.r.t. polynomial g or both f and g are from a base domain (should be Z or Z/p^n, then) CanonicalForm q, r; return divremt( g, f, q, r ) && r.isZero(); } }
/ same as fdivides if true returns quotient quot of g by f otherwise quot == 0 bool fdivides ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm& quot ) { quot= 0; trivial cases if ( g.isZero() ) return true; else if ( f.isZero() ) return false;
if ( (f.inCoeffDomain() || g.inCoeffDomain()) && ((getCharacteristic() == 0 && isOn( SW_RATIONAL )) || (getCharacteristic() > 0) )) { if we are in a field all elements not equal to zero are units if ( f.inCoeffDomain() ) { quot= g/f; return true; } else g.inCoeffDomain() return false; }
we may assume now that both levels either equal LEVELBASE or are greater zero int fLevel = f.level(); int gLevel = g.level(); if ( (gLevel > 0) && (fLevel == gLevel) ) f and g are polynomials in the same main variable if ( degree( f ) <= degree( g ) && fdivides( f.tailcoeff(), g.tailcoeff() ) && fdivides( f.LC(), g.LC() ) ) { CanonicalForm q, r; if (divremt( g, f, q, r ) && r.isZero()) { quot= q; return true; } else return false; } else return false; else if ( gLevel < fLevel ) g is a coefficient w.r.t. f return false; else { either f is a coefficient w.r.t. polynomial g or both f and g are from a base domain (should be Z or Z/p^n, then) CanonicalForm q, r; if (divremt( g, f, q, r ) && r.isZero()) { quot= q; return true; } else return false; } }
/ same as fdivides but handles zero divisors in Z_p[t]/(f)[x1,...,xn] for reducible f bool tryFdivides ( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm& M, bool& fail ) { fail= false; trivial cases if ( g.isZero() ) return true; else if ( f.isZero() ) return false;
if (f.inCoeffDomain() || g.inCoeffDomain()) { if we are in a field all elements not equal to zero are units if ( f.inCoeffDomain() ) { CanonicalForm inv; tryInvert (f, M, inv, fail); return !fail; } else { return false; } }
we may assume now that both levels either equal LEVELBASE or are greater zero int fLevel = f.level(); int gLevel = g.level(); if ( (gLevel > 0) && (fLevel == gLevel) ) { if (degree( f ) > degree( g )) return false; bool dividestail= tryFdivides (f.tailcoeff(), g.tailcoeff(), M, fail);
if (fail || !dividestail) return false; bool dividesLC= tryFdivides (f.LC(),g.LC(), M, fail); if (fail || !dividesLC) return false; CanonicalForm q,r; bool divides= tryDivremt (g, f, q, r, M, fail); if (fail || !divides) return false; return r.isZero(); } else if ( gLevel < fLevel ) { g is a coefficient w.r.t. f return false; } else { either f is a coefficient w.r.t. polynomial g or both f and g are from a base domain (should be Z or Z/p^n, then) CanonicalForm q, r; bool divides= tryDivremt (g, f, q, r, M, fail); if (fail || !divides) return false; return r.isZero(); } }
/** CanonicalForm maxNorm ( const CanonicalForm & f )
maxNorm() - return maximum norm of `f'.
That is, the base coefficient of `f' with the largest absolute value.
Valid for arbitrary polynomials over arbitrary domains, but most useful for multivariate polynomials over Z.
f: CurrentPP
Definition at line 536 of file cf_algorithm.cc.
| CanonicalForm psq | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g, | ||
| const Variable & | x ) |
cf_algorithm.cc - simple mathematical algorithms.
Hierarchy: mathematical algorithms on canonical forms
A "mathematical" algorithm is an algorithm which calculates some mathematical function in contrast to a "structural" algorithm which gives structural information on polynomials.
Compare these functions to the functions in `cf_ops.cc', which are structural algorithms.
**/
void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
/** CanonicalForm psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
psr() - return pseudo remainder of f' and g' with respect to `x'.
`g' must not equal zero.
For f and g in R[x], R an arbitrary ring, g != 0, there is a representation
LC(g)^s*f = g*q + r
with r = 0 or deg(r) < deg(g) and s = 0 if f = 0 or s = max( 0, deg(f)-deg(g)+1 ) otherwise. r = psr(f, g) and q = psq(f, g) are called "pseudo remainder" and "pseudo quotient", resp. They are uniquely determined if LC(g) is not a zero divisor in R.
See H.-J. Reiffen/G. Scheja/U. Vetter - "Algebra", 2nd ed., par. 15, for a reference.
f, g: Current x: Polynomial
Polynomials over prime power domains are admissible if lc(LC(g',x')) is not a zero divisor. This is a slightly stronger precondition than mathematically necessary since pseudo remainder and quotient are well-defined if LC(g',x') is not a zero divisor.
For example, psr(y^2, (13*x+1)*y) is well-defined in (Z/13^2[x])[y] since (13*x+1) is not a zero divisor. But calculating it with Factory would fail since 13 is a zero divisor in Z/13^2.
Due to this inconsistency with mathematical notion, we decided not to declare type CurrentPP' for f' and `g'.
This is not an optimal implementation. Better would have been an implementation in InternalPoly' avoiding the exponentiation of the leading coefficient of g'. In contrast to psq()' and psqr()' it definitely seems worth to implement the pseudo remainder on the internal level.
psr ( const CanonicalForm &rr, const CanonicalForm &vv, const Variable & x ) { CanonicalForm r=rr, v=vv, l, test, lu, lv, t, retvalue; int dr, dv, d,n=0;
dr = degree( r, x ); if (dr>0) { dv = degree( v, x ); if (dv <= dr) {l=LC(v,x); v = v -l*power(x,dv);} else { l = 1; } d= dr-dv+1; out_cf("psr(",rr," "); out_cf("",vv," "); printf(" var=%d\n",x.level()); while ( ( dv <= dr ) && ( !r.isZero()) ) { test = power(x,dr-dv)*v*LC(r,x); if ( dr == 0 ) { r= CanonicalForm(0); } else { r= r - LC(r,x)*power(x,dr); } r= l*r -test; dr= degree(r,x); n+=1; } r= power(l, d-n)*r; } return r; }
/** CanonicalForm psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
psq() - return pseudo quotient of f' and g' with respect to `x'.
`g' must not equal zero.
f, g: Current x: Polynomial
This is not an optimal implementation. Better would have been an implementation in InternalPoly' avoiding the exponentiation of the leading coefficient of g'. It seemed not worth to do so.
Definition at line 172 of file cf_algorithm.cc.
| void psqr | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g, | ||
| CanonicalForm & | q, | ||
| CanonicalForm & | r, | ||
| const Variable & | x ) |
| CanonicalForm psr | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g, | ||
| const Variable & | x ) |
| CanonicalForm FACTORY_PUBLIC resultant | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g, | ||
| const Variable & | x ) |
CanonicalForm resultant ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x ).
resultant() - return resultant of f and g with respect to x.
The chain is calculated from f and g with respect to variable x which should not be an algebraic variable. If f or q equals zero, zero is returned. If f is a coefficient with respect to x, f^degree(g, x) is returned, analogously for g.
This algorithm serves as a wrapper around other resultant algorithms which do the real work. Here we use standard properties of resultants only.
Definition at line 173 of file cf_resultant.cc.
| CFFList FACTORY_PUBLIC sqrFree | ( | const CanonicalForm & | f, |
| bool | sort = false ) |
squarefree factorization
Definition at line 963 of file cf_factor.cc.
| CFArray subResChain | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g, | ||
| const Variable & | x ) |
CFArray subResChain ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x ).
subResChain() - caculate extended subresultant chain.
The chain is calculated from f and g with respect to variable x which should not be an algebraic variable. If f or q equals zero, an array consisting of one zero entry is returned.
Note: this is not the standard subresultant chain but the extended chain!
This algorithm is from the article of R. Loos - 'Generalized Polynomial Remainder Sequences' in B. Buchberger - 'Computer Algebra - Symbolic and Algebraic Computation' with some necessary extensions concerning the calculation of the first step.
Definition at line 42 of file cf_resultant.cc.
| bool tryFdivides | ( | const CanonicalForm & | f, |
| const CanonicalForm & | g, | ||
| const CanonicalForm & | M, | ||
| bool & | fail ) |
| EXTERN_VAR int singular_homog_flag |
Definition at line 65 of file cf_algorithm.h.