//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // FACTORY - Includes #include #ifdef HAVE_IOSTREAM #include #define OSTREAM std::ostream #define ISTREAM std::istream #define CERR std::cerr #define CIN std::cin #elif defined(HAVE_IOSTREAM_H) #include #define OSTREAM ostream #define ISTREAM istream #define CERR cerr #define CIN cin #endif // Factor - Includes #include "tmpl_inst.h" #include "Factor.h" // some CC's need it: #include "homogfactor.h" void out_cf(char *s1,const CanonicalForm &f,char *s2); #ifdef HFACTORDEBUG # define DEBUGOUTPUT #else # undef DEBUGOUTPUT #endif #include #include "timing.h" TIMING_DEFINE_PRINT(hfactorize_time) #if 0 /////////////////////////////////////////////////////////////// // get_Terms: Split the polynomial in the containing terms. // // getTerms: the real work is done here. // /////////////////////////////////////////////////////////////// static void getTerms( const CanonicalForm & f, const CanonicalForm & t, CFList & result ){ if ( getNumVars(f) == 0 ) result.append(f*t); else{ Variable x(level(f)); for ( CFIterator i=f; i.hasTerms(); i++ ) getTerms( i.coeff(), t*power(x,i.exp()), result); } } CFList get_Terms( const CanonicalForm & f ){ CFList result,dummy,dummy2; CFIterator i; CFListIterator j; if ( getNumVars(f) == 0 ) result.append(f); else{ Variable _x(level(f)); for ( i=f; i.hasTerms(); i++ ){ getTerms(i.coeff(), 1, dummy); for ( j=dummy; j.hasItem(); j++ ) result.append(j.getItem() * power(_x, i.exp())); dummy= dummy2; // have to initalize new } } return result; } #endif #if 0 /////////////////////////////////////////////////////////////// // is_homogeneous returns 1 iff f is homogeneous, 0 otherwise// /////////////////////////////////////////////////////////////// bool is_homogeneous( const CanonicalForm & f){ CFList termlist= get_Terms(f); CFListIterator i; int deg= totaldegree(termlist.getFirst()); for ( i=termlist; i.hasItem(); i++ ) if ( totaldegree(i.getItem()) != deg ) return 0; return 1; // now: return f.isHomogeneous(); } #endif #if 0 /////////////////////////////////////////////////////////////// // get_max_degree_Variable returns Variable with // // highest degree. We assume f is *not* a constant! // /////////////////////////////////////////////////////////////// static Variable get_max_degree_Variable(const CanonicalForm & f){ ASSERT( ( ! f.inCoeffDomain() ), "no constants" ); int max=0, maxlevel=0, n=level(f); for ( int i=1; i<=n; i++ ) if (degree(f,Variable(i)) >= max) { max= degree(f,Variable(i)); maxlevel= i; } return Variable(maxlevel); } #endif #if 0 /////////////////////////////////////////////////////////////// // homogenize homogenizes f with Variable x // /////////////////////////////////////////////////////////////// static CanonicalForm homogenize( const CanonicalForm & f, const Variable & x){ CFList Newlist, Termlist= get_Terms(f); int maxdeg=totaldegree(f), deg; CFListIterator i; CanonicalForm elem, result=f.genZero(); for (i=Termlist; i.hasItem(); i++){ elem= i.getItem(); deg = totaldegree(elem); if ( deg < maxdeg ) Newlist.append(elem * power(x,maxdeg-deg)); else Newlist.append(elem); } for (i=Newlist; i.hasItem(); i++) // rebuild result += i.getItem(); return result; } #endif // we assume g is square-free CFFList HomogFactor( const CanonicalForm & g, const CanonicalForm & minpoly, const int Mainvar ) { DEBINCLEVEL(CERR, "HomogFactor"); Variable xn = get_max_degree_Variable(g); //out_cf("HomogFactor:",g,"\n"); int d_xn = degree(g,xn); CanonicalForm F = g(1,xn); DEBOUTLN(CERR, "xn= ", xn); DEBOUTLN(CERR, "d_xn= ", d_xn); DEBOUTLN(CERR, "F= ", F); //out_cf("HomogFactor:subst ",F,"\n"); // should we do this for low degree polys g ? e.g. quadratic? // CFFList Homoglist; CFFListIterator j; if (minpoly.isZero()) Homoglist = factorize(F, 1); else { CFFList Intermediatelist; CFMap n; Intermediatelist = Factorized(compress(F,n), minpoly, Mainvar); for ( j=Intermediatelist; j.hasItem(); j++ ) Homoglist.append(CFFactor( n(j.getItem().factor()), j.getItem().exp()) ); } // Now we have uncompressed factors in Homoglist DEBOUTLN(CERR, "F factors as: ", Homoglist); CFFList Unhomoglist; CanonicalForm unhomogelem; if ((!(minpoly.isZero())) &&(getCharacteristic() == 0) ) { for ( j=Homoglist; j.hasItem(); j++ ) { // assume that minpoly.level() < level of all "real" variables of g DEBOUTLN(CERR, "Homogenizing ",j.getItem().factor()); unhomogelem= homogenize(j.getItem().factor(),xn, Variable(minpoly.level()+1),g.mvar()); DEBOUTLN(CERR, " that is ", unhomogelem); Unhomoglist.append(CFFactor(unhomogelem,j.getItem().exp())); d_xn -= degree(unhomogelem,xn)*j.getItem().exp(); } } else { for ( j=Homoglist; j.hasItem(); j++ ) { DEBOUTLN(CERR, "Homogenizing ",j.getItem().factor()); unhomogelem= homogenize(j.getItem().factor(),xn); DEBOUTLN(CERR, " that is ", unhomogelem); //out_cf("unhomogelem:",unhomogelem,"\n"); Unhomoglist.append(CFFactor(unhomogelem,j.getItem().exp())); d_xn -= degree(unhomogelem,xn)*j.getItem().exp(); } } DEBOUTLN(CERR, "Power of xn to append is ", d_xn); if ( d_xn != 0 ) // have to append xn^(d_xn) Unhomoglist.append(CFFactor(CanonicalForm(xn),d_xn)); DEBDECLEVEL(CERR, "HomogFactor"); return Unhomoglist; }