gfan0.6.2/0000755000175000017500000000000013163176266011702 5ustar andersandersgfan0.6.2/src/0000755000175000017500000000000013163176175012470 5ustar andersandersgfan0.6.2/src/traverser_resultantfan.h0000644000175000017500000000266313122232611017432 0ustar andersanders/* * traverser_resultantfan.h * * Created on: Apr 29, 2011 * Author: anders */ #ifndef TRAVERSER_RESULTANTFAN_H_INCLUDED #define TRAVERSER_RESULTANTFAN_H_INCLUDED #include "symmetrictraversal.h" #include "triangulation2.h" IntegerMatrix cayleyConfiguration(PolynomialSet const &g); IntegerMatrix cayleyConfiguration(list const &g, int d); vector > polynomialSetToIntervals(PolynomialSet const &g); set > mixedCells(vector > const&intervals, Triangulation2 const &t, IntegerMatrix const &A, IntegerVector const &w); vector > subsetToIntervals(PolynomialSet const &g, set const &subset); IntegerVectorList quickLink(IntegerMatrix const &m, set const &cell, vector > const &intervals, IntegerVectorList const &linealitySpace); class ResultantFanTraverser : public ConeTraverser { Triangulation2 theTriangulation; PolyhedralCone theCone; // PolynomialSet g; IntegerVectorListList tuple; IntegerMatrix theConfiguration; int n,d; public: ResultantFanTraverser(IntegerVectorListList const &tuple_, IntegerMatrix const &theConfiguration_); // ResultantFanTraverser(PolynomialSet const &g_, IntegerMatrix const &theConfiguration_); virtual void changeCone(IntegerVector const &ridgeVector, IntegerVector const &rayVector); virtual IntegerVectorList link(IntegerVector const &ridgeVector); PolyhedralCone &refToPolyhedralCone(); }; #endif gfan0.6.2/src/bergmanBackup.cpp0000644000175000017500000006251213122232611015722 0ustar andersanders#include "bergman.h" #include "enumeration.h" #include "reversesearch.h" #include "tropical.h" #include "buchberger.h" #include "division.h" #include "dimension.h" #include "wallideal.h" #include "lp.h" #include "subspace.h" #include "symmetry.h" #include "tropical2.h" #include "tropicalbasis.h" #include "polyhedralcone.h" #include "multiplicity.h" #include "log.h" static Polynomial wallPolynomial(Polynomial const &p, Subspace const &subspace) // This routine should be deleted since it is inefficient // hmm... does this actually work? { Polynomial r(p.getRing()); IntegerVector markedExponent=p.getMarked().m.exponent; for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { IntegerVector dif=markedExponent-i->first.exponent; if(subspace.contains(dif)) r+=Polynomial(Term(i->second,i->first)); } r.mark(Monomial(p.getRing(),markedExponent)); return r; } static PolynomialSet wallIdeal(PolynomialSet const &groebnerBasis, Subspace const &subspace) { // fprintf(Stderr,"wallIdeal %i",perp.size()); PolynomialSet ret(groebnerBasis.getRing()); for(PolynomialSet::const_iterator i=groebnerBasis.begin();i!=groebnerBasis.end();i++) ret.push_back(wallPolynomial(*i,subspace)); // fprintf(Stderr,"done\n"); return ret; } BergmanFan bergmanRayIntersection(PolynomialSet const &idealGroebnerBasis) // Input ideal is assumed to be homogeneous with respect to a positive vector // Input ideal is assumed not to contain a monomial // Call the Krull dimensionn of the ring/ideal d // The ideal is homogenous with respect to a vector space of dimension d-1 // All d dimensional cones in the Gro\"obner fan with no monomials are computed { BergmanFan bfan; int n=idealGroebnerBasis.numberOfVariablesInRing(); int d=krullDimension(idealGroebnerBasis); //There should be a better way of doing this PolyhedralFan bergmanFan(n); PolynomialSet tropBasis=tropicalBasisOfCurve(n,idealGroebnerBasis,&bergmanFan,d-1); // PolyhedralFan bergmanFan=tropicalPrincipalIntersection(n,tropBasis,d-1); IntegerVectorList rays=bergmanFan.getRays(d); int maximalConeLabel=0; // fprintf(Stderr,"---------------------------------------------------------\n"); // AsciiPrinter(Stderr).printVectorList(rays); // fprintf(Stderr,"---------------------------------------------------------\n"); for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) { PolynomialSet g=idealGroebnerBasis; buchberger(&g,WeightReverseLexicographicTermOrder(*i)); PolynomialSet cg=initialFormsAssumeMarked(g,*i); bool inList=false; for(BergmanFan::MaximalConeList::const_iterator j=bfan.cones.begin();j!=bfan.cones.end();j++) { if(areIdealsEqual(j->coneGroebnerBasis,cg)) { inList=true; break; } } if(!inList) { bfan.cones.push_back(BergmanFan::MaximalCone(cg,g,maximalConeLabel++)); } } // AsciiPrinter temp(Stderr); // bfan.print(temp); return bfan; } BergmanFan bergmanRay(PolynomialSet const &idealGroebnerBasis) // Input ideal is assumed to be homogeneous with respect to a positive vector // Input ideal is assumed not to contain a monomial // Call the Krull dimensionn of the ring/ideal d // The ideal is homogenous with respect to a vector space of dimension d-1 // All d dimensional cones in the Gro\"obner fan with no monomials are computed { BergmanFan bfan; EnumerationTargetCollector gfan; LexicographicTermOrder myTermOrder; ReverseSearch rs(myTermOrder); rs.setEnumerationTarget(&gfan); rs.enumerate(idealGroebnerBasis); int n=idealGroebnerBasis.numberOfVariablesInRing(); fprintf(Stderr,"rankOfMatrix(wallin.idealGroebnerBasis=%i\n",rankOfMatrix(wallInequalities(idealGroebnerBasis))); AsciiPrinter(Stderr).printVectorList(wallInequalities(idealGroebnerBasis)); int d=n-rankOfMatrix(wallInequalities(idealGroebnerBasis))+1; int krull=krullDimension(idealGroebnerBasis); //AsciiPrinter(Stderr).printVectorList(wallInequalities(idealGroebnerBasis)); assert(rankOfMatrix(wallInequalities(idealGroebnerBasis))==Subspace(wallInequalities(idealGroebnerBasis)).dimension()); // fprintf(Stderr,"d: %i krull: %i\n",d,krull); // assert(d==krull); int maximalConeLabel=0; for(PolynomialSetList::const_iterator g=gfan.theList.begin();g!=gfan.theList.end();g++) { PolynomialSetList s; //fprintf(Stderr,"current gbasis:\n"); //AsciiPrinter(Stderr).printPolynomialSet(*g); if(0) { s=fullColoredIdeals(*g,false); fprintf(Stderr,"Full colored ideals computed, #=%i\n",s.size()); } else { IntegerVectorList inequalities=wallInequalities(*g); inequalities=wallFlipableNormals(*g,true); int isize=inequalities.size(); // fprintf(Stderr,"cdd facets to rays "); // AsciiPrinter(Stderr).printVectorList(inequalities); IntegerVectorList rays=extremeRaysInequalityIndices(inequalities); //fprintf(Stderr,"done\n"); //AsciiPrinter(Stderr).printVectorList(rays); // AsciiPrinter(Stderr).printVectorList(rays); for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) if(i->size()!=isize) { IntegerVectorList perp; int j=0; int K=0; for(IntegerVectorList::const_iterator k=inequalities.begin();k!=inequalities.end()&&jsize();k++,K++) if((*i)[j]==K) { perp.push_back(*k); j++; } s.push_back(wallIdeal(*g,Subspace(perp))); } } //fprintf(Stderr,"Number of face ideals to check:%i\n",s.size()); for(PolynomialSetList::const_iterator i=s.begin();i!=s.end();i++) { //fprintf(Stderr,"d:%i\n",d); //fprintf(Stderr,"krull:%i\n",krull); //fprintf(Stderr,"n:%i\n",n); //fprintf(Stderr,"rank: %i\n",rankOfMatrix(wallInequalities(*i))); assert(i->isMarked()); // fprintf(Stderr,"d: %i, rank %i",d,n-rankOfMatrix(wallInequalities(*i))); if(d==n-rankOfMatrix(wallInequalities(*i)))//dimension check { // fprintf(Stderr,"Checking monomial containment"); if(!containsMonomial(*i)) { // fprintf(Stderr,"Done - no\n"); PolynomialSet cg=*i; //buchberger(&cg,StandardGradedLexicographicTermOrder()); The cg is already a Groebner basis bool inList=false; for(BergmanFan::MaximalConeList::const_iterator j=bfan.cones.begin();j!=bfan.cones.end();j++) { if(areIdealsEqual(j->coneGroebnerBasis,cg)) { inList=true; break; } } if(!inList) { bfan.cones.push_back(BergmanFan::MaximalCone(cg,*g,maximalConeLabel++)); } } // else // fprintf(Stderr,"Done - yes\n"); } else fprintf(Stderr,"dimension check fails\n"); } } //fprintf(Stderr,"No duplicates:\n"); /* for(PolynomialSetList::const_iterator i=tropical.begin();i!=tropical.end();i++) { AsciiPrinter(Stdout).printPolynomialList(i->coneGroebnerBasis); int coDim=rankOfMatrix(wallInequalities(*i)); int d=i->numberOfVariablesInRing()-coDim; fprintf(Stderr,"%i\n",d); } */ return bfan; } static bool staticInOrbit(PolynomialSet const &groebnerBasis1, PolynomialSet const &groebnerBasis2, SymmetryGroup const &s) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(areIdealsEqual(SymmetryGroup::permutePolynomialSet(groebnerBasis2,*j),groebnerBasis1))return true; return false; } static bool staticPermutationFixesCone(PolynomialSet const &groebnerBasis, IntegerVector const &v) { // Cone is fixed iff the cone ideal is fixed. PolynomialSet q(groebnerBasis.getRing()); for(PolynomialSet::const_iterator i=groebnerBasis.begin();i!=groebnerBasis.end();i++) { q.push_back(SymmetryGroup::permutePolynomial(*i,v)); } return areIdealsEqual(q,groebnerBasis); } static int staticOrbitSize(PolynomialSet const &groebnerBasis, SymmetryGroup const &s) { int groupSize=s.elements.size(); int numFixed=0; for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(staticPermutationFixesCone(groebnerBasis,*j))numFixed++; // fprintf(Stderr,"groupSize = %i, numFixed = %i\n",groupSize,numFixed); return groupSize/numFixed; } class ConeOrbit { public: const SymmetryGroup &s; PolynomialSet coneGroebnerBasis; PolynomialSet idealGroebnerBasis; int label; PolynomialSetList markedFacets; PolyhedralCone theCone; ConeOrbit(const SymmetryGroup &s_, PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &idealGroebnerBasis_, int label_): coneGroebnerBasis(coneGroebnerBasis_), idealGroebnerBasis(idealGroebnerBasis_), label(label_), s(s_), theCone(wallInequalities(coneGroebnerBasis_), wallFlipableNormals(idealGroebnerBasis_,false), idealGroebnerBasis_.getRing().getNumberOfVariables()) { theCone.findFacets(); } void markFacet(PolynomialSet const &f) { markedFacets.push_back(f); } bool containsAndMark(PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &facetIdeal, IntegerVector *labelPermutation) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(areIdealsEqual(coneGroebnerBasis,SymmetryGroup::permutePolynomialSet(coneGroebnerBasis_,*j))) { PolynomialSet facetIdeal2=SymmetryGroup::permutePolynomialSet(facetIdeal,*j); bool found=false; for(PolynomialSetList::const_iterator i=markedFacets.begin();i!=markedFacets.end();i++) if(areIdealsEqual(*i,facetIdeal2)) { found=true; break; } // assert(!found); //this is not a mistake is it? markedFacets.push_back(facetIdeal2); if(labelPermutation)*labelPermutation=*j; return true; } return false; } /* Alternative using only geometric information. */ /* bool containsAndMark(IntegerVector const &v, IntegerVector *labelPermutation) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(theCone.contains(SymmetryGroup::compose(*j,v))) { // PolynomialSet facetIdeal2=SymmetryGroup::permutePolynomialSet(facetIdeal,*j); bool found=false; for(PolynomialSetList::const_iterator i=markedFacets.begin();i!=markedFacets.end();i++) if(areIdealsEqual(*i,facetIdeal2)) { found=true; break; } // assert(!found); //this is not a mistake is it? markedFacets.push_back(facetIdeal2); if(labelPermutation)*labelPermutation=*j; return true; } return false; }*/ bool isMarkedFacet(PolynomialSet const &f) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(staticPermutationFixesCone(coneGroebnerBasis,*j)) for(PolynomialSetList::const_iterator i=markedFacets.begin();i!=markedFacets.end();i++) if(areIdealsEqual(SymmetryGroup::permutePolynomialSet(f,*j),*i))return true; return false; } int orbitSize() { return staticOrbitSize(coneGroebnerBasis,s); } void print(AsciiPrinter &p)const { p.printString("ConeOrbit{\n"); p.printInteger(label); p.printString("\nConeIdeal:\n"); p.printPolynomialSet(coneGroebnerBasis); p.printString("\nFullIdeal:\n"); p.printPolynomialSet(idealGroebnerBasis); p.printString("Marked facets:\n"); p.printPolynomialSetList(markedFacets); p.printString("}ConeOrbit\n"); } }; class ConeOrbitContainer { typedef list ConeOrbitList; ConeOrbitList l; public: void push_back(const ConeOrbit &orbit) { l.push_back(orbit); } bool empty() { return l.empty(); } ConeOrbit &front() { return *l.begin(); } int size() { return l.size(); } void pop_front() { l.pop_front(); } void print(AsciiPrinter &p) { p.printString("OrbitList{\n"); for(ConeOrbitList::const_iterator i=l.begin();i!=l.end();i++) { i->print(p); // p.printPolynomialSet(i->coneGroebnerBasis); //p.printNewLine(); } p.printString("}OrbitList\n"); } bool containsAndMark(PolynomialSet const &coneGroebnerBasis, PolynomialSet const &facetIdeal, int *label, IntegerVector *labelPermutation) { // fprintf(Stderr,"listlength:%i",l.size()); // int I=0; // for(ConeOrbitList::const_iterator i=l.begin();i!=l.end();i++) // { // fprintf(Stderr,"%i",I++); // } for(ConeOrbitList::iterator i=l.begin();i!=l.end();i++) { /* fprintf(Stderr,"Comparing:\n"); AsciiPrinter(Stderr).printPolynomialSet(coneGroebnerBasis); AsciiPrinter(Stderr).printPolynomialSet(i->coneGroebnerBasis); */ if(i->containsAndMark(coneGroebnerBasis,facetIdeal,labelPermutation)) // if(areIdealsEqual(coneGroebnerBasis,i->coneGroebnerBasis))// this could be slow! { *label=i->label; return true; } // if(i->coneGroebnerBasis==coneGroebnerBasis)return true; } /* fprintf(Stderr,"________________NOT IN LIST:\n"); AsciiPrinter(Stderr).printPolynomialSet(coneGroebnerBasis); */ return false; } }; BergmanFan bergman(PolynomialSet const &coneGroebnerBasis1, PolynomialSet const &idealGroebnerBasis1, SymmetryGroup const *symmetryGroup) { PolynomialRing theRing=coneGroebnerBasis1.getRing(); bool useFanIntersection=true; bool isSimplicial=true; assert(coneGroebnerBasis1.numberOfVariablesInRing()==idealGroebnerBasis1.numberOfVariablesInRing()); int n=coneGroebnerBasis1.numberOfVariablesInRing(); SymmetryGroup localSymmetryGroup(n); if(!symmetryGroup)symmetryGroup=&localSymmetryGroup; BergmanFan ret; ret.setSymmetryGroup(*symmetryGroup); ConeOrbitContainer active; int maximalConeLabel=0; { ConeOrbit newConeOrbit(*symmetryGroup,coneGroebnerBasis1,idealGroebnerBasis1,maximalConeLabel++); log1 fprintf(Stderr,"Adding orbit of size: %i\n",newConeOrbit.orbitSize()); active.push_back(newConeOrbit); } while(!active.empty()) { log1 fprintf(Stderr,"\n-------------------------------------\n"); log1 fprintf(Stderr,"Size of active set: %i, Completed: %i\n",active.size(),ret.cones.size()); log1 fprintf(Stderr,"-------------------------------------\n"); AsciiPrinter p(Stderr); // fprintf(Stderr,"----------------Active--------------------\n"); // active.print(p); // ret.print(p); ConeOrbit ¤t=active.front(); assert(current.idealGroebnerBasis.isMarked()); assert(current.coneGroebnerBasis.isMarked()); /* fprintf(Stderr,"ConeGroebnerBasis:\n"); AsciiPrinter(Stderr).printPolynomialSet(current.coneGroebnerBasis); fprintf(Stderr,"\n"); fprintf(Stderr,"IdealGroebnerBasis:\n"); AsciiPrinter(Stderr).printPolynomialSet(current.idealGroebnerBasis); fprintf(Stderr,"\n"); */ IntegerVectorList equalities=wallInequalities(current.coneGroebnerBasis); /*fprintf(Stderr,"Perp:\n"); AsciiPrinter(Stderr).printVectorList(facePerp); AsciiPrinter(Stderr).printPolynomialSet(current.idealGroebnerBasis); */ IntegerVectorList normals=wallFlipableNormals(current.idealGroebnerBasis,false); /*fprintf(Stderr,"Normals:\n"); AsciiPrinter(Stderr).printVectorList(normals); */ { PolyhedralCone p(normals,equalities); p.findFacets(); isSimplicial&=p.isSimplicial(); } removeRedundantRows(&normals,&equalities,true);//IS THIS RIGHT? IntegerVectorList facePerp=equalities; int numberOfNormals=normals.size(); int numberOfEqualities=equalities.size(); IntegerVectorList inequalities=equalities; inequalities.splice(inequalities.begin(),normals,normals.begin(),normals.end()); IntegerVector equalitySet(inequalities.size()); for(int i=0;iidealGroebnerBasis.isMarked()); int label=-1; IntegerVector labelPermutation; if(!active.containsAndMark(i->coneGroebnerBasis,initialIdeal,&label,&labelPermutation)) { if(!ret.contains(i->coneGroebnerBasis)) { /*fprintf(Stderr,"Lifting...\n"); AsciiPrinter(Stderr).printPolynomialSet(i->idealGroebnerBasis); */ PolynomialSet g2(theRing); for(PolynomialSet::const_iterator j=i->idealGroebnerBasis.begin();j!=i->idealGroebnerBasis.end();j++) g2.push_back(divisionLift(*j, initialIdeal, current.idealGroebnerBasis, LexicographicTermOrder())); //fprintf(Stderr,"Done lifting.\n"); assert(g2.isMarked()); //fprintf(Stderr,"Autoreducing...\n"); //AsciiPrinter(Stderr).printPolynomialSet(g2); autoReduce(&g2,LexicographicTermOrder()); //fprintf(Stderr,"Done autoreducing.\n"); // fprintf(Stderr,"Inserting:\n"); // AsciiPrinter(Stderr).printPolynomialSet(i->coneGroebnerBasis); // AsciiPrinter(Stderr).printPolynomialSet(g2); label=maximalConeLabel++; labelPermutation=SymmetryGroup::identity(n); ConeOrbit newConeOrbit(*symmetryGroup,i->coneGroebnerBasis,g2,label); log1 fprintf(Stderr,"Adding orbit of size: %i\n",newConeOrbit.orbitSize()); newConeOrbit.markFacet(initialIdeal); active.push_back(newConeOrbit); } } ret.codimensionOneCones.back().incidenceList.push_back(label); ret.codimensionOneCones.back().incidencePermutationList.push_back(labelPermutation); } } else numberOfAlreadyMarkedFacets++; } } equalitySet[I]=0; i++; } log1 fprintf(Stderr,"Done processing this orbit - Number of valid facets: %i Number of already marked facets: %i\n",numberOfValidFacets,numberOfAlreadyMarkedFacets); ret.cones.push_back(BergmanFan::MaximalCone(current.coneGroebnerBasis,current.idealGroebnerBasis,current.label,numberOfValidFacets)); active.pop_front(); } ret.setSimplicial(isSimplicial); return ret; } //-------------------------------------- // BergmanFan //-------------------------------------- int BergmanFan::numberOfMaximalCones()const { int ret=0;; for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) ret+=staticOrbitSize(i->coneGroebnerBasis, symmetryGroup); return ret; } void BergmanFan::print(Printer &p) { int numberOfMaximalCones=0; p.printString("Printing tropical variety modulo symmetry\n"); p.printString("-----------------"); p.printNewLine(); p.printString("1. Maximal cones:\n"); p.printString("-----------------"); p.printNewLine(); for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) { p.printString("Orbit index: "); p.printInteger(i->label); p.printString("\n"); p.printString("Groebner pair:\n"); p.printPolynomialSet(i->coneGroebnerBasis); p.printPolynomialSet(i->idealGroebnerBasis); int orbitSize=(symmetryGroup.sizeOfBaseSet())?staticOrbitSize(i->coneGroebnerBasis,symmetryGroup):1; p.printString("OrbitSize:"); p.printInteger(orbitSize); p.printString("\n"); p.printString("NumberOfFacets:"); p.printInteger(i->numberOfFacets); p.printString("\n\n"); numberOfMaximalCones+=orbitSize; /* { IntegerVectorList normals=wallInequalities(i->idealGroebnerBasis); IntegerVectorList equations=wallInequalities(i->coneGroebnerBasis); PolyhedralCone c(normals,equations); c.canonicalize(); c.print(&p); } */ if(symmetryGroup.sizeOfBaseSet()) { list indices; int index=0; for(MaximalConeList::const_iterator j=cones.begin();j!=cones.end();j++,index++) if(staticInOrbit(j->coneGroebnerBasis,i->coneGroebnerBasis,symmetryGroup))indices.push_back(index); if(indices.size()>1) { fprintf(Stderr,"Conflicting orbits!!!!:"); for(list::const_iterator j=indices.begin();j!=indices.end();j++) fprintf(Stderr," %i ",*j); fprintf(Stderr,"\n"); } } } p.printString("-----------------------"); p.printNewLine(); p.printString("2. Codimension 1 cones:\n"); p.printString("-----------------------"); p.printNewLine(); for(CodimensionOneConeList::const_iterator i=codimensionOneCones.begin();i!=codimensionOneCones.end();i++) { //p.printString("----------------------"); // p.printNewLine(); p.printString("Groebner basis of initial ideal:\n"); p.printPolynomialSet(i->idealGroebnerBasis); // p.printNewLine(); p.printString("Adjacent maximal cones (orbit index, permutation):\n"); p.printString("("); IntegerVectorList::const_iterator J=i->incidencePermutationList.begin(); for(list::const_iterator j=i->incidenceList.begin();j!=i->incidenceList.end() && J!=i->incidencePermutationList.end();j++,J++) { if(j!=i->incidenceList.begin())p.printString(",\n"); p.printString("("); p.printInteger(*j); p.printString(", "); p.printVector(*J); p.printString(")"); } p.printString(")\n"); { int index=*(i->incidenceList.begin()); MaximalConeList::const_iterator j=cones.begin(); while(index>0){index--;j++;} // IntegerVectorList normals=wallInequalities(SymmetryGroup::permutePolynomialSet(j->idealGroebnerBasis,*(i->incidencePermutationList.begin()))); /* IntegerVectorList normals=wallInequalities(SymmetryGroup::permutePolynomialSet(j->idealGroebnerBasis,SymmetryGroup::inverse(*(i->incidencePermutationList.begin())))); IntegerVectorList equations=wallInequalities(i->idealGroebnerBasis); PolyhedralCone c(normals,equations); c.canonicalize(); c.print(&p); */ /* p.printString("-----------"); p.printNewLine(); PolyhedralFan F=PolyhedralFan::facetsOfCone(c); F.print(&p); p.printString("-----------"); p.printNewLine(); */ //p.printString("----------------------"); p.printNewLine(); } } p.printString("Done printing tropical variety - #maxcones="); p.printInteger(numberOfMaximalCones); p.printString(" ("); p.printInteger(cones.size()); p.printString(") #codim1cones= ? ("); p.printInteger(codimensionOneCones.size()); p.printString(")"); p.printNewLine(); } bool BergmanFan::contains(PolynomialSet const &g) { for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) { if(areIdealsEqual(g,i->coneGroebnerBasis)) { return true; } } return false; } void BergmanFan::setSymmetryGroup(SymmetryGroup const &s) { symmetryGroup=s; } PolyhedralFan BergmanFan::toPolyhedralFan()const { assert(!cones.empty()); int n=cones.begin()->idealGroebnerBasis.numberOfVariablesInRing(); PolyhedralFan ret(n); for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) { PolyhedralCone c1(wallInequalities(i->idealGroebnerBasis),wallInequalities(i->coneGroebnerBasis)); log1 fprintf(Stderr,"Cononicalising...\n"); c1.canonicalize(); log1 fprintf(Stderr,"... done canonicalising...\n"); // fprintf(Stderr,"a\n"); // for(SymmetryGroup::ElementContainer::const_iterator j=symmetryGroup.elements.begin();j!=symmetryGroup.elements.end();j++) // { /* IntegerVectorList normals=wallInequalities(SymmetryGroup::permutePolynomialSet(i->idealGroebnerBasis,*j)); IntegerVectorList equations=wallInequalities(SymmetryGroup::permutePolynomialSet(i->coneGroebnerBasis,*j)); PolyhedralCone c(normals,equations); */ // PolyhedralCone c=c1.permuted(*j); // c.canonicalize(); c1.setMultiplicity(i->multiplicity); ret.insert(c1); // } } return ret; } void BergmanFan::setSimplicial(bool b) { simplicial=b; } bool BergmanFan::isSimplicial()const { return simplicial; } void BergmanFan::computeMultiplicities() { for(MaximalConeList::iterator i=cones.begin();i!=cones.end();i++) i->multiplicity=multiplicity(i->coneGroebnerBasis); //MULTIPLICITY TEST // AsciiPrinter(Stderr).printPolynomialSet(current.coneGroebnerBasis); // fprintf(Stderr,"MULTIPLICITY :%i\n",multiplicity(current.coneGroebnerBasis)); } gfan0.6.2/src/singular.cpp0000644000175000017500000001252313122232611015002 0ustar andersanders#include "singularconversion.h" #include "polynomialring.h" #include "polynomial.h" #include "field_rationals.h" #include "buchberger.h" #include "division.h" #include "printer.h" #include "log.h" #include void singularBuchberger(PolynomialSet *g, TermOrder const &termOrder) { ring R=singularRing(g->getRing()); ideal i=singularPolynomialSet(*g); // ideal j=kStd(i,NULL,testHomog,NULL); // test|=(Sy_bit(OPT_REDSB)|Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_INTSTRATEGY)); test|=(Sy_bit(OPT_REDSB)|Sy_bit(OPT_REDTAIL)); ideal j=kStd(i,NULL,testHomog,NULL); //idShow(j); idDelete(&i); PolynomialSet ret=fromSingularIdeal(g->getRing(),j,R); idDelete(&j); freeSingularRing(R); *g=ret; // return ret; } /**************************************************************************************************************************/ #include "groebnerengine.h" static ring mySingularRingDegRevLex(PolynomialRing const &r, IntegerVector const &weight) { // FieldRationalsImplementation *q=dynamic_castr.getField().implementingObject; ring ret=(ring)omAlloc0(sizeof(sip_sring)); if(r.getField().isRationals()) { ret->ch=0; } else { assert(0); } ret->N=r.getNumberOfVariables(); ret->names=(char**) omAlloc(ret->N*sizeof(char*)); for(int i=0;iN;i++) ret->names[i]=omStrDup(r.getVariableName(i).c_str()); ret->order=(int*)omAlloc0(3*sizeof(int)); ret->block0=(int*)omAlloc0(3*sizeof(int)); ret->block1=(int*)omAlloc0(3*sizeof(int)); ret->order[0]=ringorder_wp;//degree revlex // ret->order[0]=ringorder_Wp;//degree lex ret->block0[0]=1;ret->block1[0]=ret->N; ret->order[1]=ringorder_C; ret->OrdSgn=1; // global order ret->wvhdl=(int**)omAlloc0(3*sizeof(int*)); ret->wvhdl[0]=(int*)omAlloc(ret->N*sizeof(int)); { IntegerVector weight2=weight+(1-weight.min())*IntegerVector::allOnes(weight.size()); debug<<"WEIGHT FOR SINGULAR"<N;i++) ret->wvhdl[0][i]=weight2[i];//FIXMEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE } rComplete(ret); ret->options|=(Sy_bit(OPT_REDSB)|Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_INTSTRATEGY)|Sy_bit(OPT_REDTHROUGH)); cerr<<"ringoptions"<options)<<"\n"; // cerr<<"test"< (&termOrder)) { const WeightReverseLexicographicTermOrder *T=dynamic_cast (&termOrder); ring R=mySingularRingDegRevLex(idealGenerators.getRing(),T->getWeight()); ideal i=singularPolynomialSet(idealGenerators); test|=(Sy_bit(OPT_REDSB)|Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_INTSTRATEGY)); test|=(Sy_bit(OPT_REDTHROUGH)); log2 cerr<<"calling singular\n"; // debug<<"test"< #include "halfopencone.h" #include "regularsubdivision.h" #include "log.h" IntegerMatrix cayleyConfiguration(PolynomialSet const &g) { int ambientDim=g.getRing().getNumberOfVariables(); int numberOfPolytopes=g.size(); IntegerVectorList L; int I=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++,I++) { for(TermMap::const_iterator j=i->terms.begin();j!=i->terms.end();j++) { L.push_back(concatenation(IntegerVector::standardVector(numberOfPolytopes,I),j->first.exponent)); } } return rowsToIntegerMatrix(L); } IntegerMatrix cayleyConfiguration(list const &g, int d) { int ambientDim=d; int numberOfPolytopes=g.size(); IntegerVectorList L; int I=0; for(list::const_iterator i=g.begin();i!=g.end();i++,I++) { for(IntegerVectorList::const_iterator j=i->begin();j!=i->end();j++) { L.push_back(concatenation(IntegerVector::standardVector(numberOfPolytopes,I),*j)); } } return rowsToIntegerMatrix(L); } set > mixedCells(vector > const&intervals/*PolynomialSet const &g*/, Triangulation2 const &t, IntegerMatrix const &A, IntegerVector const &w) { set > ret; #if 1 map > equivalenceClasses; for(set::const_iterator i=t.bases.begin();i!=t.bases.end();i++) { IntegerVectorList M; IntegerVector temp(1); for(int j=0;jsize();j++) {temp[0]=w[(*i)[j]];M.push_back(concatenation(A[(*i)[j]],temp));} IntegerMatrix M2=rowsToIntegerMatrix(M); IntegerVector normal=vectorInKernel(M2); for(int j=0;jsize();j++)equivalenceClasses[normal].insert((*i)[j]); } for(map >::const_iterator i=equivalenceClasses.begin();i!=equivalenceClasses.end();i++) #else set > temp=regularSubdivision(A,w); for(set >::const_iterator i=temp.begin();i!=temp.end();i++) #endif { set allPoints; for(int j=0;jfirst,concatenation(A[j],temp))==0)allPoints.insert(j); } // for(set::const_iterator j=i->second.begin();j!=i->second.end();j++)debug<<*j<<","; // debug<<"\n"; bool OK=true; /* int first=0; for(PolynomialSet::const_iterator j=g.begin();j!=g.end();j++) { int last=first+j->numberOfTerms(); */ for(int j=0;jsecond.count(k))numberFound++; for(int k=first;ksecond); ret.insert(allPoints); } } return ret; } vector > polynomialSetToIntervals(PolynomialSet const &g) { vector > intervals; int index=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { intervals.push_back(pair(index,index+i->numberOfTerms())); index+=i->numberOfTerms(); } return intervals; } vector > tupleToIntervals(IntegerVectorListList const &tuple) { vector > intervals; int index=0; for(IntegerVectorListList::const_iterator i=tuple.begin();i!=tuple.end();i++) { intervals.push_back(pair(index,index+i->size())); index+=i->size(); } return intervals; } set > mixedCells(PolynomialSet const &g, Triangulation2 const &t, IntegerMatrix const &A, IntegerVector const &w) { return mixedCells(polynomialSetToIntervals(g),t,A,w); } set > mixedCells(IntegerVectorListList const &tuple, Triangulation2 const &t, IntegerMatrix const &A, IntegerVector const &w) { return mixedCells(tupleToIntervals(tuple),t,A,w); } static void printCone(PolyhedralCone c) { c.canonicalize(); PolyhedralFan f(c.ambientDimension()); f.insert(c); f.printWithIndices(&debug); } // contributed by Josephine Yu int weightVectorToMultiplicity(/*PolynomialSet const &g,*/IntegerVectorListList const &tuple, IntegerMatrix const &theConfiguration, Triangulation2 const &theTriangulation, IntegerVector const &omega) { int mult = 0; set > theMixedCells = mixedCells(tuple,theTriangulation,theConfiguration,omega); for(set >::const_iterator i=theMixedCells.begin();i!=theMixedCells.end();i++) { // should assert that each set contains exactly two elements //pick out submatrix whose ROWS are the vertices of the Cayley configuration in the mixed cell IntegerVectorList submatrix; for(set::const_iterator j=i->begin();j!=i->end();j++){submatrix.push_back(theConfiguration[*j]);} IntegerMatrix newConfiguration=rowsToIntegerMatrix(submatrix,theConfiguration.getWidth()); FieldMatrix hermiteForm=integerMatrixToFieldMatrix(newConfiguration, Q); toInteger(hermiteForm[0][0])+toInteger(hermiteForm[1][1]); hermiteForm.reduce(false,true); int latticeIndex =1; for(int k=0; k < hermiteForm.getWidth(); k++) { latticeIndex *= toInteger(hermiteForm[k][k]);} mult += abs(latticeIndex); } return mult; } static int findD(IntegerVectorListList const &tuple) { int d=0; for(IntegerVectorListList::const_iterator i=tuple.begin();i!=tuple.end();i++) for(IntegerVectorList::const_iterator j=i->begin();j!=i->end();j++) {d=j->size();goto leave;} leave: for(IntegerVectorListList::const_iterator i=tuple.begin();i!=tuple.end();i++) for(IntegerVectorList::const_iterator j=i->begin();j!=i->end();j++) {assert(d==j->size());} return d; } ResultantFanTraverser::ResultantFanTraverser(/*PolynomialSet const &g_,*/ IntegerVectorListList const &tuple_, IntegerMatrix const &theConfiguration_): ConeTraverser(theConfiguration_.getHeight()), theTriangulation(theConfiguration_.transposed()), theCone(0), // g(g_), tuple(tuple_), theConfiguration(theConfiguration_) { assert(theTriangulation.getN()==theConfiguration_.getHeight()); assert(::rank(theConfiguration)==theConfiguration.getWidth()); n=theTriangulation.getN(); IntegerVector omega; int codimension=coDimensionOfResultantVariety(tuple,findD(tuple),&omega); // int codimension=coDimensionOfResultantVariety(g,&omega); d=n-codimension; IntegerVectorList M; M.push_back(omega); for(int i=0;i > subsetToIntervals(PolynomialSet const &g, set const &subset) {//improve complexity vector > intervals; int index=0; int indexOriginal=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { int nt=0; for(int j=indexOriginal;jnumberOfTerms();j++)nt+=subset.count(j); intervals.push_back(pair(index,index+nt)); index+=nt; indexOriginal+=i->numberOfTerms(); } return intervals; } vector > subsetToIntervals(IntegerVectorListList const &tuple, set const &subset) {//improve complexity vector > intervals; int index=0; int indexOriginal=0; for(IntegerVectorListList::const_iterator i=tuple.begin();i!=tuple.end();i++) { int nt=0; for(int j=indexOriginal;jsize();j++)nt+=subset.count(j); intervals.push_back(pair(index,index+nt)); index+=nt; indexOriginal+=i->size(); } return intervals; } IntegerVectorList quickLink(IntegerMatrix const &m, set const &cell, vector > const &intervals, IntegerVectorList const &linealitySpace) { int n=m.getHeight(); IntegerVectorList ret; set zeroHeight; set otherHeight; for(vector >::const_iterator i=intervals.begin();i!=intervals.end();i++) { set inInterval; for(set::const_iterator j=cell.begin();j!=cell.end();j++) if(*j>=i->first && *jsecond)inInterval.insert(*j); if(inInterval.size()==2) for(set::const_iterator j=inInterval.begin();j!=inInterval.end();j++)zeroHeight.insert(*j); else for(set::const_iterator j=inInterval.begin();j!=inInterval.end();j++)otherHeight.insert(*j); } assert(otherHeight.size()==3); for(set::const_iterator i=otherHeight.begin();i!=otherHeight.end();i++) { /* IntegerVector v(n)=IntegerVector::all(n); for(set::const_iterator j=otherHeight.begin();j!=otherHeight.end();j++) if(j!=i) v[*j]=1; */ IntegerVectorList rays; // for(int j=0;j ret; set > subproblems=mixedCells(tuple,theTriangulation,theConfiguration,ridgeVector);//HERE assert(!subproblems.empty()); for(set >::const_iterator i=subproblems.begin();i!=subproblems.end();i++) { //pick out submatrix IntegerVectorList submatrix; for(set::const_iterator j=i->begin();j!=i->end();j++)submatrix.push_back(theConfiguration[*j]); IntegerMatrix newConfiguration=rowsToIntegerMatrix(submatrix,theConfiguration.getWidth()).transposed(); // debug< > intervals=subsetToIntervals(/*g*/tuple,*i); //compute its secondary fan Triangulation2::makeConfigurationFullDimensional(newConfiguration); if(newConfiguration.getHeight()==newConfiguration.getWidth()-(n-d)) { //debug<<"SPECIAL\n"; //We are in the case where the lineality space of the secondary fan of the subproblem has //codimension equal to that of the resultant variety. In this case the contribution of the //subproblem is two rays, which IntegerMatrix M(theConfiguration.getHeight(),theConfiguration.getWidth()); for(set::const_iterator j=i->begin();j!=i->end();j++)M[*j]=theConfiguration[*j]; IntegerVectorList temp=M.transposed().getRows(); for(int j=0;jcount(j))temp.push_back(IntegerVector::standardVector(n,j)); PolyhedralCone span=PolyhedralCone::givenByRays(IntegerVectorList(),temp,n); // PolyhedralCone span=PolyhedralCone(IntegerVectorList(),M.transposed().getRows(),theCone.ambientDimension()); // PolyhedralCone span=PolyhedralCone(IntegerVectorList(),theCone.getEquations(),theCone.ambientDimension()); PolyhedralCone C=theCone.link(ridgeVector).linealitySpace().dualCone(); PolyhedralCone D=intersection(span,C); assert(D.dimension()==1); IntegerVector v=normalized(D.generatorsOfLinealitySpace().front()); ret.insert(v); ret.insert(-v); continue; } // debug<<"NONSPECIAL\n"; #if 0 // debug<<"NONSPECIAL\n"; // debug< > cells2=mixedCells(intervals,T2,newConfiguration,*j); //if so lift the vector back into full space and add to ret if(!cells2.empty())toBeLifted.push_back(*j); } #else // debug<<"To be lifted:"< temp;for(int k=0;ksize();k++)temp.insert(k); IntegerVectorList toBeLifted=quickLink(newConfiguration.transposed(),temp,subsetToIntervals(/*g*/tuple,*i),newConfiguration.getRows()); #endif for(IntegerVectorList::const_iterator j=toBeLifted.begin();j!=toBeLifted.end();j++) { IntegerVector lift(n); int K=0; for(set::const_iterator k=i->begin();k!=i->end();k++,K++)lift[*k]=(*j)[K]; ret.insert(lift); // debug<::const_iterator i=ret.begin();i!=ret.end();i++)ret2.push_back(*i); // debug<<"LINK AT "< const &cones; map > adjacency; PolyhedralCone theCone; PolyhedralCone theRestrictingCone; // int n,d; void updatePolyhedralCone(); public: IntegerVector currentNormal; SphereTraverser(vector const &cones_, map > const &ajacency_, IntegerVector const &startCone, IntegerVector const &normal); virtual void changeCone(IntegerVector const &ridgeVector, IntegerVector const &rayVector); virtual IntegerVectorList link(IntegerVector const &ridgeVector); PolyhedralCone & refToPolyhedralCone(); }; #endif gfan0.6.2/src/app_lpsolve.cpp0000644000175000017500000000233513122232611015502 0ustar andersanders#include "vektor.h" #include "printer.h" #include "parser.h" #include "gfanapplication.h" #include "fieldlp.h" class LPSolveApplication : public GFanApplication { public: bool includeInDefaultInstallation() { return false; } LPSolveApplication() { registerOptions(); } const char *name() { return "_lpsolve"; } int main() { FileParser P(Stdin); FieldMatrix A=integerMatrixToFieldMatrix(rowsToIntegerMatrix(P.parseIntegerVectorList()),Q); IntegerVector b0=P.parseIntegerVector(); FieldVector b=integerVectorToFieldVector(b0,Q); FieldLP lp(A,b); FieldVector w=integerVectorToFieldVector(P.parseIntegerVector(),Q); lp.setObjectiveFunction(w); /* set B; for(int i=0;i<3;i++)B.insert(2*i+1); lp.setCurrentBasis(B); */ if(!lp.findFeasibleBasis()) { fprintf(Stderr,"LP is infeasible\n"); } else { int status; do { AsciiPrinter Q(Stdout); lp.print(Q); status=lp.step(); } while(status==1); fprintf(Stderr,status?"LP is unbounded.\n":"Optimal solution found.\n"); } return 0; } const char *helpText() { return "Test program for FieldLP.\n"; } }; static LPSolveApplication theApplication; gfan0.6.2/src/tropicaltraverse.h0000644000175000017500000000073113122232611016212 0ustar andersanders#ifndef TROPICALTRAVERSE_H_INCLUDED #define TROPICALTRAVERSE_H_INCLUDED #include "bergman.h" /** Represents a tropical variety up to symmetry. New strategy. */ PolyhedralFan tropicalTraverse(PolynomialSet coneGroebnerBasis, PolynomialSet idealGroebnerBasis, SymmetryGroup const *symmetryGroup=0); void coneChangeDebugger(PolynomialSet coneGroebnerBasis, PolynomialSet idealGroebnerBasis, IntegerVectorList const &ridges, IntegerVectorList const &rays); #endif gfan0.6.2/src/app_genericlinearchange.cpp0000644000175000017500000000514513122232611017775 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "buchberger.h" #include "wallideal.h" #include "termorder.h" #include "gfanapplication.h" #include "tropical2.h" class GenericLinearChangeApplication : public GFanApplication { public: const char *helpText() { return "This program takes a list of polynomials and performs a generic linear change of coordinates by introducing nxn new variables.\n"; } GenericLinearChangeApplication() { registerOptions(); } const char *name() { return "_genericlinearchange"; } Polynomial substitueMonomial(Monomial const &m, vector const &substitutionTable, PolynomialRing const &R2) { IntegerVector v=m.exponent; Polynomial ret=R2.one(); for(int i=0;i const &substitutionTable, PolynomialRing const &R2) { Polynomial ret(R2); for(TermMap::const_iterator i=f.terms.begin();i!=f.terms.end();i++) { ret+=R2.polynomialFromField(i->second)*substitueMonomial(i->first,substitutionTable,R2); } return ret; } int main() { FileParser P(Stdin); PolynomialSet g=P.parsePolynomialSetWithRing(); PolynomialRing R1=g.getRing(); int n=g.getRing().getNumberOfVariables(); vector names=matrixVariableNames("g",n,n); for(int i=0;i substitutionTable; for(int i=0;i #include #include #include #if USESHAREDPTR #include #endif #include /* Always include cstdio before gmp.h.*/ #include //SHOULD BE REMOVED /** A FieldElement is an element of a Field in the algebraic sense. A FieldElement always knows its associated Field to which it belongs. We may perform arithmetic operations on a FieldElement and a FieldElement is passed around by value. Thus in C++ it makes no sense to derive classes from the FieldElement class. The actual data is contained in an object of the class FieldElementImplementation and the FieldElement serves as a smart pointer with reference counting to this implementation. */ class FieldElement { public: #if USESHAREDPTR std::shared_ptr implementingObject; #else class FieldElementImplementation *implementingObject; #endif FieldElement(class FieldElementImplementation *implementingObject_); void makeUnique(); public: class FieldImplementation *getField()const; /* Returns a pointer to the FieldImplementation which does NOT get its refCount increased. The pointer should immediately be cast to a Field object, there by incresing the refCount. This allows code like this void test(FieldElement a){Field b=a.getField();...}. Would it also work for this (a+a).getField(); or could the ref count get 0 before it is increased? */ /* * The following is only supported for Z/pZ */ int getIntegerRepresentation()const; /* * The following two are only supported for rationals. */ mpq_t const *getGmpRationalTemporaryPointer()const; double floatingPointApproximation()const; bool isInteger()const; virtual FieldElement multiplierGivingInteger()const; #if !USESHAREDPTR void setImplementingObject(FieldElementImplementation *implementingObject_){implementingObject=implementingObject_;assert(0);} #endif FieldElement one() const; bool isZero()const; virtual bool isOne()const; friend FieldElement operator+(const FieldElement &a,const FieldElement &b); friend FieldElement operator-(const FieldElement &a,const FieldElement &b); friend FieldElement operator-(const FieldElement &b); FieldElement inverse()const; int sign()const; // Only allowed for ordered field. Asserts otherwise. int pAdicValuation(int p)const; // Only allowed for the field Q. FieldElement pAdicRemainder(class Field const &ZModPZ)const; // Only allowed for the field Q. FieldElement modularRepresentative(class Field const &ZModPZ)const; // Only allowed for the field Q and only for integers in that field. int integerRepresentative()const; // Only allowed for Z/pZ std::string toString(bool writeIfOne=true, bool alwaysWriteSign=false ,bool latexMode=false) const; void operator*=(const FieldElement &a); void operator+=(const FieldElement &a); /** Adds a*b to the value of the object. */ void madd(const FieldElement &a, const FieldElement &b); friend FieldElement operator*(const FieldElement &a,const FieldElement &b); // Constructors: FieldElement(class Field const &f);//Initializes to zero FieldElement() // This constructor causes a lot of trouble { // Having a legal FieldElement without an implementing object #if USESHAREDPTR fprintf(stderr,"TROUBLE\n"); #else implementingObject=0; // we must check for each assignment (copy constructor/assignment operator) #endif } // if the pointer is zero. - And some operation will be illegal on // on this element ( one(),..... ) FieldElement(const FieldElement &a); FieldElement& operator=(const FieldElement& a); virtual ~FieldElement(); }; /** The Field class describes an object which has as its value a field (in the algebraic sense). The value/object can be copied around as a value. The Field object serves as a smart pointer with reference counting to a FieldImplementation which is hidden for the user of the Field class. In C++ it makes no sense to derive classes from this class because the object must be passable by value. */ class Field { friend class FieldElement; // protected: public: #if USESHAREDPTR std::shared_ptr implementingObject; #else class FieldImplementation *implementingObject; #endif public: FieldElementImplementation *zHomomorphismImplementation(int n)const; /** @return The image of the integer n under the unique ring homomorphism from the integers Z to the Field taking 1 to the multiplicative neutral element. */ FieldElement zHomomorphism(int n)const; FieldElement random()const; int getCharacteristic()const; bool isRationals()const; const char *name(); std::string toString()const; Field(Field const &a);//copy constructor //explicit Field(FieldImplementation *implObj);//constructor Field& operator=(const Field& a);//assignment ~Field();//destructor }; class FieldElementImplementation { static int numberOfLivingFieldElementImplementations; class FieldImplementation &theFieldImplementation; /* Ideally FieldElement would contain a Field object. However, since methods of a Field should be able to return FieldElements this seems impossible because of the stupid one-pass convention of C++. Instead FieldElement contains a FieldImplementation pointer and FieldElement must thus do the reference counting for this pointer on its own ???*/ public: class FieldImplementation *getField()const; // class Field getField2()const; // class FieldImplementation *getFieldImplementation()const; // class Field getField()const; static int getNumberOfLivingFieldElementImplementations(){return numberOfLivingFieldElementImplementations;}; #if !USESHAREDPTR int refCount; #endif FieldElementImplementation(FieldImplementation &a);//ref count = 1?? virtual ~FieldElementImplementation(); virtual FieldElementImplementation *one() const=0; virtual FieldElementImplementation *copy()const=0; virtual bool isZero()const=0; virtual FieldElementImplementation *sum(const FieldElementImplementation &b)const=0; virtual FieldElementImplementation *difference(const FieldElementImplementation &b)const=0; virtual FieldElementImplementation *negation()const=0; virtual FieldElementImplementation *inverse()const=0; virtual std::string toString(bool writeIfOne=true, bool alwaysWriteSign=false, bool latexMode=false) const=0; virtual void operator*=(const FieldElementImplementation &a)=0; virtual void operator+=(const FieldElementImplementation &a)=0; virtual void madd(const FieldElementImplementation &a,const FieldElementImplementation &b)=0; virtual int sign()const { assert(0); return 0; } virtual int pAdicValuation(int p)const { assert(0); return 0; } virtual FieldElement pAdicRemainder(Field const &ZModPZ)const { assert(0); return pAdicRemainder(ZModPZ); } virtual FieldElement modularRepresentative(Field const &ZModPZ)const { assert(0); return modularRepresentative(ZModPZ); } /* virtual int integerRepresentative()const { assert(0); return 0; }*/ virtual mpq_t const *getGmpRationalTemporaryPointer()const { fprintf(stderr,"*this object is not implemented using GMP\n"); assert(0); return 0; } virtual int getIntegerRepresentation()const { fprintf(stderr,"*this is not in Z/pZ.\n"); assert(0); } virtual bool isInteger()const { assert(0); return false; } virtual FieldElementImplementation *multiplierGivingInteger()const { assert(0); return multiplierGivingInteger(); } Field& operator=(const Field& a) { assert(0); }//assignment }; extern int FieldElementRationalsLiving; class FieldImplementation { public: #if !USESHAREDPTR int refCount; #endif // static class Field *currentField; // ?? // static void checkInitialized(); // ?? protected: // class Field *next; // static class Field *list; static int numberOfLivingFieldImplementations; public: virtual FieldElementImplementation *zHomomorphismImplementation(int n)=0;/* Creates FieldElementImplementation object with refcount1 */ public: static int getNumberOfLivingFieldImplementations(){return numberOfLivingFieldImplementations;}; #if USESHAREDPTR FieldImplementation()//:refCount(0) #else FieldImplementation():refCount(0) #endif { // fprintf(stderr,"FieldImplementationCreation\n"); numberOfLivingFieldImplementations++; } virtual ~FieldImplementation() { // fprintf(stderr,"FieldImplementationDestruction\n"); numberOfLivingFieldImplementations--; } virtual bool isRationals()const { return false; } // static Field *find(const char *name); // static void printList(FILE *f); virtual FieldElement zHomomorphism(int n)=0; virtual FieldElement random() { assert(0); } virtual int getCharacteristic()const=0; virtual const char *name()=0; virtual std::string toString()const=0; // static void setField(Field *f); // Do we really want these // static FieldElement staticZHomomorphism(int n); // two procedures? }; #endif gfan0.6.2/src/vektor.h0000644000175000017500000003055213122232611014137 0ustar andersanders#ifndef VEKTOR_H_INCLUDED #define VEKTOR_H_INCLUDED #include #include #include #include #include #include using namespace std; typedef signed long int int64; void outOfRange(int i, int n); /* * TODO: in the process of making gfan a library to be used by POLYMAKE etc. * we need to: * - make an integer class with overflow checking. At every addition the difference * between bit 31 and 32 is or'ed to a register, which can be checked later. * - group the current asserts into categories. Some will assert in the usual way. * Others will throw exceptions. In the library version all throw exceptions. */ template class Vektor{ public: vector v; int support; public: //-------------- // Constructors //-------------- Vektor(const Vektor &a):v(a.v),support(a.support){ } Vektor(int n):v(n){ assert(n>=0); support=0; for(int i=0;i=0); support=0;for(int i=0;i explicit Vektor(const Vektor& c) :v(c.size()) { for(int i=0;i=0 && n=0 && nb.size())return false; for(int i=0;i::const_iterator j=q.v.begin(); for(typename std::vector::const_iterator i=p.v.begin();i!=p.v.end();i++,j++)s+=((int64)*i)*((int64)*j); return s;} inline friend void dotLong4(const Vektor& p, const Vektor& q,const Vektor& a, const Vektor& b, int64 &pa, int64 &pb, int64 &qa, int64 &qb) { assert(p.v.size()==q.v.size()); assert(a.v.size()==b.v.size()); assert(a.v.size()==q.v.size()); int64 PA=0; int64 PB=0; int64 QA=0; int64 QB=0; typename vector::const_iterator qi=q.v.begin(); typename vector::const_iterator ai=a.v.begin(); typename vector::const_iterator bi=b.v.begin(); for(typename std::vector::const_iterator pi=p.v.begin();pi!=p.v.end();pi++,qi++,ai++,bi++) { PA+=((int64)*pi)*((int64)*ai); PB+=((int64)*pi)*((int64)*bi); QA+=((int64)*qi)*((int64)*ai); QB+=((int64)*qi)*((int64)*bi); } pa=PA; pb=PB; qa=QA; qb=QB; } /** * *this represents a permutation, and we let *this act on src, and assign the result to dest. * If dest does not have the right size, then the routine reallocates. */ inline void composeAssign(const Vektor& src, Vektor &dest)const { if(dest.size()!=src.size())dest=Vektor(src.size()); assert(size()==src.size()); typename std::vector::const_iterator p=v.begin(); for(typename std::vector::iterator d=dest.v.begin();d!=dest.v.end();d++,p++) *d=src.UNCHECKEDACCESS(*p); } inline void composeInverseAssign(const Vektor& src, Vektor &dest)const { if(dest.size()!=src.size())dest=Vektor(src.size()); assert(size()==src.size()); typename std::vector::const_iterator p=v.begin(); for(typename std::vector::const_iterator s=src.v.begin();s!=src.v.end();s++,p++) dest[*p]=*s; } bool operator==(const Vektor & q)const{if(size()!=q.size())return false;for(int i=0;iv[i])ret=v[i]; return ret; } typ infinityNorm()const { typ a=0; typ b=0; for(int i=0;iv[i])b=v[i]; } if(a>-b)return a; return -b; } bool infinityNormLessThan(typ k)const { bool aOK=true; bool bOK=true; for(int i=0;i-k); } return aOK&&bOK; } friend bool dependent(const Vektor& p, const Vektor& q) { /* typ pp=dot(p,p); typ qq=dot(q,q); typ pq=dot(p,q); return pq*pq==pp*qq; */ int n=p.size(); assert(n==q.size()); int i; for(i=0;iq[i])p1[i]=q[i];return p1;} friend Vektor coordinatewiseProduct(const Vektor& p, const Vektor& q){assert(p.size()==q.size());Vektor p1(q.size());for(int i=0;i0)if(q.v[i]0)&&(q[t]>0)) return false; return true; } Vektor supportVector()const { Vektor r(v.size()); for(int i=0;i=0); assert(end<=size()); assert(end>=begin); Vektor ret(end-begin); for(int i=0;i const &chosenIndices)const { Vektor ret(chosenIndices.size()); int I=0; for(list::const_iterator i=chosenIndices.begin();i!=chosenIndices.end();i++,I++)ret[I]=v[*i]; return ret; } Vektor subvectorSubsetBoolean(Vektor const &subset)const { Vektor ret(subset.sum()); int i=0; for(int j=0;j const &subset)const // Inverse of the above, except that unknown entries are set to zero. { Vektor ret(subset.size()); int i=0; for(int j=0;j const &positions) { Vektor ret(newSize); assert(positions.size()==size()); for(int i=0;i0)==true)&1); } }; typedef complex ComplexNumber; typedef Vektor ComplexVector; typedef Vektor FloatVector; typedef Vektor IntegerVector; typedef list IntegerVectorList; typedef list IntegerVectorListList; IntegerVectorList transposeIntegerVectorList(IntegerVectorList const &l); IntegerVectorList multiplyIntegerVectorList(IntegerVectorList const &A, IntegerVectorList const &B); IntegerVectorList subvectorsOfIntegerVectorList(IntegerVectorList const &l, list const &chosen); int gcdOfVector(IntegerVector const &v); void normalizedLowLevel(IntegerVector const &v, IntegerVector &dest); IntegerVector normalized(IntegerVector const &v); IntegerVector randomIntegerVector(int n, int range); /** * Removes duplicates and reorders list. */ void removeDuplicates(IntegerVectorList &l); #endif int gcdGFAN(int r, int s); gfan0.6.2/src/regularsubdivision.cpp0000644000175000017500000000446713122232611017106 0ustar andersanders#include "regularsubdivision.h" #include "polyhedralcone.h" #include "log.h" #include "polyhedralfan.h" set > regularSubdivision(IntegerMatrix const &m, IntegerVector const &w) { IntegerVectorList m2; int n=m.getWidth(); for(int i=0;i > faces; for(IntegerVectorList::const_iterator i=lowerNormals.begin();i!=lowerNormals.end();i++) { set face; //if((*i)[n]<0) //This is how it was originally if((*i)[n]>0) { int J=0; for(IntegerVectorList::const_iterator j=m2.begin();j!=m2.end();j++,J++) if(dotLong(*j,*i)==0) face.insert(J); faces.insert(face); } } return faces; } void printSetSetInt(FILE *f, set > const &faces) { fprintf(f,"{"); for(set >::const_iterator i=faces.begin();i!=faces.end();i++) { if(i!=faces.begin())fprintf(f,",\n"); fprintf(f,"{"); for(set::const_iterator j=i->begin();j!=i->end();j++) { if(j!=i->begin())fprintf(f,","); fprintf(f,"%i",*j); } fprintf(f,"}"); } fprintf(f,"}\n"); } /* PolyhedralCone secondaryCone(IntegerMatrix const &m, set > const &subdivision) { IntegerVectorList equations; IntegerVectorList inequalities; for(set >::const_iterator i=subdivision.begin();i!=subdivision.end();i++) { for(int j=0;jcontains(j)) { for(set::const_iterator k=i->begin();k!=i->end();k++) { IntegerMatrix m(m.getWidth(),m.getWidth()); int L=0; for(set::const_iterator l=i->begin();l!=i->end();l++) if(l!=k) { m[L]=*L; L++; } } } } } } */ gfan0.6.2/src/app_homogeneityspace.cpp0000644000175000017500000000231413122232611017356 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "gfanapplication.h" #include "wallideal.h" #include "polyhedralcone.h" class HomogeneitySpaceApplication : public GFanApplication { public: const char *helpText() { return "This program computes the homogeneity space of a list of polynomials - as a cone. Thus generators for the homogeneity space are found in the section LINEALITY_SPACE. If you wish the homogeneity space of an ideal you should first compute a set of homogeneous generators and call the program on these. A reduced Groebner basis will always suffice for this purpose.\n"; } HomogeneitySpaceApplication() { registerOptions(); } const char *name() { return "_homogeneityspace"; } int main() { FileParser P(Stdin); PolynomialSet g=P.parsePolynomialSetWithRing(); IntegerVectorList l=wallInequalities(g); IntegerVectorList a; PolyhedralCone c(a,l); c.canonicalize(); AsciiPrinter(Stdout).printPolyhedralCone(c); return 0; } }; static HomogeneitySpaceApplication theApplication; gfan0.6.2/src/padic.cpp0000644000175000017500000004300113122232611014231 0ustar andersanders/* * padic.cpp * * Created on: Nov 30, 2010 * Author: anders */ #define DEBUG if(0) #include "padic.h" #include "polynomial.h" #include #include "field_zmodpz.h" #include "printer.h" #include "wallideal.h" #include "log.h" using namespace std; static int64 smartDot(IntegerVector const &v, IntegerVector const &omega) { int64 ret=0; int n=v.size(); for(int i=0;isecond<<" ----- "<second.pAdicValuation(prime)<<"\n"; // return omega[0]*(i->second.pAdicValuation(prime))+dotLong(i->first.exponent,omega.subvector(1,omega.size())); return omega[0]*(i->second.pAdicValuation(prime))+smartDot(i->first.exponent,omega); } static int64 omegaDegree(Term const t, int prime, IntegerVector const &omega) { // return omega[0]*t.c.pAdicValuation(prime)+dotLong(t.m.exponent,omega.subvector(1,omega.size())); return omega[0]*t.c.pAdicValuation(prime)+smartDot(t.m.exponent,omega); } Term iteratorToTerm(TermMap::const_iterator i) { return Term(i->second,i->first); } Polynomial pAdicInitialForm(PolynomialRing const &ZModPZRing, Polynomial const &f, int prime, IntegerVector const &omega) { if(f.isZero())return ZModPZRing.zero(); Polynomial ret(ZModPZRing); int64 d=omegaDegree(f.terms.begin(),prime,omega); // debug<<"INPUT"<second.pAdicRemainder(ZModPZRing.getField()),Monomial(ZModPZRing,i->first.exponent)); } if(omegaDegree(i,prime,omega)second.pAdicRemainder(ZModPZRing.getField()),Monomial(ZModPZRing,i->first.exponent)); d=omegaDegree(i,prime,omega); } } // debug<<"OUTPUT"<bD) return true; if (bD>aD) return false; return tieBreaker(b.m.exponent,a.m.exponent); } static Term ST(Polynomial const &f, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { assert(!f.isZero()); Term ret=iteratorToTerm(f.terms.begin()); for(TermMap::const_iterator i=f.terms.begin();i!=f.terms.end();i++) { if(GReater(ret,iteratorToTerm(i),prime,omega,tieBreaker)) { ret=iteratorToTerm(i); } } return ret; } static Monomial SM(Polynomial const &f, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { assert(!f.isZero()); return ST(f,prime,omega,tieBreaker).m; } Polynomial pAdicInitialTerm(PolynomialRing const &ZModPZRing, Polynomial const &f, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { assert(!f.isZero()); Term T=ST(f,prime,omega,tieBreaker); return Polynomial(Term(T.c.pAdicRemainder(ZModPZRing.getField()),Monomial(ZModPZRing,T.m.exponent))); } PolynomialSet pAdicInitialTerms(PolynomialRing const &ZModPZRing, PolynomialSet const &g, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { PolynomialSet ret(g.getRing()); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) ret.push_back(pAdicInitialTerm(ZModPZRing,*i,prime,omega,tieBreaker)); return ret; } /*** * Omega is considered to be perturbed. */ IntegerVectorList normalPolyhedralInequalities(Polynomial const &f, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) {//first coordinate is special IntegerVectorList ret; if(!f.isZero()) { Term T=ST(f,prime,omega,tieBreaker); int Tval=T.c.pAdicValuation(prime); IntegerVector Texp=T.m.exponent; for(TermMap::const_iterator i=f.terms.begin();i!=f.terms.end();i++) { int Cval=i->second.pAdicValuation(prime); IntegerVector Cexp=i->first.exponent; IntegerVector temp(1); temp[0]=Cval-Tval; ret.push_back(concatenation(temp,Cexp-Texp)); } } return ret; } IntegerVectorList normalPolyhedralInequalities(PolynomialSet const &g, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { IntegerVectorList ret; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { IntegerVectorList ret2=normalPolyhedralInequalities(*i,prime,omega,tieBreaker); ret.splice(ret.end(),ret2); } return ret; } static int E(Polynomial const &f, Polynomial const &g) { int ret=0; for(TermMap::const_iterator i=f.terms.begin();i!=f.terms.end();i++) { if(!g.terms.count(i->first))ret++; } return ret; } //Based on Diane's draft: Polynomial longDivision(Polynomial f, PolynomialSet const &G2, int prime, IntegerVector const &omega, TermOrder const &tieBreaker, PolynomialSet &H2, Polynomial &u2) { // debug<<"DIVISION INPUT"<isZero()); } FieldZModPZ residueField(prime); PolynomialRing S=G2.getRing(); FieldElement pFieldElement=S.getField().zHomomorphismImplementation(prime); int s=G2.size(); vector G; for(PolynomialSet::const_iterator k=G2.begin();k!=G2.end();k++)G.push_back(*k); vector H(s,Polynomial(S)); Polynomial r(S); Polynomial u=S.one(); vector > HCache; vector rCache; vector uCache; Polynomial q=f; vector T=G; while(!q.isZero()) { DEBUG debug<<"looping\n"; bool doesSomeSMgDivide=false; for(int ii=0;ii0) { T.push_back(q); uCache.push_back(u); HCache.push_back(H); rCache.push_back(r); } DEBUG debug<<"----ii\n"; //iii DEBUG debug<<"iii----\n"; Term cuxu=ST(q,prime,omega,tieBreaker)/ST(g,prime,omega,tieBreaker); DEBUG debug<<"g="<< g << " ST "<< ST(g,prime,omega,tieBreaker)<<"\n"; DEBUG debug<<"qj="<< q << " ST "<< ST(q,prime,omega,tieBreaker)<<"\n"; Polynomial a=cuxu/SM(cuxu,prime,omega,tieBreaker); Polynomial b=S.one(); int aval=cuxu.c.pAdicValuation(prime); while(aval<0) { b*=pFieldElement; a*=pFieldElement; aval++; } Polynomial p=b*q-a*SM(cuxu,prime,omega,tieBreaker)*g; if(p.isZero()){DEBUG debug<<"p IS ZERO!\n";} else { DEBUG debug<<"p="<< p << " ST "<< ST(p,prime,omega,tieBreaker)<<"\n"; DEBUG debug<<"bq="<< b*q << " ST "<< ST(b*q,prime,omega,tieBreaker)<<"\n"; assert(GReater(ST(p,prime,omega,tieBreaker),ST(b*q,prime,omega,tieBreaker),prime,omega,tieBreaker)); } DEBUG debug<<"----iii\n"; //iv DEBUG debug<<"iv----\n"; for(int iprime=0;iprime::const_iterator k=H.begin();k!=H.end();k++)H2.push_back(*k); u2=u; //Check correctness of result { Polynomial sum=u*f-r; PolynomialSet::const_iterator i=H2.begin(); for(PolynomialSet::const_iterator j=G2.begin();j!=G2.end();i++,j++)sum-=(*i)*(*j); assert(sum.isZero()); {for(PolynomialSet::const_iterator i=H2.begin();i!=H2.end();i++)assert(i->isHomogeneous());} assert(r.isHomogeneous()); if(!(u*f).isZero()) { if(!r.isZero()) assert(!GReater(ST(u*f,prime,omega,tieBreaker),ST(r,prime,omega,tieBreaker),prime,omega,tieBreaker)); i=H2.begin(); for(PolynomialSet::const_iterator j=G2.begin();j!=G2.end();i++,j++) { if(!((*i)*(*j)).isZero()) assert(!GReater(ST(u*f,prime,omega,tieBreaker),ST((*i)*(*j),prime,omega,tieBreaker),prime,omega,tieBreaker)); } } DEBUG debug<<"1\n"; for(TermMap::const_iterator k=r.terms.begin();k!=r.terms.end();k++) for(PolynomialSet::const_iterator j=G2.begin();j!=G2.end();j++) if(!j->isZero()) assert(!(SM(*j,prime,omega,tieBreaker).exponent.divides(k->first.exponent))); } return r; } Polynomial SPolynomial(Polynomial const &a, Polynomial const &b, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { Term lcm=Term(a.getRing().getField().zHomomorphism(1),Monomial(a.getRing(),max( ST(a,prime,omega,tieBreaker).m.exponent, ST(b,prime,omega,tieBreaker).m.exponent))); return (lcm/ST(a,prime,omega,tieBreaker))*a-(lcm/ST(b,prime,omega,tieBreaker))*b; } void pAdicAutoReduce(PolynomialSet &g, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { PolynomialSet temp(g.getRing()); for(PolynomialSet::iterator i=g.begin();i!=g.end();i++) { PolynomialSet::iterator ipp=i;ipp++; temp.splice(temp.begin(),g,i,ipp); i=ipp; DEBUG debug<<"TEMP"<isZero())) { (*temp.begin())*=ST(*temp.begin(),prime,omega,tieBreaker).c.inverse(); g.splice(i,temp,temp.begin(),temp.end()); } else { temp.pop_back(); } // debug<mark(SM(*i,prime,omega,tieBreaker)); } void pAdicBuchberger(PolynomialSet &g, int prime, IntegerVector const &omega, TermOrder const &tieBreaker) { for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) for(PolynomialSet::const_iterator j=g.begin();j!=i;j++) { log2 debug<<"checking s poly\n"<<*i<<"("<terms.begin();j!=i->terms.end();j++) { inOldRing+=Term(groebnerBasis.getRing().getField().zHomomorphism(j->second.getIntegerRepresentation()),Monomial(groebnerBasis.getRing(),j->first.exponent)); } PolynomialSet H(groebnerBasis.getRing()); Polynomial u=groebnerBasis.getRing().zero(); Polynomial r=longDivision(inOldRing, groebnerBasis,prime,omega,tieBreaker2,H,u); liftedBasis.push_back(u*inOldRing-r); } pAdicAutoReduce(liftedBasis,prime,omega,tieBreaker); PolynomialSet newInitialForms=pAdicInitialForms(R2,liftedBasis,prime,omega); // debug<<"LIFTED"<0) { // debug< #include "vektor.h" #include "monomial.h" #include "polynomial.h" #include "field.h" #include "polynomialring.h" using namespace std; class Parser { protected: void parserError(const char *expected, char c); public: virtual int parseInt()=0; virtual Monomial parseMonomial(PolynomialRing const &r)=0; virtual IntegerVector parseIntegerVector()=0; }; class CharacterBasedParser : public Parser { private: PolynomialRing azAZ(Field const &f, int n=52); bool isVariable(int c); bool isDigit(int c); int variableIndex(int c); protected: virtual int getChar()=0; virtual void ungetChar(int c)=0; public: int nextNonBlank(); int nextNonBlankDoNotGet(); bool isLeftBracket(int c); bool isRightBracket(int c); int parseChar(); int parseInt(); double parseFloat(); ComplexNumber parseComplexNumber(); FieldElement parseFieldElement(Field const &f); FieldElement parseFieldElementFromInteger(Field const &f); Monomial parseMonomial(PolynomialRing const &r); IntegerVector parseIntegerVector(); FloatVector parseFloatVector(); ComplexVector parseComplexVector(); IntegerVectorList parseIntegerVectorList(); IntegerVectorList parseIntegerVectorList4ti2(); IntegerVectorListList parseIntegerVectorListList(); Term parseTerm(PolynomialRing const &r); Field parseField(); string parseVariableName(); vector parseVariableList(); PolynomialRing parsePolynomialRing(); Polynomial parsePolynomial(PolynomialRing const &r); Polynomial parsePolynomialWithRing(); PolynomialSet parsePolynomialSet(PolynomialRing const &r); PolynomialSet parsePolynomialSetWithRing(); PolynomialSetList parsePolynomialSetList(PolynomialRing const &r); PolynomialSetList parsePolynomialSetListWithRing(); }; class FileParser : public CharacterBasedParser { FILE *f; protected: virtual int getChar(); virtual void ungetChar(int c); public: FileParser(FILE *f); }; class StringParser : public CharacterBasedParser { const char *s; int index; bool hasUngotten; char ungotten; protected: virtual int getChar(); virtual void ungetChar(int c); public: StringParser(const char *s); }; #endif gfan0.6.2/src/latticeideal.cpp0000644000175000017500000000143513122232611015602 0ustar andersanders#include "latticeideal.h" #include "binomial.h" #include "buchberger.h" #include "printer.h" #include "field_rationals.h" IntegerVectorList latticeIdealRevLex(IntegerMatrix const &lattice) { PolynomialRing theRing(Q,lattice.getHeight()); IntegerMatrix L=lattice.transposed(); PolynomialSet g(theRing); for(int i=0;isaturate(); } IntegerVectorList ret; for(PolynomialSet::const_iterator j=g.begin();j!=g.end();j++) ret.push_back(binomialToIntegerVector(*j)); return ret; } gfan0.6.2/src/gfanlib_symmetriccomplex.cpp0000644000175000017500000005366013122232611020253 0ustar andersanders/* * gfanlib_symmetriccomplex.cpp * * Created on: Nov 16, 2010 * Author: anders */ #include "gfanlib_symmetriccomplex.h" #include "gfanlib_polymakefile.h" #include #include namespace gfan{ SymmetricComplex::Cone::Cone(std::set const &indices_, int dimension_, Integer multiplicity_, bool sortWithSymmetry, SymmetricComplex const &complex): isKnownToBeNonMaximalFlag(false), dimension(dimension_), multiplicity(multiplicity_), sortKeyPermutation(complex.n) { indices=IntVector(indices_.size()); int j=0; for(std::set::const_iterator i=indices_.begin();i!=indices_.end();i++,j++) indices[j]=*i; ZMatrix const &vertices=complex.getVertices(); ZVector sum(vertices.getWidth()); for(unsigned i=0;i::const_iterator i =indexMap.begin();i!=indexMap.end();i++)std::cerr<first; std::map::const_iterator it=indexMap.find(v); assert(it!=indexMap.end()); return it->second; } void SymmetricComplex::Cone::remap(SymmetricComplex &complex) { ZMatrix const &vertices=complex.getVertices(); ZVector sum(vertices.getWidth()); for(unsigned i=0;i::const_iterator it=complex.indexMap.find(ny); assert(it!=complex.indexMap.end()); indicesNew[I]=it->second; } indices=indicesNew; } std::set SymmetricComplex::Cone::indexSet()const { std::set ret; for(unsigned i=0;i=c.indices.size())return false; if(indices[i]==c.indices[next])break; next++; } } return true; } SymmetricComplex::Cone SymmetricComplex::Cone::permuted(Permutation const &permutation, SymmetricComplex const &complex, bool withSymmetry)const { std::set r; for(unsigned i=0;i::const_iterator it=complex.indexMap.find(ny); if(it==complex.indexMap.end()) { // AsciiPrinter(Stderr).printVector(complex.vertices[indices[i]]); // AsciiPrinter(Stderr).printVector(ny); assert(0); } r.insert(it->second); } return Cone(r,dimension,multiplicity,withSymmetry,complex); } bool SymmetricComplex::Cone::operator<(Cone const & b)const { return sortKeydimension)dimension=c.dimension; if(!contains(c))//#2 { cones.insert(c); } else { if(c.isKnownToBeNonMaximal()){cones.erase(c);cones.insert(c);}// mark as non-maximal } } int SymmetricComplex::getLinDim()const { return linealitySpace.getHeight(); } int SymmetricComplex::getMaxDim()const { return dimension; } int SymmetricComplex::getMinDim()const { int ret=100000; for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++) { if(i->dimensiondimension; } return ret; } bool SymmetricComplex::isMaximal(Cone const &c)const { if(c.isKnownToBeNonMaximal())return false; if(c.dimension==dimension)return true; for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++) { Cone c2=c.permuted(*k,*this,false); for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++) { if(i->dimension>c.dimension) if(c2.isSubsetOf(*i) && !i->isSubsetOf(c2))return false; } } return true; } #if 0 IntVector SymmetricComplex::dimensionsAtInfinity()const { /* Using a double description like method this routine computes the dimension of the intersection of each cone in the complex with the plane x_0=0 */ IntVector ret(cones.size()); int I=0; for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++) { ZMatrix raysAtInfinity; for(int j=0;jindices.size();j++) { if(vertices[i->indices[j]][0]==0)raysAtInfinity.push_back(vertices[i->indices[j]]); for(vector::const_iterator k=j;k!=i->indices.end();k++) if(vertices[*j][0]*vertices[*k][0]<0) raysAtInfinity.push_back(((vertices[*j][0]>0)?1:-1)*(vertices[*j][0])*vertices[*k]+ ((vertices[*k][0]>0)?1:-1)*(vertices[*k][0])*vertices[*j]); } ret[I]=rankOfMatrix(raysAtInfinity); } return ret; } #endif void SymmetricComplex::buildConeLists(bool onlyMaximal, bool compressed, std::vector >*conelist, std::vector > *multiplicities)const { int dimLow=this->linealitySpace.getHeight(); int dimHigh=this->getMaxDim(); if(dimHigh >(dimHigh-dimLow+1); if(multiplicities)*multiplicities=std::vector >(dimHigh-dimLow+1); for(int d=dimLow;d<=dimHigh;d++) { int numberOfOrbitsOutput=0; int numberOfOrbitsOfThisDimension=0; // bool newDimension=true; { int I=0; for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++) if(i->dimension==d) { numberOfOrbitsOfThisDimension++; if(!onlyMaximal || isMaximal(*i)) { numberOfOrbitsOutput++; // bool isMax=isMaximal(*i); // bool newOrbit=true; std::set,Integer> > temp; for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++) { Cone temp1=i->permuted(*k,*this,false); temp.insert(std::pair,Integer>(temp1.indexSet(),temp1.multiplicity)); if(compressed)break; } for(std::set,Integer> >::const_iterator j=temp.begin();j!=temp.end();j++) { IntVector temp; for(std::set::const_iterator k=j->first.begin();k!=j->first.end();k++)temp.push_back(*k); if(conelist)(*conelist)[d-dimLow].push_back(temp); if(multiplicities)(*multiplicities)[d-dimLow].push_back(j->second); /* if(isMax)if(multiplicities) { *multiplicities << i->multiplicity; if(group)if(newOrbit)*multiplicities << "\t# New orbit"; if(newDimension)*multiplicities << "\t# Dimension "<dimension==d) { numberOfOrbitsOfThisDimension++; if(!onlyMaximal || isMaximal(*i)) { numberOfOrbitsOutput++; bool isMax=isMaximal(*i); bool newOrbit=true; std::set > temp; for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++) { Cone temp1=i->permuted(*k,*this,false); temp.insert(temp1.indexSet()); if(compressed)break; } for(std::set >::const_iterator j=temp.begin();j!=temp.end();j++) { ret << "{"; for(std::set::const_iterator a=j->begin();a!=j->end();a++) { if(a!=j->begin())ret<<" "; ret << *a; } ret << "}"; if(group)if(newOrbit)ret << "\t# New orbit"; if(newDimension)ret << "\t# Dimension "<multiplicity; if(group)if(newOrbit)*multiplicities << "\t# New orbit"; if(newDimension)*multiplicities << "\t# Dimension "<indices.size();j++) if(vertices[i->indices[j]][0].sign()==0)isBounded=false; doAdd=isBounded; } if(doAdd) ret[i->dimension-min]+=Integer(sym.orbitSize(i->sortKey)); } return ret; } bool SymmetricComplex::isPure()const { int dim=-1; for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++) { if(isMaximal(*i)) { int dim2=i->dimension; if(dim==-1)dim=dim2; if(dim!=dim2)return false; } } return true; } bool SymmetricComplex::isSimplicial()const { int linealityDim=getMinDim(); for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++) if(!i->isSimplicial(linealityDim)) return false; return true; } void SymmetricComplex::remap() { for(ConeContainer::iterator i=cones.begin();i!=cones.end();i++) { Cone const&j=*i; Cone &j2=const_cast(j);//DANGER: cast away const. This does not change the sort key in the container, so should be OK. j2.remap(*this); } } int SymmetricComplex::numberOfConesOfDimension(int d)const { assert(sym.isTrivial()); int ret=0; for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++) if(d==i->dimension) { ret++; } return ret; } int SymmetricComplex::dimensionIndex(Cone const &c) { assert(sym.isTrivial()); int ret=0; for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++) if(c.dimension==i->dimension) { if(!(c<*i)&&!(*i &indices_, vector &signs) { indices_=vector(); signs=vector(); int d=c.dimension; IntegerVectorList l; for(int i=0;i indices; for(vector::const_iterator j=c.indices.begin();j!=c.indices.end();j++)if(dotLong(vertices[*j],*i)==0)indices.insert(*j); Cone facet(indices,d-1,1,true,*this); IntegerVectorList complementBasis2=facet.orthogonalComplement(*this); for(IntegerVectorList::const_iterator j=completion.begin();j!=completion.end();j++)complementBasis2.push_back(*j); indices_.push_back(dimensionIndex(facet)); signs.push_back(sign*determinantSign(complementBasis2)); } } IntegerMatrix SymmetricComplex::boundaryMap(int d) { assert(sym.isTrivial()); IntegerMatrix ret(numberOfConesOfDimension(d-1),numberOfConesOfDimension(d)); for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++) if(d==i->dimension) { int I=dimensionIndex(*i); vector indices; vector signs; boundary(*i,indices,signs); for(int j=0;jcontains(*i)&&(j->dimensionOfLinealitySpace()+1==j->dimension())) primitiveRays.push_back(j->semiGroupGeneratorOfRay()); polymakeFile.writeMatrixProperty("PRIMITIVE_RAYS",rowsToIntegerMatrix(primitiveRays,n)); } */ #if 0 ZMatrix generatorsOfLinealitySpace=cones.begin()->generatorsOfLinealitySpace(); log1 fprintf(Stderr,"Building symmetric complex.\n"); for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++) { { static int t; // log1 fprintf(Stderr,"Adding faces of cone %i\n",t++); } // log2 fprintf(Stderr,"Dim: %i\n",i->dimension()); addFacesToSymmetricComplex(symCom,*i,i->getHalfSpaces(),generatorsOfLinealitySpace); } // log1 cerr<<"Remapping"; symCom.remap(); // log1 cerr<<"Done remapping"; PolyhedralFan f=*this; #endif // log1 fprintf(Stderr,"Computing f-vector.\n"); ZVector fvector=this->fvector(); polymakeFile.writeCardinalVectorProperty("F_VECTOR",fvector); // log1 fprintf(Stderr,"Done computing f-vector.\n"); if(flags&FPF_boundedInfo) { // log1 fprintf(Stderr,"Computing bounded f-vector.\n"); ZVector fvectorBounded=this->fvector(true); polymakeFile.writeCardinalVectorProperty("F_VECTOR_BOUNDED",fvectorBounded); // log1 fprintf(Stderr,"Done computing bounded f-vector.\n"); } #if 0 { Integer euler; int mul=-1; for(int i=0;iprintString(S.c_str()); */// log1 fprintf(Stderr,"Done printing string.\n"); } ZCone SymmetricComplex::makeZCone(IntVector const &indices)const { ZMatrix generators(indices.size(),getAmbientDimension()); for(unsigned i=0;i class SageSingularPrimDec : public PrimaryDecompositionEngine { public: SageSingularPrimDec() : PrimaryDecompositionEngine() { cerr<<"constructing SageSingularPrimDec"<-D to end.\n"; } LexicographicTermOrder myOrder; PolynomialSet g=FileParser(Stdin).parsePolynomialSetWithRing(); if(optionParameters.getValue())g=makeVariablesParameters(makeVariablesParameters(g.getRing(),optionParameters.getValue()),g); log3 AsciiPrinter(Stderr).printPolynomialSet(g); AsciiPrinter(Stdout).printPolynomialRing(g.getRing()); printf("\n"); EnumerationFilePrinter *ep; { ep=new StandardEnumerationPrinter(); } bool outputLatex=true; Printer *P; LatexPrinter *Q; FILE *latexFile; globalTimer.on(); { if(optionInputIsGroebnerBasis.getValue()) { log1 fprintf(Stderr,"Minimizing and autoreducing input...\n"); minimize(&g); autoReduce(&g, LexicographicTermOrder()); } else { log1 fprintf(Stderr,"Computing Groebner Basis...\n"); buchberger(&g,StandardGradedLexicographicTermOrder()); log2 AsciiPrinter(Stderr).printPolynomialSet(g); } log1 fprintf(Stderr,"A reduced Groebner basis has been computed\n"); } SymmetryGroup s(g.numberOfVariablesInRing()); IntegerVectorList generators; { EnumerationAlgorithm *rs; if(optionSymmetry.getValue()) { generators=FileParser(Stdin).parseIntegerVectorList(); if(!optionDisableSymmetryTest.getValue()) { for(IntegerVectorList::iterator i=generators.begin();i!=generators.end();i++) { // fprintf(Stderr,"testing\n"); assert(areIdealsEqual(g,SymmetryGroup::permutePolynomialSet(g,*i))); } } s.computeClosure(generators); log1 s.print(Stderr); if(0) {//using old breadth first traversal BreadthFirstSearch *bs=new BreadthFirstSearch(s,/*minkowski*/0); /* if(optionSubspace.getValue()) bs->setSubspace(FileParser(Stdin).parseIntegerVectorList()); */ rs=bs; if(optionEchoSymmetry.getValue())AsciiPrinter(Stdout).printVectorList(generators); ep->open(Stdout); rs->setEnumerationTarget(ep); rs->enumerate(g); delete rs; //<--- In next release, make the class virtual } else {//using new traversal GroebnerFanTraverser traverser(g); TargetGlue target(*ep); if(optionEchoSymmetry.getValue())AsciiPrinter(Stdout).printVectorList(generators); ep->open(Stdout); SymmetricTargetCounterInterrupted target2(target,optionInterrupt.getValue()); symmetricTraverse(traverser,target2,&s); } } else { rs=new ReverseSearch(myOrder); ep->open(Stdout); rs->setEnumerationTarget(ep); rs->enumerate(g); delete rs;//<--- In next release, make the class virtual } } ep->close(); delete ep;//<--- In next release, make the class virtual printf("\n"); globalTimer.off(); // if(optionPerformanceTimer.getValue())Timer::printList(); return 0; } }; static GCats theApplication("_bases"); static GCats theApplication2(""); gfan0.6.2/src/polynomialgcd.cpp0000644000175000017500000005400013122232611016013 0ustar andersanders/* * polynomialgcd.cpp * * Created on: Apr 26, 2014 * Author: anders */ #define USEFACTORY 0 #include //#include #include #include "field_rationals.h" #include "field_zmodpz.h" //#include "factory.h" // to be moved into a subclass //#include "/home/anders/math/software/Singular-svn/trunk/x86_64-Linux/include/factory.h" // to be moved into a subclass // AT THE MOMENT WE CANNOT USE FACTORY TOGETHER WITH MATRICES IN THIS FILE!!! //#define USEFACTORY 1 #if USEFACTORY #include "factory/factory.h" #else #include "linalg.h" #include "polynomial.h" #endif #include "polynomialgcd.h" #include "saturation.h" #include "printer.h" #include "wallideal.h" inline int64 min(int64 a, int64 b){return a >& operator<< (std::basic_ostream >&, List const&); #if USEFACTORY CanonicalForm convertToFactory(Polynomial const &a) { CanonicalForm A=0; int n=a.getRing().getNumberOfVariables(); for(TermMap::const_iterator i=a.terms.begin();i!=a.terms.end();i++) { CanonicalForm term; if(a.getRing().getField().getCharacteristic()==0) { mpq_t *c=const_cast(i->second.getGmpRationalTemporaryPointer()); mpz_t num; mpz_t den; mpz_init_set(num,mpq_numref(*c)); mpz_init_set(den,mpq_denref(*c)); term=make_cf(num,den,true); } else { // term=make_cf_from_gf(i->second.getIntegerRepresentation()); term=i->second.getIntegerRepresentation(); } for(int j=0;jfirst.exponent[j]);//HERE A+=term; } return A; } static void recursiveConvert(const CanonicalForm &f, IntegerVector &exponentVector, PolynomialRing const &r, Polynomial &result) { if (f.isZero()) { return; } if ( ! f.inCoeffDomain() ) { int l = f.level()-1;//HERE for ( CFIterator i = f; i.hasTerms(); i++ ) { exponentVector[l]=i.exp(); recursiveConvert(i.coeff(),exponentVector,r,result); } exponentVector[l]=0; } else { FieldElement c(r.getField()); if ( f.isImm() ) { c=r.getField().zHomomorphism(f.intval()); } else { mpz_t den; gmp_denominator(f,den); mpz_t num; gmp_numerator(f,num); FieldElement K=fieldElementFromGmpZ(&num);//Should these take the field as argument? FieldElement L=fieldElementFromGmpZ(&den); c=K*L.inverse(); } result+=Term(c,Monomial(r,exponentVector)); } } Polynomial convertFromFactory(CanonicalForm &A, PolynomialRing const &r) { IntegerVector v(r.getNumberOfVariables()); Polynomial res(r); recursiveConvert(A,v,r,res); // debug<<"RESULT:"<0 /*TODO:check if field is Z/pZ */); // debug<<"polynomialGCD called on:\n"< parts; for(TermMap::const_iterator i=p->terms.begin();i!=p->terms.end();i++) { // parts[grading.vectormultiply(i->first.exponent)][i->first]=i->second; //This line fails when not using shared pointers for implementing objects of FieldElements parts[grading.vectormultiply(i->first.exponent)].insert(*i); } for(map::const_iterator i=parts.begin();i!=parts.end();i++) { Polynomial a(l.getRing()); for(TermMap::const_iterator j=i->second.begin();j!=i->second.end();j++) a+=Term(j->second,Monomial(l.getRing(),j->first.exponent)); ret.push_back(a); } } return ret; } PolynomialSet splitPoly(Polynomial const &p, IntegerVector const &gradings)//gradings is a zero-one vector { PolynomialSet ret(p.getRing()); map parts; for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { parts[coordinatewiseProduct(i->first.exponent,gradings)][i->first]=i->second;//This line seems to cause a copy of a FieldElement that has only been initialised with its default constructor. } for(map::const_iterator i=parts.begin();i!=parts.end();i++) { Polynomial a(p.getRing()); for(TermMap::const_iterator j=i->second.begin();j!=i->second.end();j++) a+=Term(j->second,Monomial(p.getRing(),j->first.exponent)); ret.push_back(a); } return ret; } PolynomialSet splitPolys(PolynomialSet const &s, IntegerVector const &gradings)//gradings is a zero-one vector { PolynomialSet ret=s.getRing(); for(PolynomialSet::const_iterator i=s.begin();i!=s.end();i++) { PolynomialSet temp=splitPoly(*i,gradings); ret.insert(ret.end(),temp.begin(),temp.end()); } return ret; } Polynomial findFactorForRandomSubstitutionAllButI(PolynomialSet p, int i); Polynomial findFactorForRandomSubstitution(PolynomialSet const &p, int i, FieldElement v); static bool comparer(const Polynomial & a, const Polynomial & b) {return a.totalDegree()> b.totalDegree();} Polynomial withLexLargestCoefficientScaledTo(Polynomial p, FieldElement v) { LexicographicTermOrder T; p.mark(T); FieldElement s=p.getMarked().c.inverse()*v; return p*s; } Polynomial naiveGCD(PolynomialSet const &p) { assert(p.size()); Polynomial ret=p.front(); PolynomialSet::const_iterator i=p.begin();i++; for(;i!=p.end();i++) { PolynomialSet a(p.getRing()); PolynomialSet b(p.getRing()); a.push_back(ret); b.push_back(*i); PolynomialSet c=idealIntersection(a,b); assert(c.size()==1); c.front().divides(ret*(*i),&ret); } return ret; } bool simplifyPolynomialsForGCD(PolynomialSet const &p, PolynomialSet &newPolys, IntegerVector &support) { IntegerVector dv=p.front().degreeVector(); for(auto i=p.begin();i!=p.end();i++)dv=min(dv,i->degreeVector()); support=dv.supportVector(); if(support.sum()!=support.size()) { int newnvars=support.sum(); PolynomialRing r=p.getRing(); PolynomialRing r2=r.subRing(support); newPolys=splitPolys(p,IntegerVector::allOnes(support.size())-support).withRestrictedVariables(support,r2); newPolys.saturate(); return true; } return false; } PolynomialSet simplifyPolysViaHomogeneitySpace(PolynomialSet p) { FieldMatrix A=spanOfHomogeneitySpaces(p); // debug<>"<=4) // debug<<"LEVEL3:"< bool {return a.totalDegree()> b.totalDegree();} );*/ // debug<degreeVector()); IntegerVector support=dv.supportVector(); if(support.sum()!=support.size()) {// the positions where support is zero are not used in at least one polynomial. // Therefore it cannot we involved in the gcd. // The gcd must then divide each homogeneous part in all gradings w.r.t. e_i where support_i==1 //debug<<"A\n"<1) { PolynomialSet p3(r); for(PolynomialSet::const_iterator i=p.begin();i!=p.end();i++) { // Polynomial q(r); // projectionFactor.divides(*i,&q);//exact division? Polynomial q=i->exactlyDividedBy(projectionFactor); p3.push_back(q); } return projectionFactor*NonMonomialPolynomialGCDForZModP(p3); } // assert(0); // check if this is because the projection direction gave a factor // if so divide a try again. Multiply // if not continure , i.e. try again continue; } else { // we think we found a factor // debug<<"OTHER DIRECTION"<degree(IntegerVector::standardVector(n,i))); */ int M=findFactorForRandomSubstitutionAllButI(p,i).totalDegree(); // M--;//////////////////// FORCE FACTOR TO CONTAIN THE ITH VARIABLE?????? // debug<<"M:"< > samples; int randomtries=0; for(int k=0;k(c2,f2)); else { k--; randomtries++; if(randomtries>100)debug<<"TROUBLE IN GCD COMPUTATION\n"; } } // debug<<"AA\n"; set observedExponentsSet; for(vector >::const_iterator k=samples.begin();k!=samples.end();k++) { IntegerVectorList L=k->second.exponents(); // debug.printVectorList(L); for(IntegerVectorList::const_iterator l=L.begin();l!=L.end();l++) //observedExponentsSet.insert(l->withIthCoordinateRemoved(i)); observedExponentsSet.insert(*l); } // debug<<"AB\n"; vector observedExponents; for(set::const_iterator a=observedExponentsSet.begin();a!=observedExponentsSet.end();a++)observedExponents.push_back(*a); // debug<<"AC\n"; int numberOfObservedExponents=observedExponents.size(); int width=(M+1)*numberOfObservedExponents+numberOfSamples; int height=numberOfObservedExponents*numberOfSamples; // debug<<"AD\n"; FieldMatrix A(r.getField(),height,width); // debug< >::const_iterator k=samples.begin();k!=samples.end();k++,K++) { for(int a=0;afirst; } A[K*numberOfObservedExponents+a][(M+1)*numberOfObservedExponents+K]=k->second.coefficientOf(observedExponents[a]); } } // debug<<"OBSERVED EXPONENTS:"; IntegerVectorList setTemp;for(auto c=observedExponents.begin();c!=observedExponents.end();c++)setTemp.push_back(*c); // debug.printVectorList(setTemp); // debug<<"Multiplication terms: 1,...,"<<"x_"<isZero())allAreZero=false; if(allAreZero)return r2.zero(); } // debug<<"RANDOMSUBST"<i),true); FieldElement v=r2.getField().random(); p=p.withIthVariableSubstituted(r2,j>i,v); } // debug<terms.begin();j!=i->terms.end();j++)if(!j->second.isInteger()){hasIntegerCoefficients=false;s=j->second.multiplierGivingInteger();break;} if(!hasIntegerCoefficients)(*i)*=s; }while(!hasIntegerCoefficients); } } FieldElement gcdofcoef=p.front().getMarked().c; for(PolynomialSet::const_iterator i=p.begin();i!=p.end();i++) { FieldElement temp1=p.getRing().getField().zHomomorphism(0); FieldElement temp2=p.getRing().getField().zHomomorphism(0); gcdofcoef=gcd(gcdofcoef,i->getMarked().c,temp1,temp2); } // We should use Chinese remainer reconstruction in the following. // But since our examples are quite simple for now, we just stict to considering one prime at a time const int primes[]={9851,9967,37,13}; for(int i=0;iisZero())good=false; if(!good){debug<<"FAIL ON:"< data; void insert(Polynomial const &p) { if(p.numberOfTerms()>2) { if(data.size()greatestCommonMonomialDivisor(); for(auto i=p.begin();i!=p.end();i++)monomialFactor=min(monomialFactor,i->greatestCommonMonomialDivisor()); p.saturate(); // for(PolynomialSet::iterator j=p.begin();j!=p.end();j++) // *j*=Monomial(r,-monomialFactor); return NonMonomialPolynomialGCDForZModP(r,p)*Monomial(r,monomialFactor); } #endif gfan0.6.2/src/continuedfractions.h0000644000175000017500000000046513122232611016526 0ustar andersanders#ifndef CONTINUEDFRACTIONS_H_INCLUDED #define CONTINUEDFRACTIONS_H_INCLUDED #include using namespace std; void doubleToFraction(double f, int &numerator, int &denominator, int maksIter=15); void doubleVectorToFractions(vector const &v, vector &numerators, int &denominator); #endif gfan0.6.2/src/printer.h0000644000175000017500000001724713122232611014316 0ustar andersanders#ifndef Printer_INCLUDED #define Printer_INCLUDED class Printer; #include #include #include "vektor.h" #include "term.h" #include "termorder.h" #include "polynomial.h" // We need to help the Mac compiler: #define Stdin ((FILE*)stdin) #define Stdout ((FILE*)stdout) #define Stderr ((FILE*)stderr) class Printer { static bool assertOnPrinting; protected: static void printCheck(); FILE *f; virtual string variableIndexToString(PolynomialRing const &r, int i); public: static void setAssertOnPrinting(bool b); Printer(FILE *f){this->f=f;}; virtual void printVariable(PolynomialRing const &r, int i); virtual void printInteger(int i, int minimalFieldWidth=0)=0; virtual void printFloat(double i, int minimalFieldWidth=0)=0; virtual void printComplexNumber(ComplexNumber const &i, int minimalFieldWidth=0)=0; // virtual void printComplex(class complex const &c, int minimalFieldWidth=0)=0; virtual void printMonomial(const Monomial &m, bool alwaysWriteSign=false, bool writeIfOne=true)=0; virtual void printFieldElement(const FieldElement &e, bool writeIfOne=true, bool alwaysWriteSign=false)=0; virtual void printTerm(const Term &t)=0; virtual void printPolynomial(const Polynomial &p)=0; virtual void printPolynomialSet(const PolynomialSet &p, bool newLine=false)=0; virtual void printPolynomialSetList(const PolynomialSetList &s)=0; virtual void printVector(const IntegerVector &v, bool curly=false, int minimalFieldWidth=0)=0; virtual void printFloatVector(FloatVector const &v, bool curly=false, int minimalFieldWidth=0)=0; virtual void printComplexVector(ComplexVector const &v, bool curly=false, int minimalFieldWidth=0)=0; virtual void printVectorList(const IntegerVectorList &s, bool indexed=false)=0; virtual void printVectorListList(const IntegerVectorListList &s)=0; virtual void printString(const string &s)=0; virtual void printNewLine()=0; virtual void printChar(int c){char s[2];s[0]=c;s[1]=0;printString(s);} virtual void printTermOrder(TermOrder const &t); virtual void printPolyhedralCone(class PolyhedralCone const &c, bool xml=false); virtual void printPolyhedralConeAsFan(class PolyhedralCone const &c); virtual void printPolyhedralFan(class PolyhedralFan const &c); virtual void printField(class Field const &f); virtual void printPolynomialRing(class PolynomialRing const &r); Printer& operator<<(IntegerVector const &v) { printVector(v); return *this; } /* Printer& operator<<(FloatVector const &v) { printFloatVector(v); return *this; }*/ Printer& operator<<(class FieldElement const &v); Printer& operator<<(class FieldVector const &v); Printer& operator<<(class FieldMatrix const &m); Printer& operator<<(IntegerVectorList const &l); Printer& operator<<(IntegerVectorListList const &l); Printer& operator<<(PolynomialRing const &r); Printer& operator<<(PolynomialSet const &l); Printer& operator<<(Polynomial const &p); Printer& operator<<(const string &s); Printer& operator<<(list &l); Printer& operator<<(class PolyhedralCone const &c); Printer& operator>>(class PolyhedralCone const &c); Printer& operator<<(class PolyhedralFan const &f); Printer& operator<<(class TermOrder const &t); Printer& operator<<(int a); Printer& operator<<(double a); }; class LatexPrinter:public Printer { int mathModeLevel; void pushMathMode(); void popMathMode(); public: LatexPrinter(FILE *f):Printer(f){mathModeLevel=0;} virtual void printInteger(int i, int minimalFieldWidth=0); virtual void printFloat(double i, int minimalFieldWidth=0); virtual void printComplexNumber(ComplexNumber const &i, int minimalFieldWidth=0); virtual void printMonomial(const Monomial &m, bool alwaysWriteSign=false, bool writeIfOne=true); virtual void printFieldElement(const FieldElement &e, bool writeIfOne=true, bool alwaysWriteSign=false); virtual void printTerm(const Term &t); virtual void printPolynomial(const Polynomial &p); virtual void printPolynomialSet(const PolynomialSet &s, bool newLine=false); virtual void printPolynomialSetList(const PolynomialSetList &s); virtual void printVector(const IntegerVector &v, bool curly=false, int minimalFieldWidth=0); virtual void printFloatVector(FloatVector const &v, bool curly=false, int minimalFieldWidth=0); virtual void printComplexVector(ComplexVector const &v, bool curly=false, int minimalFieldWidth=0); virtual void printVectorList(const IntegerVectorList &s, bool indexed=false); virtual void printVectorListList(const IntegerVectorListList &s); virtual void printString(const string &s); virtual void printNewLine(); void printLatexStart(); void printLatexEnd(); }; class AsciiPrinter:public Printer { public: AsciiPrinter(FILE *f):Printer(f){} virtual char vectorLeftBrackets(){return '(';} virtual char vectorRightBrackets(){return ')';} virtual char vectorListLeftBrackets(){return '{';} virtual char vectorListRightBrackets(){return '}';} virtual void printInteger(int i, int minimalFieldWidth=0); virtual void printFloat(double i, int minimalFieldWidth=0); virtual void printComplexNumber(ComplexNumber const &i, int minimalFieldWidth=0); virtual void printMonomial(const Monomial &m, bool alwaysWriteSign=false, bool writeIfOne=true); virtual void printFieldElement(const FieldElement &e, bool writeIfOne=true, bool alwaysWriteSign=false); virtual void printTerm(const Term &t); virtual void printPolynomial(const Polynomial &p); virtual void printPolynomialSet(const PolynomialSet &s, bool newLine=false); virtual void printPolynomialSetList(const PolynomialSetList &s); virtual void printVector(const IntegerVector &v, bool curly=false, int minimalFieldWidth=0); virtual void printFloatVector(FloatVector const &v, bool curly=false, int minimalFieldWidth=0); virtual void printComplexVector(ComplexVector const &v, bool curly=false, int minimalFieldWidth=0); virtual void printVectorList(const IntegerVectorList &s, bool indexed=false); virtual void printVectorListList(const IntegerVectorListList &s); virtual void printString(const string &s); virtual void printNewLine(); }; class XmlPrinter:public Printer { public: XmlPrinter(FILE *f):Printer(f){} virtual void printInteger(int i, int minimalFieldWidth=0); virtual void printFloat(double i, int minimalFieldWidth=0); virtual void printComplexNumber(ComplexNumber const &i, int minimalFieldWidth=0); virtual void printMonomial(const Monomial &m, bool alwaysWriteSign=false, bool writeIfOne=true); virtual void printFieldElement(const FieldElement &e, bool writeIfOne=true, bool alwaysWriteSign=false); virtual void printTerm(const Term &t); virtual void printPolynomial(const Polynomial &p); virtual void printPolynomialSet(const PolynomialSet &s, bool newLine=false); virtual void printPolynomialSetList(const PolynomialSetList &s); virtual void printString(const string &s); virtual void printNewLine(); virtual void printVector(const IntegerVector &v, bool curly=false, int minimalFieldWidth=0); virtual void printFloatVector(FloatVector const &v, bool curly=false, int minimalFieldWidth=0); virtual void printComplexVector(ComplexVector const &v, bool curly=false, int minimalFieldWidth=0); virtual void printVectorList(const IntegerVectorList &s, bool indexed=false); virtual void printVectorListList(const IntegerVectorListList &s); }; class TopcomPrinter:public AsciiPrinter { public: TopcomPrinter(FILE *f):AsciiPrinter(f){} virtual char vectorLeftBrackets(){return '[';} virtual char vectorRightBrackets(){return ']';} virtual char vectorListLeftBrackets(){return '[';} virtual char vectorListRightBrackets(){return ']';} }; extern AsciiPrinter debug; extern AsciiPrinter pout; #define D(a) debug<<#a<<":"< chosenVariables; for(int j=0;jterms.begin();j!=i2->terms.end();j++) p+=Term(Q.zHomomorphism(1),Monomial(r,j->first.exponent[i]*IntegerVector::standardVector(2,0)+dot(j->first.exponent,concatenation(IntegerVector(1),*k))*IntegerVector::standardVector(2,1))); newI.push_back(p); } debug << "NEW" << newI << "\n"; assert(0); PolyhedralFan::fullSpace(2) Fnew=PolyhedralFan::fullSpace(2); for(PolynomialSet::const_iterator i=newI.begin();i!=newI.end();i++) { Fnew=refinement(PolyhedralFan::normalFanOfNewtonPolytope(*i),F); } if(Fnew.conesBegin()->linealitySpace().dimension()==1) { IntegerVectorList toCheckNew=Fnew.getRays(); for(PolyhedralFan::coneIterator i=Fnew.begin();i!=Fnew.end();i++) if(i->dimension()==2) toCheckNew.push_back(i->getRelativeInteriorPoint()); IntegerVectorList toCheck; for(IntegerVector::const_iterator i=toCheckNew.begin();i!=toCheckNew.end();i++) toCheck.push_back(); } else { assert(0); } PolyhedralFan F(n); #endif // debug<<"COOONE"<<*k<exponents()<<"\n"; F.printWithIndices(&debug,FPF_default); PolyhedralFan t=PolyhedralFan::bergmanOfPrincipalIdeal(*i); t.printWithIndices(&debug,FPF_default); F=refinement(t,F); F.printWithIndices(&debug,FPF_default); } }*/ log2 debug<<"Done with polyhedral computations\n"; log2 debug<<"Intersection fan dim "<subvector(1,n).isZero()) candidates.push_back(*j); log2 debug<<"Number of candidates "<<(int)candidates.size()<<"\n"; if(candidates.size()==1) { ret.push_back(candidates.front()); if(earlyExit)return ret; } else { toCheck.splice(toCheck.end(),candidates); } assert(i==0); } else { stat_finiteLiftHard++; complicatedList.push_back(*k); } } log2 debug<<"Checking complicated list:\n"; log2 debug<supportAsZeroOneVector(); log2 debug<<"Support sum:"<=i)j2++; list chosenVariables; chosenVariables.push_back(i); chosenVariables.push_back(j2); IntegerVectorList A; #if 0 A.push_back(IntegerVector::allOnes(n)-IntegerVector::standardVector(n,i)-IntegerVector::standardVector(n,j2)); A.push_back(IntegerVector::allOnes(n)); MatrixTermOrder T(A); PolynomialSet J=I; debug<<"Doing elimination\n"; buchberger(&J,T,true); PolynomialRing newRing2(newRing.getField(),2); PolynomialSet P=J.polynomialRingIntersection(newRing2,&chosenVariables); #else A.push_back(IntegerVector::allOnes(n+1)-IntegerVector::standardVector(n+1,i)-IntegerVector::standardVector(n+1,j2)-IntegerVector::standardVector(n+1,n)); A.push_back(IntegerVector::allOnes(n+1)); MatrixTermOrder T(A); PolynomialRing newRing3=I.getRing().withVariablesAppended("H"); PolynomialSet J=I.homogenization(newRing3); log2 debug<<"Doing elimination\n"; buchberger(&J,T,true); J.changeNumberOfVariables(I.getRing()); PolynomialRing newRing2(newRing.getField(),2); PolynomialSet P=J.polynomialRingIntersection(newRing2,&chosenVariables); #endif additionalPolys.splice(additionalPolys.end(),J); log2 debug<<"Done eliminating\n"; log2 debug<generatorsOfLinealitySpace(); assert(l.size()==1); F.push_back(l.front()); F.push_back(-l.front()); // debug<<"LINgen"<0) { // debug<<"YES\n"; int LCM=(*k)[j]*(*l)[1]/gcdGFAN((*k)[j],(*l)[1]); int s1=LCM/(*k)[j]; int s2=LCM/(*l)[1]; if(s1<0)s1=-s1; if(s2<0)s2=-s2; // debug<<"YES\n"; IntegerVector v=s1*concatenation(concatenation(k->subvector(0,i),IntegerVector(1)),k->subvector(i,n-1))+s2*(*l)[0]*IntegerVector::standardVector(n,i); preCheck.push_back(v); } log2 debug<<"Combined:\n"<=i)j2++; list chosenVariables; chosenVariables.push_back(i); chosenVariables.push_back(j2); IntegerVectorList A; A.push_back(IntegerVector::allOnes(n)-IntegerVector::standardVector(n,i)-IntegerVector::standardVector(n,j2)); A.push_back(IntegerVector::allOnes(n)); MatrixTermOrder T(A); PolynomialSet J=I; debug<<"Doing elimination\n"; buchberger(&J,T,true); PolynomialRing newRing2(newRing.getField(),2); PolynomialSet P=J.polynomialRingIntersection(newRing2,&chosenVariables); debug<<"Done eliminating\n"; assert(P.size()==1); debug<<"Doing polyhedral computation\n"; // debug<<"PFRONT:"<generatorsOfLinealitySpace(); assert(l.size()==1); F.push_back(l.front()); F.push_back(-l.front()); // debug<<"LINgen"<0) { // debug<<"YES\n"; int LCM=(*k)[j]*(*l)[1]/gcdGFAN((*k)[j],(*l)[1]); int s1=LCM/(*k)[j]; int s2=LCM/(*l)[1]; if(s1<0)s1=-s1; if(s2<0)s2=-s2; // debug<<"YES\n"; IntegerVector v=s1*concatenation(concatenation(k->subvector(0,i),IntegerVector(1)),k->subvector(i,n-1))+s2*(*l)[0]*IntegerVector::standardVector(n,i); preCheck.push_back(v); } debug<<"Combined:\n"<isZero())) { AsciiPrinter(Stdout).printVector(*i); fprintf(Stdout," :"); AsciiPrinter(Stdout).printInteger(multiplicity(initialIdeal(theInput,*i))); fprintf(Stdout,"\n"); } } } int t=optionNumberOfNegativeVariables.getValue(); assert(t<=n); IntegerVectorList equations,inequalities; for(int i=0;i=0)isNeg=false; } if(isNeg) { AsciiPrinter(Stdout).printVector(v);fprintf(Stdout,"\n"); } } return 0; } }; static TropicalLiftingApplication theApplication; gfan0.6.2/src/gfanlib_field.cpp0000644000175000017500000000070413122232611015721 0ustar andersanders/* * gfanlib_field.cpp * * Created on: Sep 2, 2015 * Author: anders */ #include "gfanlib_field.h" FieldElement::FieldElement(Field const &f): // theField(f) implementingObject(f.zHomomorphismImplementation(0)) { // assert(f.implementingObject); // implementingObject=f.zHomomorphismImplementation(0);//create object with refCount 1 // f.implementingObject->refCount++; // flog2 fprintf(Stderr,"FieldElement - constructing1\n"); } gfan0.6.2/src/gfanlib_circuittableint.cpp0000644000175000017500000000031713122232611020023 0ustar andersanders/* * gfanlib_circuittableint.cpp * * Created on: Apr 10, 2016 * Author: anders */ #include "gfanlib_circuittableint.h" namespace gfan{ class MVMachineIntegerOverflow MVMachineIntegerOverflow; } gfan0.6.2/src/app_tropicalhypersurface.cpp0000644000175000017500000000246713122232611020262 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "polyhedralcone.h" #include "polyhedralfan.h" #include "tropical.h" #include "tropical2.h" #include "symmetry.h" #include "halfopencone.h" #include "log.h" class TropicalHypersurfaceApplication : public GFanApplication { public: const char *helpText() { return "This program computes the tropical hypersurface defined by a principal" " ideal. The input is the polynomial ring followed by a set containing" " just a generator of the ideal."; } TropicalHypersurfaceApplication() { registerOptions(); } const char *name() { return "_tropicalhypersurface"; } int main() { FileParser P(Stdin); PolynomialSet f=P.parsePolynomialSetWithRing(); int n=f.numberOfVariablesInRing(); assert(f.size()==1); PolyhedralFan F=PolyhedralFan::bergmanOfPrincipalIdeal(*f.begin()); { AsciiPrinter p(Stdout); PolyhedralFan a=F; a.printWithIndices(&p,FPF_default|FPF_values|FPF_multiplicities); } return 0; } }; static TropicalHypersurfaceApplication theApplication; gfan0.6.2/src/polyhedral.h0000644000175000017500000000000113122232611014752 0ustar andersanders gfan0.6.2/src/app_tropicalcurve.cpp0000644000175000017500000001001513122232611016672 0ustar andersanders/* * app_tropicalcurve.cpp * * Created on: Apr 23, 2014 * Author: anders */ #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "polyhedralcone.h" #include "polyhedralfan.h" #include "tropical.h" #include "tropical2.h" #include "tropicalbasis.h" #include "tropicalcurve.h" #include "dimension.h" #include "field_rationalfunctions2.h" #include "log.h" class TropicalCurveApplication : public GFanApplication { // SimpleOption optionHomogenize; SimpleOption optionSingleRay; IntegerOption optionParameters; public: const char *helpText() { return "This program computes a tropical basis for an ideal defining a tropical curve. Defining a tropical curve means that the Krull dimension of R/I is at most 1 + the dimension of the homogeneity space of I where R is the polynomial ring. The input is a generating set for the ideal. If the input is not homogeneous option -h must be used.\n"; } TropicalCurveApplication(): // optionHomogenize("-h","Homogenise the input before computing a tropical basis and dehomogenise the output. This is needed if the input generators are not already homogeneous.") optionParameters("--parameters","With this option you can specify how many variables to treat as parameters instead of variables. This makes it possible to do computations where the coefficient field is the field of rational functions in the parameters.",0), optionSingleRay("--singleray","Only compute a single ray of the curve.") { registerOptions(); } const char *name() { return "_tropicalcurve"; } IntegerVectorList tropicalCurveWithPreprocessing(PolynomialSet const &theInput) { { list temp=theInput.multiDeHomogenizationToKeep(); for(list::const_iterator i=temp.begin();i!=temp.end();i++)debug<<*i<<"\n"; } debug< toKeep=groebnerBasis.multiDeHomogenizationToKeep(); PolynomialSet g1=groebnerBasis.multiDeHomogenization(); PolynomialSet g=g1.homogenization(g1.getRing().withVariablesAppended("H")); // saturatedIdeal(g); buchberger(&g,WeightReverseLexicographicTermOrder(IntegerVector::allOnes(g.getRing().getNumberOfVariables()))); int d=krullDimension(g); debug<<"d="<subvector(0,i->size()-1)-(*i)[i->size()-1]*IntegerVector::allOnes(i->size()-1)); } debug<< "Dehomogenized"<::const_iterator j=toKeep.begin();j!=toKeep.end();j++,J++) v[*j]=(*i)[J]; rays2.push_back(v); } return rays2; } int main() { FileParser P(Stdin); PolynomialSet theInput=P.parsePolynomialSetWithRing(); if(optionParameters.getValue()) theInput=makeVariablesParameters( makeVariablesParameters(theInput.getRing(),optionParameters.getValue()) ,theInput); AsciiPrinter(Stdout).printVectorList(tropicalCurveWithPreprocessing(theInput)); return 0; } }; static TropicalCurveApplication theApplication; gfan0.6.2/src/app_tropicalfunction.cpp0000644000175000017500000000412413122232611017377 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "polyhedralcone.h" #include "polyhedralfan.h" #include "tropical.h" #include "tropical2.h" #include "symmetry.h" #include "halfopencone.h" #include "log.h" #include "field_rationals.h" class TropicalFunctionApplication : public GFanApplication { SimpleOption exponentOption; public: const char *helpText() { return "This program takes a polynomial and tropicalizes it. The output is piecewise linear function represented by a fan whose cones are the linear regions. Each ray of the fan gets the value of the tropical function assigned to it. In other words this program computes the normal fan of the Newton polytope of the input polynomial with additional information."; } TropicalFunctionApplication(): exponentOption("--exponents","Tell program to read a list of exponent vectors instead.") { registerOptions(); } const char *name() { return "_tropicalfunction"; } void inner(PolynomialSet const &f) { PolyhedralFan F=PolyhedralFan::normalFanOfNewtonPolytope(*f.begin()); { AsciiPrinter p(Stdout); PolyhedralFan a=F; a.printWithIndices(&p,FPF_default|FPF_values); } } int main() { FileParser P(Stdin); if(!exponentOption.getValue()) { PolynomialSet f=P.parsePolynomialSetWithRing(); inner(f); } else { IntegerVectorList exponents=P.parseIntegerVectorList(); assert(exponents.size()); int n=exponents.begin()->size(); PolynomialRing R(Q,n); Polynomial p(R); for(IntegerVectorList::const_iterator i=exponents.begin();i!=exponents.end();i++) { p+=Term(Q.zHomomorphism(1),Monomial(R,*i)); } PolynomialSet f(R); f.push_back(p); inner(f); } return 0; } }; static TropicalFunctionApplication theApplication; gfan0.6.2/src/polynomialring.h0000644000175000017500000000456213122232611015672 0ustar andersanders#ifndef POLYNOMIALRING_H_INCLUDED #define POLYNOMIALRING_H_INCLUDED #include #include #include #include "field.h" #include "vektor.h" using namespace std; class PolynomialRingImplementation { public: int refCount; Field theField; int n; vector variableNames; PolynomialRingImplementation(Field const &f, int numberOfVariables, vector const &variableNames_): theField(f), n(numberOfVariables), refCount(0), variableNames(variableNames_) { } }; class PolynomialRing { PolynomialRingImplementation *implementingObject; public: inline int getNumberOfVariables()const{return implementingObject->n;} inline Field const&getField()const{return implementingObject->theField;} /** * Returns a new polynomial ring, the same as *this, except that some variables have been added. * The variables to append are given in a comma separated string. */ PolynomialRing withVariablesAppended(string variableNames)const; PolynomialRing subRing(IntegerVector const &keepVariable, bool getNamesFromOldRing=true)const; int variableIndex(string const &name)const;//returns -1 if no match string const &getVariableName(int i)const; vector getVariableNames()const; /** * Returns a string with comma separated of variable names used for printing. */ string toStringVariableNames()const; class Polynomial one()const; class Polynomial zero()const; class Polynomial monomialFromExponentVector(IntegerVector const &v)const; class Polynomial ithVariable(int i)const; class Polynomial polynomialFromField(FieldElement const &c)const; //construtors PolynomialRing(Field const &f, int numberOfVariables); PolynomialRing(Field const &f, vector const &variables); ~PolynomialRing(); PolynomialRing(PolynomialRing const &a);//copy constructor PolynomialRing& operator=(const PolynomialRing& a);//assignment //comparison -- added in 2016. We for now just test if the implementing objects are the same bool operator==(PolynomialRing const &b)const{return implementingObject==b.implementingObject;} }; vector matrixVariableNames(string base, int height, int width); vector vectorVariableNames(string base, int n); vector subsetVariableNames(string base, int n, int choose, bool M2Convention); int subsetToVariableIndex(set const &s, int n, int choose, bool M2Convention); #endif gfan0.6.2/src/saturation.cpp0000644000175000017500000000765313122232611015357 0ustar andersanders#include "saturation.h" #include "matrix.h" #include "multiplicity.h" #include "buchberger.h" #include "division.h" #include "tropical.h" #include "printer.h" /* #include "substitution.h" PolynomialSet colonIdeal(PolynomialSet const &ideal, polynomial f) { int n=ideal.numberOfVariablesInRing(); IntegerMatrix mat(n+1,n); for(int i=0;iterms.begin();j!=i->terms.end();j++) return j->second; assert(0); return a; } /* * This procedure does not work */ static PolynomialSet singleSaturation(PolynomialSet const &s)//TO DO: call idealIntersection to do the intersection { assert(0); PolynomialRing theRing=s.getRing(); int n=s.numberOfVariablesInRing(); FieldElement one=getFieldElement(s).one(); // add a variable // PolynomialSet s2=s;s2.changeNumberOfVariables(n+1); IntegerVector temp(theRing.getNumberOfVariables()); PolynomialSet s2=s.homogenization(theRing.withVariablesAppended("T"),&temp); /* IntegerMatrix mat(n+1,n); for(int i=0;i #include "polynomialring.h" //#include "linalg.h" #include "term.h" #include "termorder.h" struct TermMapCompare { inline bool operator()(const Monomial &s1, const Monomial &s2) const { return LexicographicTermOrder()(s1.exponent,s2.exponent); } }; typedef std::map TermMap; class Polynomial { Term marked; bool isMarkedBool; int sugar; PolynomialRing theRing; /** * Used for splitting polynomials into two. */ Polynomial half(bool secondHalf)const; public: PolynomialRing const &getRing()const{return theRing;} TermMap terms; FieldElement coefficientOf(IntegerVector const &v)const{assert(v.size()==theRing.getNumberOfVariables());for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++)if(i->first.exponent==v)return i->second;return theRing.getField().zHomomorphism(0);} Polynomial(const Term &t); Polynomial(PolynomialRing const &r); void computeInitialSugar(); int getSugar()const; void madd(const Term &m, const Polynomial &p); void operator+=(const Polynomial &p); void operator-=(const Polynomial &p); friend Polynomial operator+(const Polynomial &p, const Polynomial &q); friend Polynomial operator-(const Polynomial &p, const Polynomial &q); void operator*=(const Term &p); void operator*=(const Monomial &m); void operator*=(FieldElement const &c); void operator*=(Polynomial const &p); friend Polynomial operator*(const Polynomial &p, Term const &t); friend Polynomial operator*(const Polynomial &p, Monomial const &m); friend Polynomial operator*(const Polynomial &p, FieldElement const &c); friend Polynomial operator*(const Polynomial &p, const Polynomial &q); bool divides(const Polynomial &p, Polynomial *result=0)const; bool divides2(const Polynomial &p, Polynomial *result=0)const; Polynomial exactlyDividedBy(const Polynomial &p)const; int getNumberOfVariables()const; void changeNumberOfVariables(PolynomialRing const& r); void mark(class TermOrder const &termOrder); void mark(Monomial const &monomial); /** * Changes the marking of *this to that of p. */ void copyMarking(Polynomial const &p); void scaleMarkedCoefficientToOne(); bool isMonomial() const; const Term &getMarked()const{return marked;} bool isZero()const; bool isOne()const; int numberOfTerms()const;//linear time in worst case! IntegerVector exponentsSum()const; IntegerVectorList exponents()const; IntegerVector greatestCommonMonomialDivisor()const; IntegerVector degreeVector()const; int totalDegree()const; int64 degree(IntegerVector const &w)const;// evaluateTropically Polynomial homogenization(PolynomialRing const &newRing, IntegerVector const *w=0)const; /** Each variable x_i in the polynomial is substituted by w_ix_i. */ Polynomial torusAct(class FieldVector const &w)const; // Polynomial derivative()const;//single variable Polynomial derivative(int j=0)const;//with respect to jth variable Polynomial deHomogenization(PolynomialRing const &r)const; Polynomial deHomogenizationInSameRing()const; int numberOfVariablesInRing()const;//by looking at just one monomial bool checkMarking(TermOrder const &termOrder)const; /** Checks wether the polynomial is homogeneous with respect to the grading given by the vector. */ bool isHomogeneous(IntegerVector const &v)const; bool isHomogeneous()const; void saturate(int variableNum=-1);//default is to saturate with respect to all variables bool isMarked()const; bool isValid(int numberOfVarialbes=-1)const; //debug testing FieldElement evaluate(const FieldElement &x)const;//single variable /** * This routine returns a vector with one entry for each variable in the ring. The entry is 1 * if the variable is used in the polynomial - 0 otherwise. */ IntegerVector usedVariables()const; int maximalIndexOfVariableInSupport()const; /* Creates a polynomial in r2 by extending or truncating the exponent vectors of the current polynomial appropriately. In particular this method can be used for dehomogenization */ Polynomial embeddedInto(PolynomialRing const &r2, list const *chosenVariables=0)const; Polynomial embeddedInto2(PolynomialRing const &r2, vector const &positionOfVariables)const; Polynomial withRestrictedVariables(IntegerVector const &keepVariable, PolynomialRing const &r2)const; Polynomial withExpandedVariables(IntegerVector const &wasKeptVariables, PolynomialRing const &r1)const; /** * Returns the index of the last variable used in this polynomial +1. */ int numberOfVariablesInUseConsecutive()const; string toString(bool latex/*, bool mathMode*/)const; /** * For debugging */ bool checkExponentVectors()const; double evaluateFloat(FloatVector const &x)const; ComplexNumber evaluateComplex(ComplexVector const &x)const; Polynomial withIthVariableSubstituted(PolynomialRing const &r2, int i, FieldElement const &v)const; /** * theRing must be a polynomial ring over the rationals. * r2 must be a polynomial ring with the same number of variables over ZModPZ. * *this must have only integer coefficients. * The returned polynomial is the representative modulo P. */ Polynomial modularRepresentative(PolynomialRing const &r2)const; /** * theRing must be a polynomial ring over ZModPZ. * r2 must be a polynomial ring over rationals. * The returned polynomial is a representative of *this in r2. */ Polynomial integralRepresentative(PolynomialRing const &r2)const; /* Only works for ordered coefficient fields at the moment!!!!!!!!!!!!!!!!!!!!!! * */ bool operator==(Polynomial const &q)const; }; class PolynomialCompare { public: bool operator()(const Polynomial &a, const Polynomial &b)const; }; class PolynomialCompareMarkedTerms { TermOrder const &termOrder; public: PolynomialCompareMarkedTerms(TermOrder const &termOrder_); bool operator()(const Polynomial &a, const Polynomial &b)const; }; class PolynomialCompareMarkedTermsReverse { TermOrder const &termOrder; public: PolynomialCompareMarkedTermsReverse(TermOrder const &termOrder_); bool operator()(const Polynomial &a, const Polynomial &b)const; }; /** * Used for sorting according to number of terms without removing duplicates. */ class PolynomialCompareNumberOfTermsStable { public: bool operator()(const Polynomial &a, const Polynomial &b)const; }; class PolynomialSet : public list { PolynomialRing theRing; public: PolynomialSet(PolynomialRing const &r):theRing(r){} PolynomialRing const &getRing()const { return theRing; } /** * Returns the index of the last variable used in an element of the set +1. */ int numberOfVariablesInUseConsecutive()const; void changeNumberOfVariables(PolynomialRing const &r); int numberOfVariablesInRing()const;//by looking at just one monomial // Field & void scaleMarkedCoefficientsToOne(); void mark(class TermOrder const &termOrder); void markAndScale(TermOrder const &termOrder); /** * Changes the markings of *this to that of g. */ void copyMarkings(PolynomialSet const &g); bool checkMarkings(TermOrder const &termOrder)const; /** The set of vectors inducing the markings of the polynomials in the set is an open polyhedral cone (assuming that the markings are consistent). This function checks if the vector v is contained in the closure of that cone. */ bool containsInClosedGroebnerCone(IntegerVector const &v)const; /** Checks whether the polynomials are homogeneous with respect to the grading given by the vector. */ bool isHomogeneous(IntegerVector const &v)const; bool isHomogeneous()const; void unionPolynomial(const Polynomial &p); void unionSet(const PolynomialSet &s); int totalDegree()const; IntegerVector exponentsSum()const; void sort_(); /** * This routine reorders the polynomials such that polynomials with few terms go first. Duplicates are not removed. */ void simplestPolynomialsFirst(); friend bool operator==(PolynomialSet const &a, PolynomialSet const &b); //remember to call sort_ before calling this procedure bool isEqualTo(PolynomialSet const &b)const; //remember to call sort_ before calling this procedure /** * Assuming that the set is a Groebner basis routine tests if its ideal equals <1>. */ bool isUnitIdeal()const; PolynomialSet markedTermIdeal()const; void computeInitialSugar(); bool isMarked()const; PolynomialSet homogenization(PolynomialRing const &newRing, IntegerVector const *w=0)const; PolynomialSet torusAct(FieldVector const &w)const; /** * This routine computes a homogeneity space of the polynomial set (not the ideal) and based on this * substitutes 1 for certain variables to make polynomial set non-homogeneous in any grading. The returned * ideal sits inside new ring. */ PolynomialSet multiDeHomogenization()const; list multiDeHomogenizationToKeep()const; PolynomialSet deHomogenization()const; PolynomialSet deHomogenizationInSameRing()const; /** * This function intersects the list of polynomials with a subpolynomial ring newRing. * The ring newRing is embedded into the current polynomial ring as the polynomial ring * on the first n variables if the chosenVariables list is not specified. Otherwise it is embedded * as the polynomial ring on the chosenVariables given in the list. */ PolynomialSet polynomialRingIntersection(PolynomialRing const &newRing, list const *chosenVariables=0)const; bool isValid()const; //debug testing /** * Factors out common monomial factors of the elements in the set. This does not saturate the ideal * generated by the polynomials! */ void saturate(int variableNum=-1);//default is to saturate with respect to all variables PolynomialSet embeddedInto(PolynomialRing const &r2, list const *chosenVariables=0)const; PolynomialSet embeddedInto2(PolynomialRing const &r2, vector const &positionsOfVariables)const; // Here are two new functions for moving polynomials between polynomial rings PolynomialSet withRestrictedVariables(IntegerVector const &keepVariable, PolynomialRing const &r2)const; PolynomialSet withExpandedVariables(IntegerVector const &wasKeptVariables, PolynomialRing const &r1)const; int totalNumberOfTerms()const; list exponents()const; FloatVector evaluateFloat(FloatVector const &x)const; ComplexVector evaluateComplex(ComplexVector const &x)const; PolynomialSet withIthVariableSubstituted(PolynomialRing const &r2, int i, FieldElement const &v)const; /** * This function removes all zero polynomials from the set. */ void removeZeros(); /** * This function removes duplicates from the set by first sorting. */ void removeDuplicates(); bool containsMonomialGenerator()const{for(const_iterator i=begin();i!=end();i++)if(i->isMonomial())return true;return false;} /** * theRing must be a polynomial ring over the rationals. * r2 must be a polynomial ring with the same number of variables over ZModPZ. * *this must have only integer coefficients in its polynomials. * The returned polynomial is the representative modulo P. */ PolynomialSet modularRepresentative(PolynomialRing const &r2)const; }; typedef list PolynomialSetList; /*class PolynomialSetList : public list { };*/ #endif gfan0.6.2/src/integergb.cpp0000644000175000017500000002344613122232611015132 0ustar andersanders/* * integergb.cpp * * Created on: Dec 14, 2010 * Author: anders */ #include "integergb.h" #include "polynomial.h" #include "field_rationals.h" #include "printer.h" #include "polyhedralcone.h" #include "wallideal.h" #include "tropical2.h" /* * Implemented according to [Becker, Weispfenning] Chapter 10.1. */ Polynomial dDivision(Polynomial p, PolynomialSet const &l, TermOrder const &termOrder) { PolynomialRing theRing=p.getRing(); Polynomial r(p.getRing()); while(!p.isZero()) { p.mark(termOrder); Term initial=p.getMarked(); PolynomialSet::const_iterator i; PolynomialSet::iterator j; for(i=l.begin();i!=l.end();i++) { if(i->getMarked().m.exponent.divides(initial.m.exponent)) if((initial.c*(i->getMarked().c.inverse())).isInteger())break; } { if(i!=l.end()) { Term s(-initial.c*i->getMarked().c.inverse(),Monomial(p.getRing(),initial.m.exponent-i->getMarked().m.exponent)); p.madd(s,*i); } else { p-=initial; r+=initial; } } } return r; } Polynomial eDivision(Polynomial p, PolynomialSet const &l, TermOrder const &termOrder) { PolynomialRing theRing=p.getRing(); Polynomial r(p.getRing()); // debug<<"eDivision input "<< p<getMarked().m.exponent.divides(initial.m.exponent)) { // debug<<"CHECKING:"<getMarked().c); if(!q.isZero())break; } } { if(i!=l.end()) { // debug<<"dividing by "<<*i<<"\n"; Term s(-integerDivision(initial.c,i->getMarked().c),Monomial(p.getRing(),initial.m.exponent-i->getMarked().m.exponent)); p.madd(s,*i); } else { p-=initial; r+=initial; } } } return r; } static Polynomial sgpol(Polynomial const &g1, Polynomial const &g2, bool s) { PolynomialRing R=g1.getRing(); FieldElement a1=g1.getMarked().c; FieldElement a2=g2.getMarked().c; IntegerVector t1=g1.getMarked().m.exponent; IntegerVector t2=g2.getMarked().m.exponent; FieldElement c1(Q); FieldElement c2(Q); FieldElement g=gcd(a1,a2,c1,c2); FieldElement b1=a2*g.inverse(); FieldElement b2=a1*g.inverse(); IntegerVector s1=max(t1,t2)-t1; IntegerVector s2=max(t1,t2)-t2; /* debug <<"a1 "<getMarked().m.exponent.divides(i->getMarked().m.exponent)) if((j->getMarked().c.inverse()*i->getMarked().c).isInteger()){doDelete=true;break;} if(doDelete) { PolynomialSet::iterator i2=i; i++; F.erase(i2); } else i++; } } void zAutoReduce(PolynomialSet *g, TermOrder const &termOrder) { for(PolynomialSet::iterator i=g->begin();i!=g->end();i++) { // debug<<"1\n"; Polynomial temp(*i); PolynomialSet::iterator tempIterator=i; tempIterator++; g->erase(i); Monomial monomial=temp.getMarked().m; if(temp.getMarked().c.sign()>0) g->insert(tempIterator,eDivision(temp,*g,termOrder)); else g->insert(tempIterator,eDivision(temp.getRing().zero()-temp,*g,termOrder)); tempIterator--; i=tempIterator; if(i->isZero()) { assert(0); } else i->mark(monomial); } } typedef pair Pair; void zBuchberger(PolynomialSet &F, TermOrder const &T) { list B; PolynomialSet G(F.getRing()); for(PolynomialSet::const_iterator i=F.begin();i!=F.end();i++)if(!i->isZero())G.push_back(*i); G.mark(T); for(PolynomialSet::const_iterator i=G.begin();i!=G.end();i++) for(PolynomialSet::const_iterator j=G.begin();j!=i;j++) B.push_back(Pair(*i,*j)); list D; list C=B; while(!B.empty()) { // debug<<"Looping\n"; // debug<getMarked().m.exponent.divides(lcm) && (gi->getMarked().c.inverse()*HCf1).isInteger() && (gi->getMarked().c.inverse()*HCf2).isInteger())break; } if(gi==G.end()) { // debug<getMarked()); Polynomial r=eDivision(lt, groebnerBasis,TOld); Polynomial rIn=eDivision(lt,initialFormsAssumeMarked(groebnerBasis,ridgeVector),TOld); liftedBasis.push_back(lt-r); // debug<<"--------------------\n"; // debug<<"lt:"<0) { ret.push_back(-v); } // debug<<"LINK"< class XfigEnumerationPrinter: public EnumerationFilePrinter { int basisCounter; bool largerTriangle; int variableShift; class XFig *xfig; public: XfigEnumerationPrinter(bool _largerTriangle=false); bool basis(const PolynomialSet &groebnerBasis); string extension(); void beginEnumeration(const PolynomialSet &groebnerBasis); void endEnumeration(); void onOpened(); void onClose(); void onClosed(); void setVariableShift(int shift); }; #endif gfan0.6.2/src/polymakefile.h0000644000175000017500000000471713122232611015312 0ustar andersanders#ifndef POLYMAKEFILE_H_INCLUDED #define POLYMAKEFILE_H_INCLUDED #include #include #include #include #include "matrix.h" using namespace std; class PolymakeProperty { public: std::string value; std::string name; bool embedded; PolymakeProperty(const string &name_, const string &value_, bool embedded_=true); }; class PolymakeFile { static bool xmlForced; string application,type; string fileName; list properties; list::iterator findProperty(const char *p); void writeProperty(const char *p, const string &data, bool embedded=false); bool isXml; public: bool isXmlFormat()const{return isXml;} /** * This function takes the Gfan property names and maps them to the corresponding names in * polymake type SymmetricFan (if the file is an xml file). This preserves compatibility with old * Gfan files. Maybe Gfan should switch completely to polymake names in the future. */ const char *mapToPolymakeNames(const char *s); /** * Calling this function will set the xmlForced flag, with the consequence that every subsequently * created PolymakeFile is output in XML format no matter with what parameters it is created. */ static void forceXml(){xmlForced=true;} void open(const char *fileName_); void create(const char *fileName_, const char *application_, const char *type_, bool isXml_=false); void writeStream(ostream &file); void close(); bool hasProperty(const char *p, bool doAssert=false); // The following could be part of a subclass to avoid dependencies on gfan int readCardinalProperty(const char *p); void writeCardinalProperty(const char *p, int n); bool readBooleanProperty(const char *p); void writeBooleanProperty(const char *p, bool n); IntegerMatrix readMatrixProperty(const char *p, int height, int width); void writeMatrixProperty(const char *p, const IntegerMatrix &m, bool indexed=false, const vector *comments=0); IntegerMatrix readArrayArrayIntProperty(const char *p, int width); void writeArrayArrayIntProperty(const char *p, const IntegerMatrix &m); vector > readMatrixIncidenceProperty(const char *p); void writeIncidenceMatrixProperty(const char *p, const vector > &m, int baseSetSize); IntegerVector readCardinalVectorProperty(const char *p); void writeCardinalVectorProperty(const char *p, IntegerVector const &v); void writeStringProperty(const char *p, const string &s); }; #endif gfan0.6.2/src/app_traversetropicalintersection.cpp0000644000175000017500000000736313122232611022044 0ustar andersanders/* * app_traversetropicalintersection.cpp * * Created on: Jan 4, 2011 * Author: anders */ #include "printer.h" #include "parser.h" #include "gfanapplication.h" #include "division.h" #include "log.h" #include "polyhedralcone.h" #include "tropical2.h" #include "wallideal.h" #include "halfopencone.h" #include "integergb.h" #include using namespace std; class TropicalIntersectionTraverser: public ConeTraverser { PolynomialSet allPolys; PolynomialSet iForms; PolyhedralCone theCone; int n;//,d; int prime; bool collect; IntegerVectorList collection; void updatePolyhedralCone() { theCone=PolyhedralCone(fastNormals(wallInequalities(allPolys)),wallInequalities(iForms),n); theCone.canonicalize(); if(collect) { collection.push_back(theCone.getRelativeInteriorPoint()); int temp=collection.size(); if((temp&(2*(temp-1)))==temp)pout<<"RELINT:\n"<::const_iterator i=l.conesBegin();i!=l.conesEnd();i++) if(!(i->getUniquePoint().isZero()))ret.push_back(i->getUniquePoint()); assert(ret.size()>1); return ret; } PolyhedralCone & refToPolyhedralCone() { return theCone; } }; class TraverseTropicalIntersectionApplication : public GFanApplication { SimpleOption optionSymmetry; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program \n"; } TraverseTropicalIntersectionApplication(): optionSymmetry("--symmetry","Do computations up to symmetry and group the output accordingly. If this option is used the program will read in a list of generators for a symmetry group after the other input.") { registerOptions(); } const char *name() { return "_traversetropicalintersection"; } int main() { FileParser P(Stdin); PolynomialSet a=P.parsePolynomialSetWithRing(); int n=a.getRing().getNumberOfVariables(); IntegerVector omega=P.parseIntegerVector(); { SymmetryGroup G(n); if(optionSymmetry.getValue()) { IntegerVectorList generators=P.parseIntegerVectorList(); G.computeClosure(generators); G.createTrie(); } SymmetricTargetFanBuilder target(n,G); TropicalIntersectionTraverser traverser(a,omega); symmetricTraverse(traverser,target,&G); AsciiPrinter Q(Stdout); target.getFanRef().printWithIndices(&Q, FPF_default); } return 0; } }; static TraverseTropicalIntersectionApplication theApplication; gfan0.6.2/src/matrix.h0000644000175000017500000003167213122232611014135 0ustar andersanders#ifndef MATRIX_H_INCLUDED #define MATRIX_H_INCLUDED #include #include #include #include #include "vektor.h" #include "printer.h" using namespace std; template class Matrix{ //public: int width,height; // vector > rows; vector data; public: inline int getHeight()const{return height;}; inline int getWidth()const{return width;}; Matrix(const Matrix &a):data(a.data),width(a.getWidth()),height(a.getHeight()){ } Matrix(int height_, int width_):data(height_*width_),height(height_),width(width_){ assert(height>=0); assert(width>=0); for(int i=0;i column(int i)const { assert(i>=0); assert(i ret(getHeight()); for(int j=0;j const &r) { assert(r.size()==width); int oldsize=data.size(); data.resize(data.size()+width); for(int i=0;i const &r) { assert(r.size()==width); rows.front_back(r); height++; }*/ void setRow(int i,IntegerVector const &v) { assert(v.size()==getWidth()); assert(i>=0 && isum)sum=a[i][k]+b[k][j]; } ret[i][j]=sum; } return ret; } friend Matrix operator*(const Matrix& a, const Matrix& b) { assert(a.width==b.height); Matrix ret(b.width,a.height); for(int i=0;i Matrix(const Matrix& c):v(c.size()){ for(int i=0;i=0); assert(startColumn>=0); assert(endRow>=startRow); assert(endColumn>=startColumn); assert(endRow<=height); assert(endColumn<=width); Matrix ret(endRow-startRow,endColumn-startColumn); for(int i=startRow;igetWidth()); Matrix ret(getHeight(),subset.sum()); for(int i=0;i=0); assert(j toVector()const { Vektor ret(matrix.width); for(int j=0;j()const { return toVector(); } bool operator==(Vektor const &b)const { return toVector()==b; } typ dot(Vektor const &b)const { return dot(toVector(),b); } Vektor operator-()const { return -toVector(); } /* bool isZero()const { for(int j=0;j=0); assert(j const &v) { assert(v.size()==matrix.width); for(int j=0;j const &v) { assert(v.size()==matrix.width); for(int j=0;j toVector()const { Vektor ret(matrix.width); for(int j=0;j()const { return toVector(); } typ dot(Vektor const &b)const { return dot(toVector(),b); } /* Vector toVector() { Vector ret(matrix.width); for(int j=0;j& operator[](int n)const{assert(n>=0 && n& operator[](int n){assert(n>=0 && n& operator[](int n){if(!(n>=0 && n*)(this))[n];return (rows[n]);} inline RowRef operator[](int i) { assert(i>=0); assert(i=0); assert(i widths(m.getWidth()); for(int i=0;iwidths[j])widths[j]=s.str().length(); } stringstream s; s<<"{"; for(int i=0;i=0); assert(i=0); assert(j=0); assert(i=0); assert(j IntegerMatrix; typedef Matrix FloatMatrix; IntegerMatrix rowsToIntegerMatrix(IntegerVectorList const &rows, int width=-1);//width specifies the matrix width. If no width is specied the width is found by looking at the length of the rows. The function "asserts" if the length of the rows does not match the matrix size or if the width was not specified and could not be read off from the rows. IntegerMatrix rowToIntegerMatrix(IntegerVector const &row); FloatMatrix integerToFloatMatrix(IntegerMatrix const &m); IntegerVector flattenMatrix(IntegerMatrix const &m); int rank(IntegerMatrix const &m); #endif gfan0.6.2/src/linalgfloat.h0000644000175000017500000003027013122232611015116 0ustar andersanders#ifndef LINALGFLOAT_H_INCLUDED #define LINALGFLOAT_H_INCLUDED #include #include #include #include #include #include "matrix.h" #define EPSILON 0.0001 #define typ double namespace linalgfloat { class Vector{ int n; std::vector data; public: Vector(int n_=0): n(n_), data(n_) { for(int i=0;i=0 && n=0 && n=0); assert(end<=size()); assert(end>=begin); Vector ret(end-begin); for(int i=0;iEPSILON)||(data[i]<-EPSILON))return false; return true; } friend class Matrix; }; class Matrix{ int height,width; typ *data; public: static inline bool isZero(typ a){return (a-EPSILON);} class RowRef{ int rowNum; Matrix &matrix; public: inline RowRef(Matrix &matrix_, int rowNum_): rowNum(rowNum_), matrix(matrix_) { } inline typ &operator[](int j) { assert(j>=0); assert(j=0); assert(j=0); assert(i=0); assert(iwidth;int height=this->height; for(int i=0;i=0); assert(i=0); assert(j=0); assert(i=0); assert(i=0); assert(j=0); assert(b>=0); assert(a=height)return false; while(++j=0); assert(startColumn>=0); assert(endRow>=startRow); assert(endColumn>=startColumn); assert(endRow<=height); assert(endColumn<=width); Matrix ret(endRow-startRow,endColumn-startColumn); for(int i=startRow;i>7)+(ret<<25); return ret+(ret>>24)+(ret>>16)+(ret>>8); } #endif bool rowsAreEqual(int row1, int row2, int numberOfEntriesToConsider) { typ *r1=data+row1*width; typ *r2=data+row2*width; for(int i=0;i toCheck; for(int i=0;i::const_iterator j=toCheck.begin();j!=toCheck.end();j++) this->multiplyAndAddRow(*j,-rowDot(i,*j)/rowDot(*j,*j),i);//TODO: rowDot(j,j) is computed repeatedly - fix this if(!(*this)[i].isZero()) { retIndex++; toCheck.push_back(i); } } removeZeroRows(); */ } /* * This method assumes that rows of the matrix are orthonogal and computes * the coefficients of the projection of v onto this basis. */ Vector projectionCoefficients(Vector const &v) { Vector ret(height); for(int i=0;i #include #include "printer.h" #include "parser.h" #include "programs.h" //-------------------------------------------------- // Pipe //-------------------------------------------------- Pipe::Pipe() { int r; r=pipe(fdM2Input); assert(r==0); r=pipe(fdM2Output); assert(r==0); int pid1=fork(); if(pid1==0)//child { fprintf(stderr,"Child\n"); int r; r=dup2(fdM2Input[0],fileno(stdin)); assert(r>=0); r=dup2(fdM2Output[1],fileno(stdout)); assert(r>=0); static char M2Name[1024]; sprintf(M2Name,"%s",programNameM2);//"M2"; char *argv[2]; argv[0]=M2Name; argv[1]=0; execvp(argv[0], argv); assert(0); } else //parent { fprintf(stderr,"Parent\n"); pipeInput=fdopen(fdM2Input[1],"w"); assert(pipeInput); pipeOutput=fdopen(fdM2Output[0],"r"); assert(pipeOutput); } } Pipe::~Pipe() { //fclose? fclose(pipeInput); fclose(pipeOutput); } //-------------------------------------------------- // Macaulay2Pipe //-------------------------------------------------- Macaulay2Pipe::Macaulay2Pipe(): printer(pipeInput) { readLine(); } Macaulay2Pipe::~Macaulay2Pipe() { fprintf(pipeInput,"exit\n"); /* while(!feof(pipeOutput)) { fprintf(stdout,"%c ",(getc(pipeOutput))); } */ } void Macaulay2Pipe::skipStartOfLine() { int c; do { c=fgetc(pipeOutput); if(c==EOF) { fprintf(stderr,"EOF\n"); } // fprintf(stderr,"skipStartOfLine c=\'%c\',%i\n",c,c); } while(c!='='); } char *Macaulay2Pipe::readLine() { static char line[2048]; fgets(line,2048,pipeOutput); assert(line[strlen(line)-1]=='\n'); // fprintf(stderr,"readLine:%s",line); return line; } int Macaulay2Pipe::readInt() { char *line=readLine(); while(*line!=0 && *line!='=')line++; assert(*line!=0); int ret; sscanf(line+1,"%i",&ret); return ret; } bool Macaulay2Pipe::readBool() { char *line=readLine(); while(*line!=0 && *line!='=')line++; assert(*line!=0); int ret; return 'f'!=line[2]; } int Macaulay2Pipe::getPdimCokerGensMonomial(gbasis const &monomialIdeal) { fprintf(pipeInput,"pdim coker gens monomialIdeal "); printer.printMonomialIdeal(monomialIdeal); fprintf(pipeInput,"\n"); fflush(pipeInput); readLine(); readLine(); int pdim=readInt(); readLine(); return pdim; } bool Macaulay2Pipe::isHomogeneousIdeal(gbasis &ideal) { fprintf(pipeInput,"isHomogeneous ideal "); printer.printGroebnerBasis(ideal); fprintf(pipeInput,"\n"); fflush(pipeInput); readLine(); readLine(); int pdim=readBool(); readLine(); return pdim; } void Macaulay2Pipe::setPolynomialRing(int numberOfVariables) { fprintf(pipeInput,"R = ZZ/32003["); if(numberOfVariables>26) { fprintf(stderr,"Variable index out of range!\n"); assert(0); } for(int i=0;isize()); } StandardPairList Macaulay2Pipe::standardPairs(gbasis &monomialIdeal) { assert(monomialIdeal.begin()!=monomialIdeal.end()); StandardPairList s; setPolynomialRing(monomialIdeal); fprintf(pipeInput,"toString standardPairs monomialIdeal "); printer.printMonomialIdeal(monomialIdeal); fprintf(pipeInput,"\n"); fflush(pipeInput); skipStartOfLine(); // skipStartOfLine(); return FileParser(pipeOutput).parseStandardPairList(monomialIdeal.begin()->size()); } gfan0.6.2/src/scarf.h0000644000175000017500000000146613122232611013725 0ustar andersanders#ifndef SCARF_H_INCLUDED #define SCARF_H_INCLUDED #include "matrix.h" IntegerVectorList neighbours(IntegerMatrix const &A); bool satisfiesA1(IntegerMatrix const &A); bool satisfiesA2(IntegerMatrix const &A); bool satisfiesA3(IntegerMatrix const &A, IntegerVectorList const *N=0); /** Checks Scarf's genericity condition for jth row of the matrix A*/ bool satisfiesA3i(IntegerMatrix const &A, int j, IntegerVectorList const *N=0); IntegerVectorList orientedNeighbours(IntegerVectorList const& N, IntegerVector const &v); IntegerVector kFlip(IntegerMatrix const &A, IntegerMatrix const &N, IntegerVector simplex, int vertex); void traverseScarfComplex(IntegerMatrix const &A, IntegerMatrix const &N, IntegerVector simplex); IntegerVector computeMaximalScarfSimplex(IntegerMatrix const &A, IntegerMatrix const &N); #endif gfan0.6.2/src/gfanlib_symmetry.h0000644000175000017500000001017513122232611016177 0ustar andersanders/* * gfan_symmetry.h * * Created on: Oct 22, 2010 * Author: anders */ #ifndef GFANLIB_SYMMETRY_H_INCLUDED #define GFANLIB_SYMMETRY_H_INCLUDED #include #include "gfanlib_vector.h" #include "gfanlib_matrix.h" namespace gfan{ /** * The permutation class represents an element in the symmetric group S_n. */ class Permutation:public IntVector { // IntVector data; public: /** * Returns true if a contains the elements from 0 up to a.size()-1. */ static bool isPermutation(IntVector const &a); /** * Returns true if all rows of the matrix contains the elements 0 up to m.getWidth()-1. */ static bool arePermutations(IntMatrix const &m); /** * Generates the identity permutation on n elements. */ Permutation(int n): IntVector(n) { for(int i=0;i ElementContainer; ElementContainer elements;//Make this private int size()const { return elements.size(); } int sizeOfBaseSet()const; /** The set of vectors which cannot be improved lexicographically by applying an element from the group is a convex set. Its closure is a polyhedral cone. This routine returns a set of inequalities The returned list does not contain the zero vector. */ ZMatrix fundamentalDomainInequalities()const; SymmetryGroup(int n); void computeClosure(Permutation const &v); void computeClosure(IntMatrix const &l); IntMatrix getGenerators()const; int orbitSize(ZVector const &stable)const; bool isTrivial()const; /** The symmetry group acts on vectors by permuting the entries. The following routine returns a unique representative for the orbit containing v. This makes it easy to check if two elements are in the same orbit. The permutation used to get this representative is stored in *usedPermutation (if pointer not 0). */ ZVector orbitRepresentative(ZVector const &v, Permutation *usedPermutation=0)const; /** This routine works as orbitRepresentative() except that the symmetry group considered is only the subgroup keeping the vector fixed fixed. */ ZVector orbitRepresentativeFixing(ZVector const &v, ZVector const &fixed)const; // Methods for highly optimized symmetry group computations: void createTrie(); }; /** * Sorts v and returns the number of swaps performed. */ int mergeSort(IntVector &v); } #endif /* GFAN_SYMMETRY_H_ */ gfan0.6.2/src/app_render.cpp0000644000175000017500000000405113122232611015272 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "renderer.h" #include "xfig.h" #include class RenderApplication : public GFanApplication { SimpleOption optionLargerTriangle; IntegerOption optionShiftVariablesWhenDrawing; public: const char *helpText() { return "This program renders a Groebner fan as an xfig file. To be more precise, the input is the list of all reduced Groebner bases of an ideal. The output is a drawing of the Groebner fan intersected with a triangle. The corners of the triangle are (1,0,0) to the right, (0,1,0) to the left and (0,0,1) at the top. If there are more than three variables in the ring these coordinates are extended with zeros. It is possible to shift the 1 entry cyclic with the option --shiftVariables.\n"; } RenderApplication(): optionLargerTriangle("-L", "Make the triangle larger so that the shape of the Groebner region appears."), optionShiftVariablesWhenDrawing("--shiftVariables", "Shift the positions of the variables in the drawing. For example with the value equal to 1 the corners will be right: (0,1,0,0,...), left: (0,0,1,0,...) and top: (0,0,0,1,...). The shifting is done modulo the number of variables in the polynomial ring. The default value is 0.") { registerOptions(); } const char *name() { return "_render"; } int main() { FileParser P(Stdin); PolynomialSetList l; l=P.parsePolynomialSetListWithRing(); XfigEnumerationPrinter ep(optionLargerTriangle.getValue()); ep.setVariableShift(optionShiftVariablesWhenDrawing.getValue()); ep.open(Stdout); if(l.size()) { ep.beginEnumeration(*l.begin()); for(PolynomialSetList::const_iterator i=l.begin();i!=l.end();i++)ep.basis(*i); ep.endEnumeration(); } ep.close(); return 0; } }; static RenderApplication theApplication; gfan0.6.2/src/app_polytopealgebra.cpp0000644000175000017500000001105113122232611017202 0ustar andersanders/* * app_polytopealgebra.cpp * * Created on: Nov 30, 2011 * Author: anders */ #include #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "breadthfirstsearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "polyhedralfan.h" #include "minkowskidual.h" #include "log.h" #include "tropical_weildivisor.h" #include "field_rationals.h" #include "linalg.h" class PolytopeAlgebraApplication : public GFanApplication { public: bool includeInDefaultInstallation() // Not included since the program has not been documented and is likely not working. { return false; } const char *helpText() { return "This does some experimental computations in the polytope algebra.\n"; } PolytopeAlgebraApplication() { registerOptions(); } const char *name() { return "_polytopealgebra"; } PolyhedralFan simpleRationalFunction(PolyhedralFan const &support, IntegerVector const &withValueOne) { //D(withValueOne); int n=support.getAmbientDimension(); PolyhedralFan ret(n); for(PolyhedralFan::coneIterator i=support.conesBegin();i!=support.conesEnd();i++) if(!i->contains(withValueOne)) { PolyhedralCone temp(*i); temp.setLinearForm(IntegerVector(n)); ret.insert(temp); } else { PolyhedralCone temp(*i); IntegerVectorList rays=i->extremeRays(); IntegerVectorList lines=i->generatorsOfLinealitySpace(); FieldMatrix LFA(Q,lines.size()+rays.size(),n); FieldVector LFB(Q,lines.size()+rays.size()+n); int J=0; for(IntegerVectorList::const_iterator j=rays.begin();j!=rays.end();j++,J++) { LFA[J]=integerVectorToFieldVector(*j,Q); LFB[J]=Q.zHomomorphism((*j-withValueOne).isZero()*120); } // D(LFA); // D(LFB); FieldVector LFX=LFA.solver().canonicalize(LFB); if(LFX.subvector(0,LFX.size()-n).isZero()) { temp.setLinearForm(fieldVectorToIntegerVector(LFX.subvector(LFX.size()-n,LFX.size()))); // D(temp.getLinearForm()); } else { cerr<<"Values on cone are not linear" <> // product.printWithIndices(&debug,FPF_multiplicities|FPF_default); IntegerVector generator(E.getWidth()); int K=0; for(PolyhedralFan::coneIterator k=a.conesBegin();k!=a.conesEnd();k++,K++) { if(product.containsInSupport(k->getRelativeInteriorPoint())) generator[K]=product.coneContaining(k->getRelativeInteriorPoint()).getMultiplicity(); } generators.push_back(generator); } IntegerMatrix F=rowsToIntegerMatrix(generators,E.getWidth()); pout< #include "buchberger.h" #include "groebnerengine.h" #include "tropical.h" #include "tropical2.h" #include "division.h" #include "wallideal.h" #include "halfopencone.h" #include "log.h" #include "timer.h" static Timer iterativeTropicalBasisTimer("Iterative tropical basis",1); typedef set IntegerVectorSet; static Polynomial cleverSaturation(Polynomial const &p, IntegerVector const &w) { PolynomialRing theRing=p.getRing(); if(p.isZero())return p; if(w.size()==0)return p; Polynomial f=initialForm(p,w); debug<<"P:"<getRing().withVariablesAppended("Z"); PolynomialSet sPolynomials(theRing); for(PolynomialSet::const_iterator i=g->begin();i!=g->end();i++) if(!i->isZero())sPolynomials.push_back(cleverSaturation(i->embeddedInto(theRing),w)); // It is safe and useful to ignore the 0 polynomial sPolynomials.push_back(theRing.monomialFromExponentVector(IntegerVector::allOnes(theRing.getNumberOfVariables()))-theRing.one()); sPolynomials.saturate(); sPolynomials.markAndScale(termOrder); *g=PolynomialSet(theRing); while(!sPolynomials.empty()) { Polynomial p=*sPolynomials.begin(); sPolynomials.pop_front(); p=division(p,*g,termOrder); if(!p.isZero()) { p=cleverSaturation(p,w); p.mark(termOrder); p.scaleMarkedCoefficientToOne(); bool isMonomial=p.isMonomial(); for(PolynomialSet::const_iterator i=g->begin();i!=g->end();i++) if((!isMonomial) || (!i->isMonomial())) // 2 % speed up! { if(!relativelyPrime(i->getMarked().m.exponent,p.getMarked().m.exponent)) { Polynomial s=sPolynomial(*i,p); s.mark(termOrder); // with respect to some termorder s.scaleMarkedCoefficientToOne(); sPolynomials.push_back(s); } } g->push_back(p); { static int t; t++; // if((t&31)==0)fprintf(Stderr," gsize %i spolys:%i\n",g->size(),sPolynomials.size()); } } } minimize(g); autoReduce(g,termOrder); } PolynomialSet tropicalBasisOfCurve(int n, PolynomialSet g, PolyhedralFan *intersectionFan, int linealitySpaceDimension) //Assuming g is homogeneous { /* * TODO: Introduce the notion of a tropical prebasis: * * Definition. A set of polynomials f_1,...,f_m is called a tropical prebasis for the ideal they * generate if for every w not in the tropical variety of that ideal there exists a monomial in * the ideal generated by the initial forms of f_1,...,f_m w.r.t. w. * * Computing a tropical prebasis could be faster than computing a tropical basis since fewer * groebner bases for the originial ideal might be needed. Still, however, it is relatively easy * to determine the tropical variety given a tropical prebasis. */ PolynomialSet originalG=g; // bool prebasis=true; // debug<<"PREBASIS="<0 || n==0); TimerScope ts(&iterativeTropicalBasisTimer); PolyhedralFan f(n); if(!intersectionFan)intersectionFan=&f; // *intersectionFan=tropicalPrincipalIntersection(n,g,linealitySpaceDimension); // log1 fprintf(Stderr,"WARINING USING EXPERIMENTAL TROPICAL HYPERSURFACE INTERSECTION ROUTINE!!\n"); *intersectionFan=tropicalHyperSurfaceIntersectionClosed(n, g); IntegerVectorSet containsNoMonomialCache; while(1) { PolyhedralFan::coneIterator i; // {AsciiPrinter P(Stderr);intersectionFan->printWithIndices(&P);} restart: // {AsciiPrinter P(Stderr);intersectionFan->printWithIndices(&P);} for(i=intersectionFan->conesBegin();i!=intersectionFan->conesEnd();i++) { // log1 cerr<<"!@#$"; IntegerVector relativeInteriorPoint=i->getRelativeInteriorPoint(); // log1 cerr<<"1234/n"; if(containsNoMonomialCache.count(relativeInteriorPoint)>0) { log2 fprintf(Stderr,"Weight vector found in cache.... contains no monomial.\n"); } else { /* if(prebasis) { if(containsMonomial(initialForms(g,relativeInteriorPoint))) { intersectionFan->insertFacetsOfCone(*i); intersectionFan->remove(*i); debug<<"LOWERING DIMENSION OF CONE\n";//TODO: checking cones in order of dimension could avoid this. goto restart; } }*/ WeightReverseLexicographicTermOrder t(relativeInteriorPoint); log2 fprintf(Stderr,"Computing Gr\"obner basis with respect to:"); log2 AsciiPrinter(Stderr).printVector(relativeInteriorPoint); log2 fprintf(Stderr,"\n"); PolynomialSet h2=originalG;//g;//<------------------- Using the original set here speeds up things a lot in the starting cone via stable intersections algorithm // debug<<"g"<dimension()<=1+homog) //if(!containsMonomial(wall) && i->dimension()<=1+homog)//line for testing perturbation code { log2 fprintf(Stderr,"Initial ideal contains no monomial... caching weight vector.\n"); containsNoMonomialCache.insert(relativeInteriorPoint); } else { /* We need to compute the initial ideal with respect to "relativeInteriorPoint" perturbed with a basis of the span of the cone. Instead of perturbing we may as well compute initial ideal successively. We have already computed the initial ideal with respect to "relativeInteriorPoint". To get the perturbed initial ideal we take initial ideal with respect to each vector in the basis of the span.*/ IntegerVectorList empty; PolyhedralCone dual=PolyhedralCone(empty,i->getEquations(),i->ambientDimension()).dualCone(); dual.canonicalize(); IntegerVectorList basis=dual.getEquations(); PolynomialSet witnessLiftBasis=h2;//basis with respect to relativeInteriorPoint log2 debug<<"basis"<conesEnd())break; } log2 debug<<"TropicalBasis end\n"; log2 cerr <<"RETURNING"; return g; } /* PolynomialSet iterativeTropicalBasisNoPerturbation(int n, PolynomialSet g, PolyhedralFan *intersectionFan, int linealitySpaceDimension, bool doPrint) //Assuming g is homogeneous { TimerScope ts(&iterativeTropicalBasisTimer); PolyhedralFan f(n); if(!intersectionFan)intersectionFan=&f; *intersectionFan=tropicalPrincipalIntersection(n,g,linealitySpaceDimension); IntegerVectorSet containsNoMonomialCache; while(1) { // AsciiPrinter(Stderr).printPolyhedralFan(*intersectionFan); // assert(f.getMaxDimension()==1); IntegerVectorList l=intersectionFan->getRelativeInteriorPoints(); IntegerVectorList::const_iterator i; for(i=l.begin();i!=l.end();i++) { if(containsNoMonomialCache.count(*i)>0) { if(doPrint)fprintf(Stderr,"Weight vector found in cache.... contains no monomial.\n"); } else { WeightReverseLexicographicTermOrder t(*i); if(doPrint)fprintf(Stderr,"Computing Gr\"obner basis with respect to:"); if(doPrint)AsciiPrinter(Stderr).printVector(*i); if(doPrint)fprintf(Stderr,"\n"); PolynomialSet h2=g; buchberger(&h2,t); if(doPrint)fprintf(Stderr,"Done computing Gr\"obner basis.\n"); // AsciiPrinter(Stderr).printPolynomialSet(h2); PolynomialSet wall=initialFormsAssumeMarked(h2,*i); //fprintf(Stderr,"Wall ideal:\n"); //AsciiPrinter(Stderr).printPolynomialSet(wall); if(containsMonomial(wall)) { if(doPrint)fprintf(Stderr,"Initial ideal contains a monomial.\n"); Polynomial m(computeTermInIdeal(wall)); if(doPrint)fprintf(Stderr,"Done computing term in ideal\n"); Polynomial temp=m-division(m,h2,LexicographicTermOrder()); g.push_back(temp); if(doPrint)fprintf(Stderr,"Adding element to basis:\n"); if(doPrint)AsciiPrinter(Stderr).printPolynomial(temp); if(doPrint)fprintf(Stderr,"\n"); *intersectionFan=refinement(*intersectionFan,PolyhedralFan::bergmanOfPrincipalIdeal(temp),linealitySpaceDimension,true); break; } else { if(doPrint)fprintf(Stderr,"Initial ideal contains no monomial... caching weight vector.\n"); containsNoMonomialCache.insert(*i); } } } if(i==l.end())break; } return g; } */ gfan0.6.2/src/halfopencone.backup.cpp0000644000175000017500000007056613122232611017076 0ustar andersanders#include "halfopencone.h" #include "buchberger.h" #include "enumeration.h" #include "reversesearch.h" #include "wallideal.h" #include "printer.h" #include "parser.h" #include "lp.h" static void printHalfOpenCone(Printer &P, HalfOpenCone c) { P.printPolyhedralCone(c.closure()); } static void printHalfOpenConeList(Printer &P, HalfOpenConeList const &l) { P.printString("Begin HalfOpenConeList\n"); for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) printHalfOpenCone(P,*i); P.printString("End HalfOpenConeList\n"); } bool HalfOpenCone::contains(IntegerVector const &v)const { IntegerVectorList inequalityList=lifted.getHalfSpaces(); IntegerVectorList equationList=lifted.getLinealitySpace(); IntegerVectorList strict,nonstrict; for(IntegerVectorList::const_iterator i=inequalityList.begin();i!=inequalityList.end();i++) if((*i)[i->size()-1]<0) strict.push_back(*i); else if((*i)[i->size()-1]==0) nonstrict.push_back(*i); else {//CHANGED assert(i->subvector(0,i->size()-1).isZero()); strict.push_back(*i); } for(IntegerVectorList::const_iterator i=equationList.begin();i!=equationList.end();i++) if(dotLong(i->subvector(0,i->size()-1),v)!=0)return false; for(IntegerVectorList::const_iterator i=nonstrict.begin();i!=nonstrict.end();i++) if(dotLong(i->subvector(0,i->size()-1),v)<0)return false; for(IntegerVectorList::const_iterator i=strict.begin();i!=strict.end();i++) if(dotLong(i->subvector(0,i->size()-1),v)<=0)return false; return true; } void HalfOpenCone::appendList(IntegerVectorList &to, IntegerVectorList const &from, int appendValue) { for(IntegerVectorList::const_iterator i=from.begin();i!=from.end();i++) { IntegerVector v=*i; v.resize(v.size()+1); v[v.size()-1]=appendValue; to.push_back(v); } } HalfOpenCone::HalfOpenCone(int dimension_, PolyhedralCone const &lifted_): dimension(dimension_), liftedDimension(dimension_+1), lifted(lifted_) { // lifted.findFacets(); } HalfOpenCone::HalfOpenCone(int dimension_, IntegerVectorList const &equations, IntegerVectorList const &nonstrict, IntegerVectorList const &strict, bool findFacets): dimension(dimension_), liftedDimension(dimension_+1), lifted(dimension_+1) { IntegerVectorList equationList,inequalityList; appendList(equationList,equations,0); appendList(inequalityList,nonstrict,0); appendList(inequalityList,strict,-1); inequalityList.push_back(IntegerVector::standardVector(liftedDimension,dimension)); //CHANGED // AsciiPrinter(Stderr).printVectorList(inequalityList); // AsciiPrinter(Stderr).printVectorList(equationList); // AsciiPrinter(Stderr).printInteger(liftedDimension); lifted=PolyhedralCone(inequalityList,equationList,liftedDimension); if(findFacets)lifted.findFacets(); } static IntegerVectorList swapFirstLast(const IntegerVectorList &l) { IntegerVectorList ret; for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { IntegerVector v=*i; int t=v[0]; v[0]=v[v.size()-1]; v[v.size()-1]=t; ret.push_back(v); } return ret; } bool HalfOpenCone::isEmpty() { bool ret1=!hasHomogeneousSolution(liftedDimension, swapFirstLast(lifted.getHalfSpaces()), swapFirstLast(lifted.getLinealitySpace()) ); /* IntegerVectorList inequalityList; inequalityList.push_back(IntegerVector::standardVector(liftedDimension,dimension)); PolyhedralCone temp=intersection(lifted,PolyhedralCone(inequalityList,IntegerVectorList(),liftedDimension)); IntegerVector v=temp.getRelativeInteriorPoint(); // AsciiPrinter(Stderr).printVector(v); bool ret2=(v[dimension]==0); */ /* fprintf(Stderr,"Inequalities:\n"); AsciiPrinter(Stderr).printVectorList(lifted.getHalfSpaces()); fprintf(Stderr,"Equations:\n"); AsciiPrinter(Stderr).printVectorList(lifted.getLinealitySpace()); fprintf(Stderr,"hasSolution=%i\n",ret1); */ // assert(ret1==ret2); return ret1; } bool haveEmptyIntersection(const HalfOpenCone &a, const HalfOpenCone &b) { assert(a.dimension==b.dimension); IntegerVectorList inequalityList=a.lifted.getHalfSpaces(); IntegerVectorList equationList=a.lifted.getLinealitySpace(); IntegerVectorList inequalityList2=b.lifted.getHalfSpaces(); IntegerVectorList equationList2=b.lifted.getLinealitySpace(); inequalityList.splice(inequalityList.begin(),inequalityList2); equationList.splice(equationList.begin(),equationList2); bool ret1=!hasHomogeneousSolution(a.liftedDimension,swapFirstLast(inequalityList),swapFirstLast(equationList)); /* HalfOpenCone c=intersection(a,b); if(c.isEmpty()!=ret1) { AsciiPrinter(Stderr).printVectorList(inequalityList); AsciiPrinter(Stderr).printVectorList(equationList); AsciiPrinter(Stderr).printVectorList(c.lifted.getHalfSpaces()); AsciiPrinter(Stderr).printVectorList(c.lifted.getLinealitySpace()); fprintf(Stderr,"hasHomogeneousSolution siger %i\n",!ret1); assert(0); } */ return ret1; } /*bool HalfOpenCone::isEmpty() { IntegerVector v(liftedDimension); v[dimension]=-1; IntegerVectorList equationList,inequalityList; inequalityList.push_back(v); PolyhedralCone c(inequalityList,equationList,liftedDimension); PolyhedralCone c2=intersection(c,lifted); lifted.canonicalize(); c2.canonicalize(); return !(c2!=lifted); }*/ HalfOpenCone intersection(const HalfOpenCone &a, const HalfOpenCone &b, bool findFacets) { assert(a.dimension==b.dimension); /* fprintf(Stderr,"-----------------------------------------------------------\n"); fprintf(Stderr,"Intersecting:\n"); AsciiPrinter P(Stderr); printHalfOpenCone(P,a); printHalfOpenCone(P,b); */ HalfOpenCone ret=HalfOpenCone(a.dimension,intersection(a.lifted,b.lifted)); { static int t; t++; if(!(t&7))ret.lifted.findFacets(); //1 4:53 //3 3:38 //7 } /* fprintf(Stderr,"Result:\n"); printHalfOpenCone(P,ret); fprintf(Stderr,"Is empty:%i\n",ret.isEmpty()); fprintf(Stderr,"-----------------------------------------------------------\n"); fprintf(Stderr,"States: %i,%i,%i\n",a.lifted.getState(),b.lifted.getState(),ret.lifted.getState()); fprintf(Stderr,"-----------------------------------------------------------\n"); */ return ret; } IntegerVectorList HalfOpenCone::shrink(const IntegerVectorList &l) { IntegerVectorList ret; for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) ret.push_back(i->subvector(0,i->size()-1)); return ret; } PolyhedralCone HalfOpenCone::closure() { lifted.findFacets(); return PolyhedralCone(shrink(lifted.getHalfSpaces()),shrink(lifted.getLinealitySpace()),dimension); } /* */ HalfOpenConeList orientedBoundary(PolyhedralCone C, TermOrder const &t) { int dimension=C.ambientDimension(); HalfOpenConeList ret; C.findFacets(); assert(C.dimension()==C.ambientDimension()); IntegerVectorList facets=C.getHalfSpaces(); IntegerVectorList strictList,nonStrictList; for(IntegerVectorList::const_iterator i=facets.begin();i!=facets.end();i++) { if(t(*i,*i-*i)) strictList.push_back(*i); else nonStrictList.push_back(*i); } // Let's make the non-strict inequalities strict one at a time and add a cone for each iteration while(!nonStrictList.empty()) { IntegerVector v=nonStrictList.front(); nonStrictList.pop_front(); IntegerVectorList equationList; equationList.push_back(v); ret.push_back(HalfOpenCone(dimension,equationList,nonStrictList,strictList,true)); strictList.push_back(v); } return ret; } HalfOpenConeList tropicalHyperSurface(Polynomial const &p1) { Polynomial p=p1.homogenization(); HalfOpenConeList ret; PolynomialSet g; g.push_back(p); buchberger(&g,LexicographicTermOrder()); EnumerationTargetCollector gfan; LexicographicTermOrder myTermOrder; ReverseSearch rs(myTermOrder); rs.setEnumerationTarget(&gfan); fprintf(Stderr,"Starting enumeratioin\n"); rs.enumerate(g); fprintf(Stderr,"Done\n"); PolynomialSetList theList=gfan.getList(); for(PolynomialSetList::const_iterator i=theList.begin();i!=theList.end();i++) { HalfOpenConeList temp=orientedBoundary(groebnerCone(i->deHomogenization(),false),myTermOrder); ret.splice(ret.begin(),temp); } // AsciiPrinter P(Stderr); // printHalfOpenConeList(P,ret); return ret; } HalfOpenConeList refinement(HalfOpenConeList const &a, HalfOpenConeList const &b) { HalfOpenConeList ret; for(HalfOpenConeList::const_iterator i=a.begin();i!=a.end();i++) for(HalfOpenConeList::const_iterator j=b.begin();j!=b.end();j++) if(!haveEmptyIntersection(*i,*j)) { HalfOpenCone c=intersection(*i,*j); // c.isEmpty(); // c.isEmpty(); // if(!c.isEmpty()) ret.push_back(c); } return ret; } HalfOpenConeList tropicalHyperSurfaceIntersection2(int dimension, PolynomialSet const &g) { HalfOpenConeList intersection; intersection.push_back(HalfOpenCone(dimension,IntegerVectorList(),IntegerVectorList(),IntegerVectorList())); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { HalfOpenConeList surface=tropicalHyperSurface(*i); fprintf(Stderr,"Number of cones in current intersection:%i\n",intersection.size()); fprintf(Stderr,"Number of cones in next surface:%i\n",surface.size()); fprintf(Stderr,"A\n"); intersection=refinement(intersection,surface); fprintf(Stderr,"B\n"); } fprintf(Stderr,"%i",intersection.size()); return intersection; } PolyhedralFan tropicalHyperSurfaceIntersectionClosed(int dimension, PolynomialSet const &g) { HalfOpenConeList intersection=tropicalHyperSurfaceIntersection(dimension,g); AsciiPrinter P(Stderr); printHalfOpenConeList(intersection, P); PolyhedralFan ret(dimension); for(HalfOpenConeList::iterator i=intersection.begin();i!=intersection.end();i++) { PolyhedralCone c=i->closure(); c.canonicalize(); ret.insert(c); } return ret; } void HalfOpenCone::splitIntoRelativelyOpenCones(list &l) { // fprintf(Stderr,"BEGIN\n"); // AsciiPrinter P(Stderr); // print(P); lifted.findFacets(); // print(P); /* { IntegerVector v=StringParser("(3,0,3,2,0,3)").parseIntegerVector(); if(contains(v))fprintf(stderr,"??????????????????????????????????????????\n"); }*/ IntegerVectorList inequalityList=lifted.getHalfSpaces(); IntegerVectorList equationList=lifted.getLinealitySpace(); IntegerVectorList strict,nonstrict; for(IntegerVectorList::const_iterator i=inequalityList.begin();i!=inequalityList.end();i++) if((*i)[i->size()-1]<0) strict.push_back(*i); else if((*i)[i->size()-1]==0) nonstrict.push_back(*i); else {//CHANGED assert(i->subvector(0,i->size()-1).isZero()); strict.push_back(*i); } // AsciiPrinter(Stderr).printVectorList(nonstrict); // AsciiPrinter(Stderr).printVectorList(strict); // AsciiPrinter(Stderr).printVectorList(equationList); if(nonstrict.size()==0) { l.push_back(*this); } else { IntegerVector chosen=*nonstrict.begin(); nonstrict.pop_front(); strict.push_front(chosen); (*strict.begin())[strict.begin()->size()-1]=-1; IntegerVectorList a=nonstrict; IntegerVectorList tempa=strict; a.splice(a.begin(),tempa); // fprintf(Stderr,"New inequalities:\n"); // AsciiPrinter(Stderr).printVectorList(a); HalfOpenCone A(dimension,PolyhedralCone(a,equationList,liftedDimension)); A.splitIntoRelativelyOpenCones(l); equationList.push_front(chosen); strict.pop_front(); IntegerVectorList b=nonstrict; IntegerVectorList tempb=strict; b.splice(b.begin(),tempb); // fprintf(Stderr,"New inequalities:\n"); // AsciiPrinter(Stderr).printVectorList(b); // fprintf(Stderr,"New equationList:\n"); // AsciiPrinter(Stderr).printVectorList(equationList); HalfOpenCone B(dimension,PolyhedralCone(b,equationList,liftedDimension)); B.splitIntoRelativelyOpenCones(l); } // AsciiPrinter(Stderr).print // fprintf(Stderr,"END\n"); } void HalfOpenCone::print(class Printer &p)const { p.printString("Printing HalfOpenCone\n"); lifted.print(&p); p.printString("Done printing HalfOpenCone\n"); } HalfOpenConeList splitIntoRelativelyOpenCones(HalfOpenConeList const &l) { AsciiPrinter P(Stderr); HalfOpenConeList ret; for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) { fprintf(Stderr,"A"); HalfOpenCone temp=*i; HalfOpenConeList tempSplit; // fprintf(Stderr,"---------------------------------------------------------------\n"); // temp.print(P); // fprintf(Stderr,"---------------------------------------------------------------\n"); temp.splitIntoRelativelyOpenCones(tempSplit); // fprintf(Stderr,"Splits into:"); // for(HalfOpenConeList::const_iterator i=tempSplit.begin();i!=tempSplit.end();i++) // i->print(P); // fprintf(Stderr,"Splits into End."); ret.splice(ret.begin(),tempSplit); fprintf(Stderr,"B\n"); } return ret; } static bool isSubsetOf(IntegerVector const &v, IntegerVector const &u) { for(int i=0;i cones; for(HalfOpenConeList::iterator i=L.begin();i!=L.end();i++) cones.push_back(i->closure()); int homog=1000000; int largest=0; int ambientDimension=-1; for(list::const_iterator i=cones.begin();i!=cones.end();i++) { if(i->dimension()dimension(); if(i->dimension()>largest)largest=i->dimension(); ambientDimension=i->ambientDimension(); } assert(homog!=1000000); for(list::const_iterator i=cones.begin();i!=cones.end();i++) { assert(i->dimensionOfLargestContainedSubspace()==homog); } fprintf(stderr,"Ambient dimension: %i, maximal dimension: %i, dimension of lineality space: %i\n",ambientDimension,largest,homog); IntegerVectorList rays; for(list::iterator i=cones.begin();i!=cones.end();i++) if(i->dimension()==homog+1)rays.push_back(i->getRelativeInteriorPoint()); p.printString("Rays:\n"); p.printVectorList(rays,true); list subsets; for(int d=homog;d<=largest;d++) { IntegerVectorList thisDimension; list cones2; for(list::iterator i=cones.begin();i!=cones.end();i++) if(i->dimension()==d) cones2.push_back(*i); for(list::const_iterator i=cones2.begin();i!=cones2.end();i++) { IntegerVector v(0); int J=0; for(IntegerVectorList::const_iterator j=rays.begin();j!=rays.end();j++) { if(i->contains(*j)) { v.grow(v.size()+1); v[v.size()-1]=J; } J++; } thisDimension.push_back(v); } subsets.push_back(thisDimension); } list::const_iterator subsetIterator=subsets.begin(); list::const_iterator subsetIteratorNext=subsets.begin(); for(int d=homog;d<=largest;d++) { subsetIteratorNext++; IntegerVectorList maximal,nonmaximal; if(subsetIteratorNext!=subsets.end()) { for(IntegerVectorList::const_iterator i=subsetIterator->begin();i!=subsetIterator->end();i++) if(isSubsetOf(*i,*subsetIteratorNext)) nonmaximal.push_back(*i); else maximal.push_back(*i); } else maximal=*subsetIterator; p.printString("Printing ");p.printInteger(subsetIterator->size());p.printString(" ");p.printInteger(d);p.printString("-dimensional cones (");p.printInteger(maximal.size());p.printString(" maximal cones):\n"); p.printString("{"); { bool first=true; for(IntegerVectorList::const_iterator i=maximal.begin();i!=maximal.end();i++) { if(!first)p.printString(",\n"); p.printVector(*i); first=false; } if(!first && nonmaximal.size()!=0)p.printString(",\n"); p.printString("\n"); first=true; for(IntegerVectorList::const_iterator i=nonmaximal.begin();i!=nonmaximal.end();i++) { if(!first) p.printString(",\n"); p.printVector(*i); first=false; } } p.printString("}\n"); subsetIterator++; } /* for(int d=homog;d<=largest;d++) { list cones2; for(list::iterator i=cones.begin();i!=cones.end();i++) if(i->dimension()==d) cones2.push_back(*i); p.printString("Printing ");p.printInteger(cones2.size());p.printString(" ");p.printInteger(d);p.printString("-dimensional cones:\n"); p.printString("{"); for(list::const_iterator i=cones2.begin();i!=cones2.end();i++) { IntegerVector v(0); int J=0; for(IntegerVectorList::const_iterator j=rays.begin();j!=rays.end();j++) { if(i->contains(*j)) { v.grow(v.size()+1); v[v.size()-1]=J; } J++; } if(i!=cones2.begin())p.printString(",\n"); p.printVector(v); } p.printString("}\n"); } */ } class BitSet { vector v; public: BitSet() { } BitSet(int n): v(n) { for(int i=0;i=0 && n=0 && n > > table; public: Table(vector > const &l): table(l.size()) { int N=l.size(); for(int i=0;i > v(N); for(int j=0;j w(l[i].size()); for(int k=0;k > fanList; Table knownEmptyIntersectionInIntersection; Table knownNonEmptyIntersection; public: int numberOfSolvedLPs; RelationTable(vector > const &l): fanList(l), knownEmptyIntersectionInIntersection(l), knownNonEmptyIntersection(l), numberOfSolvedLPs(0) { } bool intersectTriviallyInIntersection(int fan1, int cone1, int fan2, int cone2) { assert(fan1 > fans; IntegerVector chosen; IntegerVector chosenFans; IntegerVector iterators; //just used for printing IntegerVector nCandidates; //just used for printing BitSet usedFans; int numberOfUsefulCalls; int totalNumberOfCalls; public: RelationTable table; RecursionData(vector > const &fans_): table(fans_), fans(fans_), chosen(fans_.size()), chosenFans(fans_.size()), usedFans(fans_.size()), iterators(fans_.size()), nCandidates(fans_.size()), numberOfUsefulCalls(0), totalNumberOfCalls(0) { } HalfOpenConeList ret; BitSet computeCandidates(int index, int fanNumber) { BitSet nonCandidates(fans[fanNumber].size()); for(int i=0;i1) { smallest=1000000; bx=-1; by=-1; for(int x=0;x > L2; { for(int i=0;i L; for(vector::const_iterator j=fans[i].begin();j!=fans[i].end();j++) { if(!haveEmptyIntersection(next,*j)) { L.push_back(intersection(next,*j,true)); } } fprintf(stderr,"New fan size:%i\n",L.size()); L2.push_back(L); } } RecursionData data(L2); data.completeTable(); success|=data.rek(0, HalfOpenCone(next.dimension,IntegerVectorList(),IntegerVectorList(),IntegerVectorList())); ret.splice(ret.begin(),data.ret); } chosen[index]=-1;//just for printing } iterators[index]++;//just for printing } /* if(!success) { for(int x=0;x > L2; { for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { HalfOpenConeList l=tropicalHyperSurface(*i); vector L; for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) { L.push_back(*i); } L2.push_back(L); } } RecursionData data(L2); // data.completeTable(); data.rek(0, HalfOpenCone(dimension,IntegerVectorList(),IntegerVectorList(),IntegerVectorList())); fprintf(stderr,"LPs solved:%i for relation table\n",data.table.numberOfSolvedLPs); return data.ret; } gfan0.6.2/src/application.cpp0000644000175000017500000003400213122232611015455 0ustar andersanders#include "application.h" #include #include #include #include #include #include #include "field.h" //REMOVE THIS INCLUDE using namespace std; #define APPLICATIONNAME "gfan" Application *Application::applicationList; Application::Option *Application::Option::constructionList; static char *findName(char *p) { // extracts filename from argv[0] int l=strlen(p); assert(l>0); do { l--; } while(p[l]!=0 && p[l]!='/'); return p+l+1; } static char* tail(char *p) { const char *n=APPLICATIONNAME; const char *m=n; assert(p); while(*m) { assert(*p==*m); m++; p++; } return p; } //-------------------------------------------------- // Main - starts an application //-------------------------------------------------- int main(int argc, char *argv[]) { { vector stack4; stack4.push_back(1); stack4.push_back(1);//This line fails with valgrind if cfmem from Singular/Factory is linked. (initCanonicalForm is called during static initialisation in canonicalform.h) stack4.pop_back(); stack4.pop_back(); } bool helpOption=false; if(argc==2)if(strcmp(argv[1],"--help")==0)helpOption=true; if(argc==3)if(strcmp(argv[2],"--help")==0)helpOption=true; /* if(argc==2) { if(strcmp(argv[1],"installlinks")==0) { Application::makeSymbolicLinks(APPLICATIONNAME,false,""); return 0; } if(strcmp(argv[1],"installlinksall")==0) { Application::makeSymbolicLinks(APPLICATIONNAME,true,""); return 0; } if(strcmp(argv[1],"documentation")==0) { Application::produceLatexDocumentation(false); return 0; } if(strcmp(argv[1],"--help")==0)helpOption=true; } if(argc==3) { if(strcmp(argv[1],"installlinks")==0) { Application::makeSymbolicLinks(APPLICATIONNAME,false,argv[2]); return 0; } if(strcmp(argv[1],"installlinksall")==0) { Application::makeSymbolicLinks(APPLICATIONNAME,true,argv[2]); return 0; } if(strcmp(argv[2],"--help")==0)helpOption=true; } */ // fprintf(Stderr,"Extracted name=%s",); // Application *app=Application::applicationList; int argumentsToSkip=0; Application *app=0; Application *app2=0; if(argc>1)app2=Application::findApplication(argv[1]); Application *app3=Application::findApplication(tail(findName(argv[0]))); if(app2) { argumentsToSkip=1; app=app2; } else app=app3; if(app==0) { fprintf(stderr,"Application not found!\n"); assert(0); return 0; } /* if((!app) || app->next) { fprintf(Stderr,app?"Error: multiple applications defined.\n" :"Error: no applications defined.\n"); assert(0); return 0; }*/ if(helpOption) { app->printHelp(); return 0; } if(app->parseOptions(argc,argv,argumentsToSkip)) { int ret=app->main(); // fprintf(Stderr,"Number of rationals living:%i\n",FieldElementRationalsLiving); app->onExit(); return ret; } return 1; } //-------------------------------------------------- // A few internal applications for installation // and generating documentation. //-------------------------------------------------- class DocumentationApplication : public Application { bool includeInDefaultInstallation() { return false; } const char *helpText() { return "Internal application for generating the LaTeX documentation.\n"; } const char *name() { return "_documentation"; } int main() { Application::produceLatexDocumentation(false); return 0; } }; DocumentationApplication theDocumentationApplication; class InstallationApplication : public Application { SimpleOption optionAll; StringOption optionPath; bool includeInDefaultInstallation() { return false; } public: InstallationApplication(): optionAll("--all","Install all links to all programs. Also the ones only known by the author.\n"), optionPath("--path","Specify the installation path.\n","") { registerOptions(); } const char *helpText() { return "Internal application for installing symboilic links.\n"; } const char *name() { return "installlinks"; } int main() { Application::makeSymbolicLinks(APPLICATIONNAME,optionAll.getValue(),optionPath.getValue()); return 0; } }; InstallationApplication theInstallationApplication; //-------------------------------------------------- // Application::Option //-------------------------------------------------- Application::Option::Option() { bool hidden=false; next=constructionList;constructionList=this; } Application::Option *Application::Option::getOptionList() { Option *ret=constructionList;constructionList=0;return ret; } void Application::Option::onOptionsParsed() { } bool Application::Option::isHidden()const { return hidden; } void Application::Option::hide(bool b) { hidden=b; } //-------------------------------------------------- // Application::StringMatchingOption //-------------------------------------------------- bool Application::StringMatchingOption::isExactMatch(const char *s) { return std::string(s)==std::string(matchString); } Application::StringMatchingOption::StringMatchingOption(const char *s, const char *description_): matchString(s), description(description_) { } bool Application::StringMatchingOption::matches(const char *s) { for(int i=0;matchString[i];i++) if(matchString[i]!=s[i])return false; return true; } std::string Application::StringMatchingOption::documentationMatchString() { return std::string(matchString); } std::string Application::StringMatchingOption::documentationDescription() { return description; } //-------------------------------------------------- // Application::SimpleOption //-------------------------------------------------- Application::SimpleOption::SimpleOption(const char *s, const char *description): StringMatchingOption(s, description), value(false) { } void Application::SimpleOption::parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed) { *numberOfArgumentsParsed=0; if(isExactMatch(argv[t])) { value=true; *ok=true; } else *ok=false; } bool Application::SimpleOption::getValue() { return value; } //-------------------------------------------------- // Application::ValueOption //-------------------------------------------------- Application::ValueOption::ValueOption(const char *s, const char *description): StringMatchingOption(s, description) { } std::string Application::ValueOption::documentationMatchString() { return std::string(matchString)+" value"; } void Application::ValueOption::parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed) { if(isExactMatch(argv[t])) { if(argv[t+1]==0 || argv[t+1][0]=='-') { assignValue(""); *ok=true; *numberOfArgumentsParsed=0; } else { assignValue(argv[t+1]); if(argv[t+1]) { *ok=true; *numberOfArgumentsParsed=1; } else { *ok=false; *numberOfArgumentsParsed=0; } } } else { assignValue(argv[t]+std::string(matchString).length()); *ok=true; *numberOfArgumentsParsed=0; } } //-------------------------------------------------- // Application::StringOption //-------------------------------------------------- Application::StringOption::StringOption(const char *s, const char *description, const char *initialValue): ValueOption(s, description), value(initialValue) { } void Application::StringOption::assignValue(const char *s) { value=s; } const char *Application::StringOption::getValue() { return value; } //-------------------------------------------------- // Application::IntegerOption //-------------------------------------------------- Application::IntegerOption::IntegerOption(const char *s, const char *description, int initialValue): ValueOption(s, description), value(initialValue), hasRange(false) { } Application::IntegerOption::IntegerOption(const char *s, const char *description, int initialValue, int lower_, int upper_): ValueOption(s, description), value(initialValue), hasRange(true), lower(lower_), upper(upper_) { } void Application::IntegerOption::assignValue(const char *s) { bool onlyDigits=true; value=0; for(int t=0;s[t];t++) { if(s[t]<'0' || s[t]>'9')onlyDigits=false; value*=10; value+=s[t]-'0'; } assert(onlyDigits); if(hasRange) if(lower>value || uppernext) { if(i->matches(argv[t]))numberOfMatchesFound++; } // fprintf(Stderr,"NumberOfMatches %i\n",numberOfMatchesFound); assert(numberOfMatchesFound<2); if(numberOfMatchesFound==0) { fprintf(stderr,"UNKNOWN OPTION: %s.\n",argv[t]); fprintf(stderr,"USE --help AS A SINGLE OPTION TO VIEW THE HELP TEXT.\n"); return false; } for(Option *i=optionList;i;i=i->next) if(i->matches(argv[t])) { bool ok=false; int argumentsParsed=1; i->parseValue(t,argv,&ok,&argumentsParsed); if(!ok) { fprintf(stderr,"PARSE ERROR PARSING ARGUMENTS IN OPTION %s.\n",argv[t]); fprintf(stderr,"USE --help AS A SINGLE OPTION TO VIEW THE HELP TEXT.\n"); // assert(0); // exit(0); return false; } t+=argumentsParsed; break; } } for(Option *i=optionList;i;i=i->next)i->onOptionsParsed(); return true; } void Application::registerOptions() {//merge current list of options with new list Option *l=Option::getOptionList(); while(l) { Option *o=l; l=o->next; o->next=optionList; optionList=o; } } void Application::printHelp() { fprintf(stderr,"%s",helpText()); Application *p=applicationList; FILE *f=stderr; Option *l=optionList; if(l) { fprintf(f,"Options:\n"); while(l) { if(!l->isHidden())fprintf(f,"%s:\n %s\n",l->documentationMatchString().c_str(),l->documentationDescription().c_str()); l=l->next; } } }; class Application *Application::findApplication(char *name) { Application *p=applicationList; while(p) { if(strcmp(name,p->name())==0)return p; p=p->next; } return 0; } void Application::makeSymbolicLinks(const char *name, bool all, const char *path) { Application *p=applicationList; while(p) { if(all || p->includeInDefaultInstallation()) if(strlen(p->name())>0) { char c[1024]; sprintf(c,"ln -s %s%s %s%s%s\n",path,name,path,name,p->name()); fprintf(stderr,"%s",c); int err=system(c); assert(err==0); } p=p->next; } } static int substituteSingleString(FILE *f,const char* s, const char* pattern, const char* substitute) { int n=0; while(*pattern) { if(*s!=*pattern)return 0; pattern++; s++; n++; } fprintf(f,"%s",substitute); return n; } static void quoteLatexPrint(FILE *f, const char *s) { while(*s) { s+=substituteSingleString(f,s,"\\omega","\\omega"); if(s[0]=='-' && s[1]=='-') { fprintf(f,"-\\hspace{0.013cm}-"); s++; } else if(s[0]=='G' && s[1]=='r' && s[2]=='o' && s[3]=='e') { fprintf(f,"Gr\\\"o"); s+=3; } else if(s[0]=='~') fprintf(f,"\\~{}"); else if(s[0]=='{') fprintf(f,"\\{"); else if(s[0]=='}') fprintf(f,"\\}"); else if(s[0]=='_') fprintf(f,"\\_"); else if(s[0]=='\\') fprintf(f,"\\backslash"); else if(s[0]=='<') fprintf(f,"\\symbol{60}"); else fprintf(f,"%c",s[0]); s++; } } static bool compare_appname(Application *a, Application *b) { return string(a->name())name()); } std::list Application::getSortedApplicationList() { Application *p=applicationList; list alist2; while(p) { alist2.push_back(p); p=p->next; } alist2.sort(compare_appname); return alist2; } void Application::produceLatexDocumentation(bool all) { FILE *f=stdout; std::list alist2=getSortedApplicationList(); // while(p) for(list::const_iterator i=alist2.begin();i!=alist2.end();i++) { Application *p=*i; if(all || p->includeInDefaultInstallation()) { fprintf(f,"{\\subsection{%s",APPLICATIONNAME); quoteLatexPrint(f,p->name()); fprintf(f,"}"); fprintf(f,"\\label{applist:%s}\n",p->name()); quoteLatexPrint(f,p->helpText()); Option *l=p->optionList; bool containsNonHidden=false; Option *l2=l; while(l2){if(!l2->isHidden())containsNonHidden=true;l2=l2->next;} if(containsNonHidden) { fprintf(f,"\\newline\n"); fprintf(f,"{\\bf Options:}\n"); fprintf(f,"\\begin{description}\n"); while(l) { if(!l->isHidden()) { fprintf(f,"\\item["); quoteLatexPrint(f,l->documentationMatchString().c_str()); fprintf(f,"]"); quoteLatexPrint(f,l->documentationDescription().c_str()); } l=l->next; } fprintf(f,"\\end{description}\n"); } fprintf(f,"\n\n"); } // p=p->next; } } void Application::onExit() { } gfan0.6.2/src/traverser_secondaryfan.h0000644000175000017500000000156013122232611017373 0ustar andersanders#ifndef TRAVERSER_SECONDARYFAN_H_INCLUDED #define TRAVERSER_SECONDARYFAN_H_INCLUDED #include "symmetrictraversal.h" #include "triangulation2.h" Triangulation2 triangulationWithFullDimensionalIntersection(Triangulation2 g, PolyhedralCone const &c); class SecondaryFanTraverser: public ConeTraverser { Triangulation2 theTriangulation; PolyhedralCone theCone; PolyhedralCone theRestrictingCone; // bool isHomogeneous; bool isSecondaryFanComplete; int n,d; void updatePolyhedralCone(); public: SecondaryFanTraverser(Triangulation2 const &triangulation_); SecondaryFanTraverser(Triangulation2 const &triangulation_, PolyhedralCone const &restrictingCone); virtual void changeCone(IntegerVector const &ridgeVector, IntegerVector const &rayVector); virtual IntegerVectorList link(IntegerVector const &ridgeVector); PolyhedralCone & refToPolyhedralCone(); }; #endif gfan0.6.2/src/subspace.cpp0000644000175000017500000001034513122232611014763 0ustar andersanders#include "subspace.h" #include "division.h" #include "buchberger.h" #include "field_rationals.h" Polynomial vectorToPolynomial(PolynomialRing const &r, IntegerVector const &v) { /*static Field* field; if(!field)field=Field::find("GmpRationals"); // this is a bit stupid. We should add a field_rationals header file instead assert(field); */ Polynomial ret(r); for(int i=0;i r(n); for(int i=0;ifirst.exponent==IntegerVector::standardVector(n,j)) { r[j]=i->second; } } return primitiveVector(r); } Subspace::Subspace(IntegerVectorList const &generators, int ambientDimension): basis2(integerMatrixToFieldMatrix(rowsToIntegerMatrix(generators,ambientDimension),Q)) // , basis(PolynomialRing(Q,ambientDimension)) { // n=ambientDimension; n=basis2.getWidth(); /* { PolynomialRing theRing=basis.getRing(); if(n==-1) { assert(!generators.empty()); n=generators.begin()->size(); } for(IntegerVectorList::const_iterator i=generators.begin();i!=generators.end();i++) { assert(i->size()==n); basis.push_back(vectorToPolynomial(theRing,*i)); } buchberger(&basis,LexicographicTermOrder()); }*/ basis2.reduce(); basis2.REformToRREform(); basis2.scaleFirstNonZeroEntryToOne(); basis2.removeZeroRows(); integerRep=getRepresentation(); integerRep.sort(); } bool Subspace::contains(IntegerVector const &v)const { if(v.size()!=n) { fprintf(Stderr,"v.size()=%i, n=%i",v.size(),n); } assert(v.size()==n); // bool oldRet=division(vectorToPolynomial(PolynomialRing(Q,v.size()),v),basis,LexicographicTermOrder()).isZero(); bool ret=basis2.canonicalize(integerVectorToFieldVector(v,Q)).isZero(); // assert(oldRet==ret); return ret; } int Subspace::dimension() { // assert(basis2.reduceAndComputeRank()==basis.size()); return basis2.reduceAndComputeRank(); // return basis.size(); } int Subspace::ambientDimension()const { return n; } Subspace sum(Subspace const &a, Subspace const &b) { /*Subspace ret=a; ret.basis.insert(ret.basis.end(),b.basis.begin(),b.basis.end()); buchberger(&ret.basis,LexicographicTermOrder()); return ret; */ Subspace ret=a; ret.basis2=combineOnTop(a.basis2,b.basis2); ret.basis2.reduce(); ret.basis2.REformToRREform(); ret.basis2.scaleFirstNonZeroEntryToOne(); ret.basis2.removeZeroRows(); ret.integerRep=ret.getRepresentation(); ret.integerRep.sort(); return ret; } IntegerVectorList Subspace::getRepresentation()const { /*IntegerVectorList ret; for(PolynomialSet::const_iterator i=basis.begin();i!=basis.end();i++) { ret.push_back(polynomialToVector(*i)); } */ IntegerVectorList ret2; for(int i=0;i0)*/ ret2.push_back(temp); /* else ret2.push_back(-temp); */ } } /* AsciiPrinter(Stderr).printVectorList(ret); AsciiPrinter(Stderr).printVectorList(ret2); fprintf(Stderr,"------------------\n"); */ return ret2; } IntegerVector Subspace::canonicalizeVector(IntegerVector const &v)const { /* Polynomial f=vectorToPolynomial(PolynomialRing(Q,v.size()),v); f=division(f,basis,LexicographicTermOrder()); IntegerVector ret=polynomialToVector(f); */ IntegerVector ret2=basis2.canonicalize(integerVectorToFieldVector(v,Q)).primitive(); // assert((ret-ret2).isZero()); return ret2; } bool Subspace::operator<(Subspace const &b)const { return integerRep #include #include #include /* Always include cstdio before gmp.h.*/ #include //SHOULD BE REMOVED #ifndef GFANLIB_FIELD_H_ #define GFANLIB_FIELD_H_ #define GFANLIB_FIELDELEMENTREFCOUNT 1 namespace gfan{ /** A FieldElement is an element of a Field in the algebraic sense. A FieldElement always knows its associated Field to which it belongs. We may perform arithmetic operations on a FieldElement and a FieldElement is passed around by value. Thus in C++ it makes no sense to derive classes from the FieldElement class. The actual data is contained in an object of the class FieldElementImplementation and the FieldElement serves as a smart pointer without reference counting to avoid multi-threaded synchronisation. */ class FieldElement { // public: #if GFANLIB_FIELDELEMENTREFCOUNT std::shared_ptr implementingObject; #else class FieldElementImplementation *implementingObject; #endif void makeUnique() { #if GFANLIB_FIELDELEMENTREFCOUNT if(implementingObject.use_count()!=1) { std::shared_ptr temp(implementingObject->copy()); swap(temp,implementingObject); } #endif } FieldElement(class FieldElementImplementation *implementingObject_); public: class FieldImplementation *getField()const; /* Returns a pointer to the FieldImplementation which does NOT get its refCount increased. The pointer should immediately be cast to a Field object, there by increasing the refCount. This allows code like this void test(FieldElement a){Field b=a.getField();...}. Would it also work for this (a+a).getField(); or could the ref count get 0 before it is increased? */ #if 0 /* * The following is only supported for Z/pZ */ int getIntegerRepresentation()const; int integerRepresentative()const; // Only allowed for Z/pZ /* * The following two are only supported for rationals. */ mpq_t const *getGmpRationalTemporaryPointer()const; double floatingPointApproximation()const; bool isInteger()const; int pAdicValuation(int p)const; // Only allowed for the field Q. FieldElement pAdicRemainder(class Field const &ZModPZ)const; // Only allowed for the field Q. #endif FieldElement one() const { assert(implementingObject); return FieldElement(implementingObject->one()); } bool isZero()const { assert(implementingObject); return implementingObject->isZero(); } bool isOne()const { if(!implementingObject)return false; return (*this-one()).isZero(); } friend FieldElement operator+(const FieldElement &a,const FieldElement &b) { assert(a.implementingObject); assert(b.implementingObject); return FieldElement(a.implementingObject->sum(*(b.implementingObject))); } friend FieldElement operator-(const FieldElement &a,const FieldElement &b) { assert(a.implementingObject); assert(b.implementingObject); return FieldElement(a.implementingObject->difference(*(b.implementingObject))); } friend FieldElement operator-(const FieldElement &b) { assert(b.implementingObject); return FieldElement(b.implementingObject->negation()); } FieldElement inverse()const { assert(implementingObject); return FieldElement(implementingObject->inverse()); } int sign()const // Only allowed for ordered field. Asserts otherwise. { assert(implementingObject); return implementingObject->sign(); } std::string toString(bool writeIfOne=true, bool alwaysWriteSign=false ,bool latexMode=false) const; void operator*=(const FieldElement &a) { assert(a.implementingObject); assert(implementingObject); makeUnique(); (*implementingObject)*=(*a.implementingObject); } void operator+=(const FieldElement &a) { assert(a.implementingObject); assert(implementingObject); makeUnique(); (*implementingObject)+=(*a.implementingObject); } /** Adds a*b to the value of the object. */ void madd(const FieldElement &a, const FieldElement &b) { assert(a.implementingObject); assert(b.implementingObject); assert(implementingObject); makeUnique(); (*implementingObject).madd(*a.implementingObject,*b.implementingObject); } friend FieldElement operator*(const FieldElement &a,const FieldElement &b) { FieldElement c=a; c*=b; return c; } // Constructors: FieldElement(class Field const &f);//Initializes to zero FieldElement() // This constructor causes a lot of trouble { // Having a legal FieldElement without an implementing object // implementingObject=0; // we must check for each assignment (copy constructor/assignment operator) } // if the pointer is zero. - And some operation will be illegal on // on this element ( one(),..... ) FieldElement(const FieldElement &a); FieldElement& operator=(const FieldElement& a); virtual ~FieldElement(); }; /** The Field class describes an object which has as its value a field (in the algebraic sense). The value/object can be copied around as a value. The Field object serves as a smart pointer with reference counting to a FieldImplementation which is hidden for the user of the Field class. In C++ it makes no sense to derive classes from this class because the object must be passable by value. */ class Field { friend class FieldElement; // protected: public: // class FieldImplementation *implementingObject; std::shared_ptr implementingObject; public: FieldElementImplementation *zHomomorphismImplementation(int n)const; /** @return The image of the integer n under the unique ring homomorphism from the integers Z to the Field taking 1 to the multiplicative neutral element. */ FieldElement zHomomorphism(int n)const; int getCharacteristic()const; bool isRationals()const; const char *name(); std::string toString()const; Field(Field const &a);//copy constructor Field(FieldImplementation *implObj);//constructor Field& operator=(const Field& a);//assignment ~Field();//destructor }; class FieldElementImplementation { static int numberOfLivingFieldElementImplementations; class FieldImplementation &theFieldImplementation; /* Ideally FieldElement would contain a Field object. However, since methods of a Field should be able to return FieldElements this seems impossible because of the stupid one-pass convention of C++. Instead FieldElement contains a FieldImplementation pointer and FieldElement must thus do the reference counting for this pointer on its own ???*/ public: class FieldImplementation *getField()const; static int getNumberOfLivingFieldElementImplementations(){return numberOfLivingFieldElementImplementations;}; // int refCount; FieldElementImplementation(FieldImplementation &a);//ref count = 1?? virtual ~FieldElementImplementation(); virtual FieldElementImplementation *one() const=0; virtual FieldElementImplementation *copy()const=0; virtual bool isZero()const=0; virtual FieldElementImplementation *sum(const FieldElementImplementation &b)const=0; virtual FieldElementImplementation *difference(const FieldElementImplementation &b)const=0; virtual FieldElementImplementation *negation()const=0; virtual FieldElementImplementation *inverse()const=0; virtual std::string toString(bool writeIfOne=true, bool alwaysWriteSign=false, bool latexMode=false) const=0; virtual void operator*=(const FieldElementImplementation &a)=0; virtual void operator+=(const FieldElementImplementation &a)=0; virtual void madd(const FieldElementImplementation &a,const FieldElementImplementation &b)=0; virtual int sign()const { assert(0); return 0; } virtual int pAdicValuation(int p)const { assert(0); return 0; } virtual FieldElement pAdicRemainder(Field const &ZModPZ)const { assert(0); return pAdicRemainder(ZModPZ); } /* virtual int integerRepresentative()const { assert(0); return 0; }*/ virtual mpq_t const *getGmpRationalTemporaryPointer()const { fprintf(stderr,"*this object is not implemented using GMP\n"); assert(0); return 0; } virtual int getIntegerRepresentation()const { fprintf(stderr,"*this is not in Z/pZ.\n"); assert(0); } virtual bool isInteger()const { assert(0); return false; } Field& operator=(const Field& a) { assert(0); }//assignment }; extern int FieldElementRationalsLiving; class FieldImplementation { public: // int refCount; // static class Field *currentField; // ?? // static void checkInitialized(); // ?? protected: // class Field *next; // static class Field *list; static int numberOfLivingFieldImplementations; public: virtual FieldElementImplementation *zHomomorphismImplementation(int n)=0;/* Creates FieldElementImplementation object with refcount1 */ public: static int getNumberOfLivingFieldImplementations(){return numberOfLivingFieldImplementations;}; FieldImplementation()//:refCount(0) { numberOfLivingFieldImplementations++; } virtual ~FieldImplementation() { numberOfLivingFieldImplementations--; } virtual bool isRationals()const { return false; } // static Field *find(const char *name); // static void printList(FILE *f); virtual FieldElement zHomomorphism(int n)=0; virtual int getCharacteristic()const=0; virtual const char *name()=0; virtual std::string toString()const=0; // static void setField(Field *f); // Do we really want these // static FieldElement staticZHomomorphism(int n); // two procedures? }; } #endif /* GFANLIB_FIELD_H_ */ gfan0.6.2/src/termorder.cpp0000644000175000017500000003205613122232611015164 0ustar andersanders#include "termorder.h" #include #include "printer.h" // To do: FIX ROWDOT, MUST USE LONGS void TermOrder::print(Printer &p)const { p.printString("TermOrder"); p.printNewLine(); } void TermOrder::printMatrix(Printer &p, int dim)const { IntegerVectorList l; for(int i=0;ilargest=largest; } int LexicographicTermOrder::rowDot(int row, const IntegerVector &v)const { return v[(unsigned int)(row+largest)%(unsigned int)v.size()]; } bool LexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b, int scaleA, int scaleB, int perturbationDegree)const { if(a.size()!=b.size()) { fprintf(Stderr,"Lexicographic term order compare failed on the following vectors:\n"); AsciiPrinter(Stderr).printVector(a); fprintf(Stderr,"\n"); AsciiPrinter(Stderr).printVector(b); fprintf(Stderr,"\n"); assert(a.size()==b.size()); } int n=a.size(); int nLoop=n; if(perturbationDegree>=0)nLoop=perturbationDegree; for(int i=0;i(int64)scaleB*b[index])return false; } return false; } /*bool LexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b)const { int n=a.size(); assert(b.size()==n); for(int i=0;ia[i])return true; if(b[i]=0;i--) { if((int64)scaleA*a[i]<(int64)scaleB*b[i])return true; if((int64)scaleA*a[i]>(int64)scaleB*b[i])return false; } return false; } /*bool LexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b)const { int n=a.size(); assert(b.size()==n); for(int i=0;ia[i])return true; if(b[i]largest=largest; } int ReverseLexicographicTermOrder::index(int row, const IntegerVector &a)const { return (unsigned int)(-row+a.size()+largest-1)%(unsigned int)a.size(); //a>b>c //does largest work? //return (unsigned int)(row+largest)%(unsigned int)a.size();//a=0)nLoop=perturbationDegree; for(int i=0;iindex(i,a); int64 A=(int64)scaleA*a[index]; int64 B=(int64)scaleB*b[index]; if(A>B)return true; if(Aa[i])return false; if(b[i]B)return true; if(Alargest=largest; } int StandardGradedLexicographicTermOrder::rowDot(int row, const IntegerVector &v)const { if(row==0)return v.sum(); row--; return v[(unsigned int)(row+largest)%(unsigned int)v.size()]; } bool StandardGradedLexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b, int scaleA, int scaleB, int perturbationDegree)const { assert(a.size()==b.size()); int n=a.size(); if(perturbationDegree==0)return false; int64 difsum=(int64)scaleA*a.sum()-(int64)scaleB*b.sum(); if(difsum<0)return true; if(difsum>0)return false; if(perturbationDegree==1)return false; int nLoop=n; if(perturbationDegree>=0)nLoop=perturbationDegree-1; for(int i=0;i(int64)scaleB*b[index])return false; } return false; } /*bool StandardGradedLexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b)const { int n=a.size(); assert(b.size()==n); int difsum=a.sum()-b.sum(); if(difsum<0)return true; if(difsum>0)return false; for(int i=0;ia[i])return true; if(b[i]largest=largest; } int StandardGradedLexicographicTermOrder::rowDot(int row, const IntegerVector &v)const { if(row==0)return v.sum(); row--; return v[(unsigned int)(row+largest)%(unsigned int)v.size()]; } bool StandardGradedLexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b, int scaleA, int scaleB, int perturbationDegree)const { assert(a.size()==b.size()); int n=a.size(); if(perturbationDegree==0)return false; int64 difsum=(int64)scaleA*a.sum()-(int64)scaleB*b.sum(); if(difsum<0)return true; if(difsum>0)return false; if(perturbationDegree==1)return false; int nLoop=n; if(perturbationDegree>=0)nLoop=perturbationDegree-1; for(int i=0;i(int64)scaleB*b[index])return false; } return false; } void StandardGradedLexicographicTermOrder::print(Printer &p)const { p.printString("StandardGradedLexicographicTermOrder"); p.printNewLine(); } */ //----------------------------------------- // WeightTermOrder //----------------------------------------- int WeightTermOrder::rowDot(int row, const IntegerVector &v)const { if(row==0)return dot(v,weight); row--; return LexicographicTermOrder().rowDot(row,v); } bool WeightTermOrder::operator()(const IntegerVector &a, const IntegerVector &b, int scaleA, int scaleB, int perturbationDegree)const { // fprintf(Stderr,"Perturbation degree: %i\n",perturbationDegree); if(perturbationDegree==0)return false; int64 d=scaleA*dotLong(a,weight)-scaleB*dotLong(b,weight); // int64 d=dotLong(scaleA*a-scaleB*b,weight); /* fprintf(Stderr,"sizeof:%i\n",sizeof(int64)); AsciiPrinter(Stderr).printVector(a); AsciiPrinter(Stderr).printVector(b); fprintf(Stderr,"%x %x\n",(int)d,(int)(d>>32)); fprintf(Stderr,"%x\n",(((int64)85569)*((int64)85569))/16); */ if(d<0)return true; if(d>0)return false; return LexicographicTermOrder()(a,b,scaleA,scaleB,perturbationDegree-1); } /*bool WeightTermOrder::operator()(const IntegerVector &a, const IntegerVector &b)const { int d=dot(a-b,weight); if(d<0)return true; if(d>0)return false; return LexicographicTermOrder()(a,b); }*/ void WeightTermOrder::print(Printer &p)const { p.printString("WeightTermOrder"); p.printVector(weight); p.printNewLine(); } //----------------------------------------- // WeightReverseLexicographicTermOrder //----------------------------------------- IntegerVector WeightReverseLexicographicTermOrder::getWeight()const { return weight; } int WeightReverseLexicographicTermOrder::rowDot(int row, const IntegerVector &v)const { if(row==0)return dot(v,weight); row--; return ReverseLexicographicTermOrder().rowDot(row,v); } bool WeightReverseLexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b, int scaleA, int scaleB, int perturbationDegree)const //bool WeightReverseLexicographicTermOrder::operator()(const IntegerVector &a, const IntegerVector &b)const { if(perturbationDegree==0)return false; //int d=dot(scaleA*a-scaleB*b,weight); int64 d=(int64)scaleA*dotLong(a,weight)-(int64)scaleB*dotLong(b,weight); if(d<0)return true; if(d>0)return false; return ReverseLexicographicTermOrder()(a,b,scaleA,scaleB,perturbationDegree-1); } void WeightReverseLexicographicTermOrder::print(Printer &p)const { p.printString("WeightReverseLexicographicTermOrder"); p<UNCHECKEDACCESS(j); db+=((int64)b.UNCHECKEDACCESS(j))*i->UNCHECKEDACCESS(j); } int64 d=scaleA*da-scaleB*db; #endif if(d<0)return true; if(d>0)return false; } return ReverseLexicographicInvertedTermOrder()(a,b,scaleA,scaleB,perturbationDegree-1); } void MatrixTermOrder::print(Printer &p)const { p.printString("MatrixTermOrder"); p<0)return false; return tieBreaker(a,b,scaleA,scaleB,perturbationDegree-1); } void TotalDegreeTieBrokenTermOrder::print(Printer &p)const { p.printString("TotalDegreeTieBrokenTermOrder"); tieBreaker.print(p); p.printNewLine(); } gfan0.6.2/src/app_padic.cpp0000644000175000017500000001714513122232611015103 0ustar andersanders/* * app_padic.cpp * * Created on: Dec 1, 2010 * Author: anders */ #include "printer.h" #include "parser.h" #include "gfanapplication.h" #include "division.h" #include "log.h" #include "polyhedralcone.h" #include "padic.h" #include using namespace std; class PAdicApplication : public GFanApplication { IntegerOption primeOption; SimpleOption gbOption; SimpleOption initialOption; SimpleOption initialFormsOption; SimpleOption gComplexOption; SimpleOption gPolyhedronOption; SimpleOption listOption; SimpleOption hyperSurfacesOption; public: const char *helpText() { return "This program is an experimental implementation of p-adic Groebner bases as proposed by Diane Maclagan.\n" "Several operations are supported by specifying the appropriate option:\n" " (1) computation of Groebner basis with respect to a given vector (tiebroken lexicographically),\n" " (2) computation of the p-adic initial ideal,\n" " (3) computation of the p-adic Groebner complex as defined by Maclagan and Sturmfels,\n" " (4) computation of a single polyhedron of the p-adic Groebner complex.\n" "The input ideal should be an ideal of the polynomial ring with coefficient field Q. The valuation is specified with the option -p. The ideal MUST BE HOMOGENEOUS (in a positive grading).\n" "Since gfan can only handle fans and not polyhedral complexes in general, what is computed as the Groebner complex is actually the \"fan over\" the complex - in other words, the first coordinate is supposed to be 1 in the output fan.\n" "Similarly, the weight vectors must be specified in an homogeneous way, for example by adding an additional 1 entry as first coordinate. (If fractions are needed, use the entry as a common denominator.) " "NOTE: This program is experimental and expected to change behaviour in future releases, so don't write your SAGE and M2 interfaces just yet. In particular this program uses the tropical minimum-convention!!\n"; } PAdicApplication(): primeOption("-p","Defines the prime used for the valuation.",2), gbOption("--groebnerBasis","Asks the program to compute a marked Groebner basis with respect to a weight vector (tie-broken lexicographically).\n" "The input order is: Ring ideal vector.\n"), initialOption("--initialIdeal","Asks the program to compute an initial ideal with respect to a vector. " "The input order is: Ring ideal vector.\n"), gComplexOption("--groebnerComplex","Asks the program to compute the p-adic Groebner complex. \n " "The input order is: Ring ideal.\n"), gPolyhedronOption("--groebnerPolyhedron","Asks the program to compute a single polyhedron of the Groebner complex containing the specified vector in its relative interior. The output is stored as a fan. " "The input order is: Ring ideal vector."), listOption("-m","For the operations taking a vector as input, read in a list of vectors instead, and perform the operation for each vector in the list."), hyperSurfacesOption("--hyper","..."), initialFormsOption("--initialForms","...") { registerOptions(); hyperSurfacesOption.hide(); initialFormsOption.hide(); } const char *name() { return "_padic"; } int main() { if(!hyperSurfacesOption.getValue()) if(gbOption.getValue()+initialOption.getValue()+initialFormsOption.getValue()+gComplexOption.getValue()+gPolyhedronOption.getValue()!=1) { debug<<"WRONG COMBINATION OF COMMAND LINE OPTIONS\n"; assert(0); } LexicographicTermOrder tieBreaker; FileParser P(Stdin); int prime=primeOption.getValue(); PolynomialSet a=P.parsePolynomialSetWithRing(); int n=a.getRing().getNumberOfVariables(); if(hyperSurfacesOption.getValue()) { PolynomialRing R=a.getRing().withVariablesAppended("T"); PolynomialSet g(R); for(PolynomialSet::const_iterator i=a.begin();i!=a.end();i++) { Polynomial p(R); for(TermMap::const_iterator j=i->terms.begin();j!=i->terms.end();j++) { IntegerVector exp=j->first.exponent; int val=j->second.pAdicValuation(prime); exp.push_back(val); Monomial A=Monomial(R,exp); p+=Term(a.getRing().getField().zHomomorphism(1),A); } g.push_back(p); } pout<size()!=a.getRing().getNumberOfVariables()+1) { debug<<"ERROR: The number of entries of the weight vector is not one higher than the number of variables in the ring.\n"; assert(0); } if(gbOption.getValue()) { //debug<<"P-ADIC GROEBNER BASIS:\n"; pAdicBuchberger(a,prime,*i,tieBreaker); pout< PolyhedralFan weilDivisor(PolyhedralFan const &F, PolyhedralFan const &G)//, Polynomial const &g) { // PolynomialRing R=g.getRing(); // PolyhedralFan G=PolyhedralFan::bergmanOfPrincipalIdeal(g); int n=G.getAmbientDimension(); int d=F.getMaxDimension(); PolyhedralFan retTemp(n); log1 cerr<<"Computing refinement"<getRelativeInteriorPoint(); PolyhedralCone c=G.coneContaining(v); if(!(c!=*i)) { retTemp.insert(c); found=true; } } if(!found) #endif for(PolyhedralConeList::const_iterator j=G.conesBegin();j!=G.conesEnd();j++) { PolyhedralCone c=intersection(*i,*j); c.canonicalize(); retTemp.insert(c); } } log1 cerr<<"Computing full complex"<dimension()==d-1) { IntegerVector v=i->getRelativeInteriorPoint(); AsciiPrinter P(Stderr); log2 P<contains(v)) { IntegerVectorList equations=j->getEquations(); IntegerVectorList inequalities1=j->getHalfSpaces(); IntegerVectorList inequalities2; for(IntegerVectorList::const_iterator i=inequalities1.begin();i!=inequalities1.end();i++) if(dotLong(v,*i)==0)inequalities2.push_back(*i); PolyhedralCone localJ(inequalities2,equations,n); localJ.canonicalize(); PolyhedralFan refinement(n); for(PolyhedralConeList::const_iterator k=localG.conesBegin();k!=localG.conesEnd();k++) { PolyhedralCone sigma=intersection(localJ,*k); sigma.canonicalize(); refinement.insert(sigma); } for(PolyhedralConeList::const_iterator k=refinement.conesBegin();k!=refinement.conesEnd();k++) { PolyhedralCone const &sigma(*k); if(sigma.dimension()==d) { /*IntegerVectorList rays=sigma.extremeRays(); assert(rays.size()==1);//SHOULD ALWAYS BE TRUE???? { IntegerVector ray=*rays.begin(); */ IntegerVector ray=sigma.semiGroupGeneratorOfRay(); evaluationVector+=j->getMultiplicity()*ray; //multiplicity+=j->getMultiplicity()*localg.degree(ray); multiplicity+=j->getMultiplicity()*localG.evaluatePiecewiseLinearFunction(ray); } } } } //multiplicity-=localg.degree(evaluationVector); multiplicity-=localG.evaluatePiecewiseLinearFunction(evaluationVector); if(multiplicity!=0) { PolyhedralCone c=*i; c.setMultiplicity(multiplicity); ret.insert(c); } } } return ret; } gfan0.6.2/src/traverser_resultantfanspecialization.h0000644000175000017500000000743613122232611022374 0ustar andersanders/* * traverser_resultantfanspecialization.h * * Created on: Jul 1, 2011 * Author: anders */ #ifndef TRAVERSER_RESULTANTFANSPECIALIZATION_H_INCLUDED #define TRAVERSER_RESULTANTFANSPECIALIZATION_H_INCLUDED #include "traverser_resultantfan.h" #include "triangulation2.h" /* * Specializing at a set of variables coresponds to stably intersecting with the subspace * where these coordinates are zero. */ class ResultantFanSpecializationTraverser : public ConeTraverser { Triangulation2 theTriangulation; PolyhedralCone theCone; // PolynomialSet g; IntegerVectorListList tuple; IntegerMatrix theConfiguration; IntegerVector isSpecial; vector > intervals; PolyhedralCone subspace; int D1; int n,d; public: ResultantFanSpecializationTraverser(/*PolynomialSet const &g, */IntegerVectorListList const &tuple_,int D_, IntegerMatrix const &cayley, vector > intervals_, IntegerVector const &isSpecial_, IntegerVector omega, int dim); virtual void changeCone(IntegerVector const &ridgeVector, IntegerVector const &rayVector); virtual IntegerVectorList link(IntegerVector const &ridgeVector); PolyhedralCone &refToPolyhedralCone(); }; IntegerVector nonTrivialVectorInSpecializedResultant(IntegerMatrix const &exponents, vector > const &intervals, IntegerVector const &subset, IntegerVector const &isSpecial); /** * This function takes a matrix whose columns are grouped according to intervals, and computes perturbed vector in the * relative interior of a maximal cone in the corresponding specialized resultant. The specialization variables are given * by the 0-1 vector isSpecial. * An additional argument is the 0-1 subset vector, which tells which columns of the matrix (and entries of isSpecial) to * take into the consideration. Usually this will be the all 1 vector, but since this function is recursive other inputs are * allowed. * The return value v, is to be interpreted as v[0]+epsilon*v[1]+epsilon^2*v[2].... */ IntegerVectorList perturbationSequenceRek(IntegerMatrix const &exponents, vector > const &intervals, IntegerVector const &subset, IntegerVector const &isSpecial, PolyhedralCone const &toBeAvoided); bool isSpecializedResultantEmpty(IntegerMatrix const &exponents, vector > const &intervals, IntegerVector const &isSpecial); /** * Computes the secondary cone containing the perturbed vector l[0]+epsilon*l[1]+.... * The configuration is.... */ PolyhedralCone perturbationSequenceToVectorInSecondaryCone(IntegerVectorList const &l, IntegerMatrix const &configuration); /** * Takes the list of boolean values and returns the subspace, generated by those standard vectors whose corresponding * entry boolean value is zero. The return value is a PolyhedralCone. */ PolyhedralCone specializedToSubspace(IntegerVector const &isSpecial); /** * This class takes a list of intervals and iterates through all vectors of possible two element subsets * where the ith two element subset is a subset of the ith interval. */ class SelectionIterator { vector > choices; public: SelectionIterator(vector > const &intervals): choices(intervals.size()) { for(int i=0;i=intervals[i].second-2); } bool operator++() { int i; for(i=0;i /* Faster version of the code in bergman.cpp. */ /** The hypergraph of ridges and facets can be considered as a usual bipartite graph where the right nodes are the ridges and the left nodes are the facets. We wish to make a traversal of this bipartite graph keeping track of the boundary edges of the traversed set. The ConeOrbit object represents the orbit of a ridge. The edges of the ridge are listed but only those which belong to the boundary of the set of ridges seen so far. When a ridge is discovered the ConeOrbit object will be created with all its edges present (except the one it was reached by). As progress in the computation is made these edges will be deleted. */ class Boundary2 { typedef pair EFirst; typedef pair ESecond; SymmetryGroup const &sym; map theSet; int theSetSize; public: Boundary2(SymmetryGroup const &sym_): sym(sym_), theSetSize(0) { } int size()const { return theSetSize; } pair normalForm(IntegerVector const &ridge, IntegerVector const &ray)const { pair ret; IntegerVector perm; ret.first=sym.orbitRepresentative(ridge,&perm); ret.second=sym.orbitRepresentativeFixing(SymmetryGroup::compose(perm,ray),ret.first); return ret; } bool containsFlip(IntegerVector const &ridge, IntegerVector const &ray, IntegerVectorList *storedInList_, IntegerVectorList::iterator listIterator_) { assert(ridge.size()==ray.size()); EFirst p=normalForm(ridge,ray); if(theSet.count(p)==1) { theSet[p].first->erase(theSet[p].second); theSet.erase(p); theSetSize--; return true; } theSet[p]=ESecond(storedInList_,listIterator_); theSetSize++; return false; } void removeDuplicates(IntegerVector const &ridge, IntegerVectorList &rays)const { IntegerVectorList ret; set representatives; for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) { IntegerVector rep=sym.orbitRepresentativeFixing(*i,ridge); if(representatives.count(rep)==0) { representatives.insert(rep); ret.push_back(*i); } } rays=ret; } void print()const { cerr<< "Boundary" <::const_iterator i=theSet.begin();i!=theSet.end();i++) { AsciiPrinter P(Stderr); P << i->first.first << i->first.second; cerr << endl; } cerr<getMarked().m.exponent==B->getMarked().m.exponent); } static void printMarkedTermIdeal(PolynomialSet const &g, string const &s) { PolynomialSet a=g.markedTermIdeal(); PolynomialSet b=a; minimize(&b); cerr << "Printing marked termideal. "<getMarked(); P.printPolynomial(m); if(division(m,temp,T).isZero()){cerr<<"YES";} cerr< const &facetStack, list const &ridgeStack) { list::const_iterator i=facetStack.begin(); list::const_iterator j=ridgeStack.begin(); AsciiPrinter P(Stderr); cerr<<"STACK:"<ridgeStack.size())goto entry; do { cerr<<"RIDGE:"<parentRidge<rays<parentRay; cerr<ridges; cerr<> a; } PolyhedralFan tropicalTraverse(PolynomialSet coneGroebnerBasis, PolynomialSet idealGroebnerBasis, SymmetryGroup const *symmetryGroup) { PolynomialSet ideal=idealGroebnerBasis; PolynomialRing theRing=coneGroebnerBasis.getRing(); assert(coneGroebnerBasis.numberOfVariablesInRing()==idealGroebnerBasis.numberOfVariablesInRing()); int n=coneGroebnerBasis.numberOfVariablesInRing(); PolyhedralFan ret(n); PolyhedralCone homogeneitySpac=homogeneitySpace(coneGroebnerBasis); int d=homogeneitySpac.dimensionOfLinealitySpace(); SymmetryGroup localSymmetryGroup(n); if(!symmetryGroup)symmetryGroup=&localSymmetryGroup; Boundary2 boundary(*symmetryGroup); list facetStack; list ridgeStack; int numberOfCompletedFacets=0; int numberOfCompletedRidges=0; int stackSize=0; PolyhedralCone currentFacet(n); IntegerVector facetUniqueVector; goto entry; while(1) { L1: // boundary.print(); //printStack(facetStack,ridgeStack); if(!facetStack.front().ridges.empty()) { cerr<<"1"; pathStepRidge top; PolyhedralCone link=currentFacet.link(facetStack.front().ridges.front()); link.canonicalize(); cerr<<"2"; top.parentRidge=facetStack.front().ridges.front(); top.parentRay=link.getUniquePoint(); cerr<<"3"; AsciiPrinter P(Stderr); // P<<"Cone groebner basis"<theCone; rayCone.canonicalize(); { if(rayCone.getUniquePoint().isZero())trouble=true; } rays.push_back(rayCone.getUniquePoint()); } if(trouble) { b.print(P); P< class MinorsApplication : public GFanApplication { IntegerOption rOption; IntegerOption dOption; IntegerOption nOption; SimpleOption M2Option; SimpleOption optionWithNames; SimpleOption dressianOption; SimpleOption pluckerSymmetriesOption; SimpleOption grassmannNormalizOption; SimpleOption symmetryOption; SimpleOption parametrizeOption; // SimpleOption threeTermOption; public: const char *helpText() { return "This program will generate the r*r minors of a d*n matrix of indeterminates.\n"; } MinorsApplication(): rOption("-r","Specify r.",1), dOption("-d","Specify d.",1), nOption("-n","Specify n.",1), M2Option("-M2","Use Macaulay2 conventions for order of variables."), dressianOption("--dressian","Produce tropical defining the Dressian(3,n) instead. (The signs may not be correct, that is the equations may not be Pluecker relations.)"), optionWithNames("--names","Assign names to the minors."), pluckerSymmetriesOption("--pluckersymmetries","Do nothing but produce symmetry generators for the Pluecker ideal."), grassmannNormalizOption("--grassmannnormalize","Produce polynomials describing the tropical polynomial map taking a plucker vector to a plucker vector where the leaf edges have length one."), symmetryOption("--symmetry","Produces a list of generators for the group of symmetries keeping the set of minors fixed. (Only without --names)."), parametrizeOption("--parametrize","Parametrize the set of d times n matrices of Barvinok rank less than or equal to r-1 by a list of tropical polynomials.") /*, threeTermOption("--threeTerm","Do nothing but output the three term Plucker relations.")*/ { registerOptions(); grassmannNormalizOption.hide(); } const char *name() { return "_minors"; } IntegerVectorList symmetries(int r, int d, int n) { IntegerVectorList ret; { IntegerVector v1(d*n); IntegerVector v2(d*n); IntegerVector v3(d*n); IntegerVector v4(d*n); for(unsigned int i=0;i const &v, int i) { for(int j=0;j pnames=subsetVariableNames("p",n,d,M2); vector qnames=subsetVariableNames("q",n,d,M2); vector names(pnames.size()*2); for(int i=0;i I; for(int i=0;i setkl; setkl.insert(k); setkl.insert(l); Polynomial f(R); Polynomial g(R); vector J; for(int i=0;i setij; setij.insert(i); setij.insert(j); set setik; setik.insert(i); setik.insert(k); set setjk; setjk.insert(j); setjk.insert(k); set setil; setil.insert(i); setil.insert(l); set setjl; setjl.insert(j); setjl.insert(l); if((J[l]==0)) { IntegerVector v=w; v[subsetToVariableIndex(setil,n,d,M2)]+=-1; v[subsetToVariableIndex(setjl,n,d,M2)]+=-1; v[subsetToVariableIndex(setij,n,d,M2)]+=1; v[subsetToVariableIndex(setkl,n,d,M2)]+=1; f+=Polynomial(Term(R.getField().zHomomorphism(1),Monomial(R,v))); } if((J[k]==0)) { IntegerVector v=w; v[subsetToVariableIndex(setik,n,d,M2)]+=-1; v[subsetToVariableIndex(setjk,n,d,M2)]+=-1; v[subsetToVariableIndex(setij,n,d,M2)]+=1; v[subsetToVariableIndex(setkl,n,d,M2)]+=1; g+=Polynomial(Term(R.getField().zHomomorphism(1),Monomial(R,v))); } } while(next_permutation(J.begin(),J.end())); IntegerVector v(names.size()); v[pnames.size()+subsetToVariableIndex(setkl,n,d,M2)]=1; ret.push_back(Polynomial(Term(R.getField().zHomomorphism(-1),Monomial(R,v)))+f*g); } while(next_permutation(I.begin(),I.end())); return ret; } int main() { FileParser P(Stdin); int d=dOption.getValue(); int n=nOption.getValue(); int r=rOption.getValue(); bool M2=M2Option.getValue(); assert(r<=d); assert(r<=n); PolynomialRing R(Q,matrixVariableNames("m",d,n)); if(parametrizeOption.getValue()) { vector A=matrixVariableNames("a",d,r-1); vector B=matrixVariableNames("b",r-1,n); A.insert(A.end(),B.begin(),B.end()); PolynomialRing R2(Q,A); PolynomialSet s(R2); for(int i=0;i I; if(n-d-2>=0)if(d-2>=0) for(int i=0;i ijkl; set S; int m=32873; for(int i=0;i s=S;s.insert(i);s.insert(j);//s.insert(m); pA[subsetToVariableIndex(s,n,d,M2)]=1; } { set s=S;s.insert(k);s.insert(l);//s.insert(m); pA[subsetToVariableIndex(s,n,d,M2)]=1; } { set s=S;s.insert(i);s.insert(k);//s.insert(m); pB[subsetToVariableIndex(s,n,d,M2)]=1; } { set s=S;s.insert(j);s.insert(l);//s.insert(m); pB[subsetToVariableIndex(s,n,d,M2)]=1; } { set s=S;s.insert(i);s.insert(l);//s.insert(m); pC[subsetToVariableIndex(s,n,d,M2)]=1; } { set s=S;s.insert(j);s.insert(k);//s.insert(m); pC[subsetToVariableIndex(s,n,d,M2)]=1; } Polynomial p= Polynomial(Term(R.getField().zHomomorphism(1),Monomial(R,pA))) -Polynomial(Term(R.getField().zHomomorphism(1),Monomial(R,pB))) +Polynomial(Term(R.getField().zHomomorphism(1),Monomial(R,pC))); g.push_back(p); } } while(next_permutation(I.begin(),I.end())); AsciiPrinter(Stdout).printPolynomialRing(R); AsciiPrinter(Stdout).printNewLine(); AsciiPrinter(stdout).printPolynomialSet(g); } else if(pluckerSymmetriesOption.getValue()) { int N=subsetVariableNames("p",n,d,M2).size(); IntegerVectorList permutations1; { IntegerVector p1(n); IntegerVector p2(n); for(int i=0;i2) { p2[0]=1; p2[1]=0; } permutations1.push_back(p1); permutations1.push_back(p2); } IntegerVectorList permutations2; IntegerVectorList signs2; for(IntegerVectorList::const_iterator k=permutations1.begin();k!=permutations1.end();k++) { IntegerVector p(N); IntegerVector signs(N); vector I; for(int i=0;i indexSet1; set indexSet2; list indexSet2List; for(int i=0;i::const_iterator i=indexSet2List.begin();i!=indexSet2List.end();i++) for(list::const_iterator j=indexSet2List.begin();j!=i;j++) if(*i<*j)permSign*=-1; p[subsetToVariableIndex(indexSet1,n,r,M2)]=subsetToVariableIndex(indexSet2,n,r,M2); signs[subsetToVariableIndex(indexSet2,n,r,M2)]=permSign; } while(next_permutation(I.begin(),I.end())); signs2.push_back(signs); permutations2.push_back(p); } AsciiPrinter(Stdout).printVectorList(permutations2); AsciiPrinter(Stdout).printVectorList(signs2); } /* else if(threeTermOption.getValue()) { for(int i=0;i S; vector ijkl; list indexSet2List; for(int i=0;i a=matrixVariableNames("m",d,n); vector b=subsetVariableNames("p",n,d,M2); for(vector::const_iterator i=b.begin();i!=b.end();i++)a.push_back(*i); R=PolynomialRing(Q,a); } PolynomialSet p=minors(R,r,d,n,optionWithNames.getValue(),M2); AsciiPrinter(Stdout).printPolynomialRing(p.getRing()); AsciiPrinter(Stdout).printNewLine(); AsciiPrinter(Stdout).printPolynomialSet(p); } if(symmetryOption.getValue()) { AsciiPrinter(Stdout)< #include #include #include #include #include #include "termorder.h" #include "division.h" #include "buchberger.h" #include "saturation.h" #include "printer.h" #include "linalg.h" #if USEPOLYNOMIALGCD #include "polynomialgcd.h" #endif #include "log.h" int FieldElementRationalFunctions2Living; /** * This field is the field of _multivariate_ rational functions. */ class FieldElementRationalFunction2 : public FieldElementImplementation { Polynomial gcd(Polynomial a, Polynomial b) { if(a.degree(IntegerVector::standardVector(1,0)) l; l.push_back(p); l.push_back(q); int n=r.getNumberOfVariables(); for(int i=0;i l2; PolynomialRing r2(r.getField(),1); for(int I=0;I<2;I++) { Polynomial temp(r2); for(TermMap::const_iterator j=l[I].terms.begin();j!=l[I].terms.end();j++) { FieldElement mp=j->second; for(int k=0;kfirst.exponent[k+(k>=i)];l>0;l--)mp*=val[k]; IntegerVector expo(1);expo[0]=j->first.exponent[i]; temp+=Term(mp,Monomial(r2,expo)); } if(temp.isZero())goto retry; if(temp.degree(IntegerVector::standardVector(1,0)!=l[I].degree(IntegerVector::standardVector(n,i)))|| temp.degree(-IntegerVector::standardVector(1,0)!=l[I].degree(-IntegerVector::standardVector(n,i)))) goto retry; l2.push_back(temp); } //gcd if(gcd(l2[0],l2[1]).numberOfTerms()!=1) return false; } return true; } public: Polynomial p,q; FieldElementRationalFunction2(FieldImplementation &a): FieldElementImplementation(a), p(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing()), q(Term(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing().getField().zHomomorphism(1),Monomial(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing()))) { FieldElementRationalFunctions2Living++; } FieldElementRationalFunction2(FieldImplementation &a,int n_): FieldElementImplementation(a), p(Term(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing().getField().zHomomorphism(n_),Monomial(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing()))), q(Term(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing().getField().zHomomorphism(1),Monomial(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing()))) { if(n_==0)p=Polynomial(((FieldRationalFunctions2Implementation*)&a)->getPolynomialRing()); FieldElementRationalFunctions2Living++; } void normalize(bool doExpensiveGCD=true) { if(p.isZero()){q=p.getRing().one();return;} //STEP 1: Scale leading term of denominator to 1 LexicographicTermOrder T; q.mark(T); FieldElement s=q.getMarked().c; if(!s.isOne()) { s=s.inverse(); q*=s; p*=s; } //STEP 2: If denominator is monomial, then everything is easy if(q.isMonomial()) { if(q.totalDegree()==0)return; if(p.isMonomial()) { p.mark(T); Monomial s(p.getRing(),-min(p.getMarked().m.exponent,q.getMarked().m.exponent)); p*=s; q*=s; return; } } //STEP 3: We factor out monomial factors in both p and q and remember them for later Monomial qm(q.getRing(),q.greatestCommonMonomialDivisor()); q.saturate(); Monomial pm(p.getRing(),p.greatestCommonMonomialDivisor()); p.saturate(); IntegerVector A=min(qm.exponent,pm.exponent); qm.exponent-=A; pm.exponent-=A; //STEP 4: If one of our polynomials is a monomial, then we can find no more common factors if(q.isMonomial()||p.isMonomial()) { p*=pm; q*=qm; return; } // STEP 5: We check special cases where p divides q or q divides p. q.mark(T); p.mark(T); { //if q divides p then we don't need to compute gcd PolynomialSet R(q.getRing()); PolynomialSet Q(q.getRing()); Q.push_back(q); if(division(p,Q,T,&R).isZero()) { //pout<CLOCKS_PER_SEC) // { // debug<<"GCD TAKES TOO LONG:\n"<numberOfTerms()){FACTOR++;//pout<q<<"\n"; debug<p<<"\n"; debug<<(q*A->p)<<" - "<q<<"\n"; */ Polynomial fac1=polynomialGCD(p,A->q); Polynomial fac2=polynomialGCD(q,A->p); // Polynomial pTemp=p; // Polynomial qTemp=q; // p*=A->p; // q*=A->q; // normalize(); //#if 1 // int totalTerms=p.numberOfTerms()+q.numberOfTerms(); // p=pTemp; // q=qTemp; #if 0 p*=A->p; q*=A->q; // debug<<"A\n"; bool err=false; err|=!fac1.divides(p,&p); err|=!fac1.divides(q,&q); err|=!fac2.divides(p,&p); err|=!fac2.divides(q,&q); // debug<<"B\n"; assert(!err); #else Polynomial tp=p.exactlyDividedBy(fac1); Polynomial tAq=A->q.exactlyDividedBy(fac1); Polynomial tq=q.exactlyDividedBy(fac2); Polynomial tAp=A->p.exactlyDividedBy(fac2); p=tp*tAp; q=tq*tAq; #endif normalize(false); /* if(totalTerms!=p.numberOfTerms()+q.numberOfTerms()) { // debug<p<<"/"<q<<"\n"; p=pTemp; q=qTemp; p*=A->p; q*=A->q; normalize(); // debug<p<<"/"<q<<"\n"; // assert(0); }*/ //#endif #else p*=A->p; q*=A->q; normalize(); #endif } void operator+=(const FieldElementImplementation &a) { const FieldElementRationalFunction2 *A=(const FieldElementRationalFunction2*)&a; assert(A); p=p*A->q+A->p*q; q=A->q*q; normalize(); } void madd(const FieldElementImplementation &a,const FieldElementImplementation &b) { const FieldElementRationalFunction2 *A=(const FieldElementRationalFunction2*)&a; const FieldElementRationalFunction2 *B=(const FieldElementRationalFunction2*)&b; assert(A); assert(B); #if 0 p=p*(A->q*B->q)+(A->p*B->p)*q; q=A->q*B->q*q; normalize(); #else Polynomial fac1=polynomialGCD(B->p,A->q); Polynomial fac2=polynomialGCD(B->q,A->p); Polynomial tBp=B->p.exactlyDividedBy(fac1); Polynomial tAq=A->q.exactlyDividedBy(fac1); Polynomial tBq=B->q.exactlyDividedBy(fac2); Polynomial tAp=A->p.exactlyDividedBy(fac2); p=p*(tBq*tAq)+(tBp*tAp)*q; q=tBq*tAq*q; normalize(); #endif } FieldElementRationalFunction2 *one() const; bool isZero() const { return p.isZero(); } FieldElementRationalFunction2 *sum(const FieldElementImplementation &b)const { const FieldElementRationalFunction2 *B=(const FieldElementRationalFunction2*)&b; Polynomial fac1=polynomialGCD(q,B->q); Polynomial nq=B->q.exactlyDividedBy(fac1)*q; Polynomial np=p*B->q.exactlyDividedBy(fac1)+B->p*q.exactlyDividedBy(fac1); // It is still possible that more common factors exist. These must appear as factors of fac1 FieldElementRationalFunction2 *r= new FieldElementRationalFunction2(*getField(),np,nq); r->normalize(); // FieldElementRationalFunction2 *r= new FieldElementRationalFunction2(*getField(),p*B->q-B->p*q,B->q*q); return r; #if 0 const FieldElementRationalFunction2 *B=(const FieldElementRationalFunction2*)&b; // pout<q<<"------"<q.divides(q,"ient)) { // pout<q<<"+-----"<p*quotient,q); } else if(q.divides(B->q,"ient)) { return new FieldElementRationalFunction2(*getField(),B->p-p*quotient,B->q); } FieldElementRationalFunction2 *r= new FieldElementRationalFunction2(*getField(),p*B->q+B->p*q,B->q*q); return r; #endif } FieldElementRationalFunction2 *difference(const FieldElementImplementation &b)const { const FieldElementRationalFunction2 *B=(const FieldElementRationalFunction2*)&b; Polynomial fac1=polynomialGCD(q,B->q); Polynomial nq=B->q.exactlyDividedBy(fac1)*q; Polynomial np=p*B->q.exactlyDividedBy(fac1)-B->p*q.exactlyDividedBy(fac1); // It is still possible that more common factors exist. These must appear as factors of fac1 FieldElementRationalFunction2 *r= new FieldElementRationalFunction2(*getField(),np,nq); r->normalize(); // FieldElementRationalFunction2 *r= new FieldElementRationalFunction2(*getField(),p*B->q-B->p*q,B->q*q); return r; } FieldElementRationalFunction2 *negation()const { FieldElementRationalFunction2 *r= new FieldElementRationalFunction2(*getField(),p-p-p,q); return r; } FieldElementImplementation *inverse()const { if(isZero()) { AsciiPrinter P(Stderr); P.printString("Error inverting FieldElement: "); P.printPolynomial(p); P.printString(" "); P.printPolynomial(q); // P.printFieldElement(*this); P.printString("\n"); assert(0); } FieldElementRationalFunction2 *r= new FieldElementRationalFunction2(*getField(),q,p); return r; } int sign()const { assert(0);//not an ordered field (yet) if(isZero())return 0; return p.terms.rbegin()->second.sign(); } static string LaTeXTranslator(const string &s) { assert(0);//not supported yet /* int startIndex=0; string sign; if(s[0]=='-') { sign=string("-"); startIndex=1; } int slashIndex=-1; for(int i=startIndex;ip=p; r->q=q; return r; } }; PolynomialRing FieldRationalFunctions2Implementation::getPolynomialRing()const { return thePolynomialRing; } bool FieldRationalFunctions2Implementation::isRationals()const { return false; } int FieldRationalFunctions2Implementation::getCharacteristic()const { return this->getPolynomialRing().getField().getCharacteristic(); } FieldRationalFunctions2Implementation::FieldRationalFunctions2Implementation(PolynomialRing const &r): thePolynomialRing(r) { } std::string FieldRationalFunctions2Implementation::toString()const { stringstream s; s<< thePolynomialRing.getField().toString() << "("<(implementingObject.get()); #else FieldRationalFunctions2Implementation *imp=dynamic_cast(implementingObject); #endif Polynomial q=Term(imp->getPolynomialRing().getField().zHomomorphism(1),Monomial(imp->getPolynomialRing())); return new FieldElementRationalFunction2(*imp, p, q); } /***************************************************** * Conversion functions *****************************************************/ PolynomialRing makeVariablesParameters(PolynomialRing const &r, int numberOfParameters) { assert(numberOfParameters>=0); assert(numberOfParameters<=r.getNumberOfVariables()); vector names(numberOfParameters); for(int i=0;i names2(r.getNumberOfVariables()-numberOfParameters); for(int i=0;i(genericRing.getField().implementingObject.get()); #else FieldRationalFunctions2Implementation const *coefficientField=dynamic_cast(genericRing.getField().implementingObject); #endif FieldRationalFunctions2 &DANGER=(FieldRationalFunctions2&)genericRing.getField(); PolynomialRing coefRing=coefficientField->getPolynomialRing(); for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { FieldElement c=i->second; IntegerVector v=i->first.exponent; IntegerVector coefficientExponent=v.subvector(0,p.getRing().getNumberOfVariables()-genericRing.getNumberOfVariables()); IntegerVector monomialExponent=v.subvector(p.getRing().getNumberOfVariables()-genericRing.getNumberOfVariables(),v.size()); FieldElement c2=DANGER.polynomialToFraction(Term( c,Monomial(coefRing, coefficientExponent)));//does the numerator not belong to a field? ret+=Polynomial(Term(c2,Monomial(genericRing,monomialExponent))); } return ret; } PolynomialSet makeVariablesParameters(PolynomialRing const &genericRing, PolynomialSet const &p) { PolynomialSet ret(genericRing); for(PolynomialSet::const_iterator i=p.begin();i!=p.end();i++) ret.push_back(makeVariablesParameters(genericRing,*i)); return ret; } gfan0.6.2/src/packedmonomial.h0000644000175000017500000001553213122232611015611 0ustar andersanders/* * packedmonomial.h * * Created on: Feb 7, 2014 * Author: anders */ #ifndef PACKEDMONOMIAL_H_ #define PACKEDMONOMIAL_H_ #include #include #include "monomial.h" #include "printer.h" /* * This is an attempt to implement packed monomials in a similar way as Singular does. * Methods are designed for speed, not flexibility. * * Only non-negative values can be stored. That saves a few bits. */ //first entry in the packed representation is the weight //However, to look it up, we use the last entry in varaibleData class PacMan{ public: // For each original coordinate struct VariableData { int64 mask; int index; int shift; VariableData(int64 mask_, int index_, int shift_): mask(mask_), index(index_), shift(shift_) { } }; vector variableData; struct WordData { int64 overflowMasks; int freeBits; WordData(): overflowMasks(0), freeBits(64) { } }; vector wordData; int nWords;//number of 64 bit words in packed monomial int nExps;//number of varaibles in ring int64 overflowFlag;//If overflow happens with these variables, this should be set to non-zero VariableData alloc(int bitsNeeded, bool addOverflowBit) { int j; for(j=0;j=bitsNeeded+addOverflowBit)break; } if(j==wordData.size()) { wordData.push_back(WordData()); } VariableData ret=VariableData(((bitsNeeded<64)?(((int64)1)< bitsNeeded(IntegerVector const &maxEntries) { vector ret; for(int i=0;i=0); while(v>0){v>>1;l++;} ret.push_back(l); } return ret; } bool fits(IntegerVector const &v) { for(int i=0;i const &bounds, int nWeightBits): //bounds are without overflow bit overflowFlag(0) { assert(r.getNumberOfVariables()==bounds.size()); VariableData temp=alloc(nWeightBits,false); for(int i=0;i((i==variableData[j].index)?variableData[j].mask<(wordData[i].overflowMasks)<<" "; std::cerr<<"(overflow mask)\n"; } }; // Only use this class with "placement new" when NWORDS=0 // skal eksistere i to varianter // med fast antal words // med variabelt antal words, hvor stoerrelse laeses fra manager og plads til data opnaas ved "slicing" template class PackedMonomial{ int64 data[NWORDS]; public: PackedMonomial() { } PackedMonomial(int64 weight, IntegerVector const &exponent, PacMan const &man) { assert(NWORDS==0||NWORDS>=man.nWords);//Assume that manager does not use too many words int nWords=NWORDS?NWORDS:man.nWords; for(int i=0;i>man.variableData[i].shift; return ret; } void initializeZero(PacMan const &man) { int nExps=man.nExps; for(int i=0;i(data[i])<<" "; } /* bool compareLess(PackedMonomial const &b,PacMan const &man) { int nWords=NWORDS?NWORDS:man.nWords; int answer=0; for(int i=0;idata[i])answer=-1;}//write this without branches } return i<0; }*/ }; // For now we just assume that coefficients are one template class PackedPolynomial { vector > p; PackedPolynomial(IntegerVector const &weight, Polynomial const &p_, PacMan const &man) { for(TermMap::const_iterator i=p_.terms.begin();i!=p_.terms.end();i++) { p.push_back(PackedMonomial(dotLong(weight,i->first.exponent),i->first,man));//dot product may overflow } debug<<"SORTDISABLED"; // sort(p.begin(),p.end(),[](int a, int b) // { // return 1; // }); } void print(PacMan const &man) { // for(vector >::const_iterator i=p.begin();i!=p.end();i++)i->print(); for(int i=0;i #include #include "buchberger.h" #include "division.h" #include "tropical.h" #include "wallideal.h" #include "dimension.h" #include "halfopencone.h" #include "breadthfirstsearch.h" #include "tropicalbasis.h" #include "tropicalcurve.h" #include "linalg.h" #include "field_rationalfunctions2.h" #include "timer.h" #include "log.h" static Timer tropicalPrincipalIntersectionTimer("Tropical principal intersection",1); ////////////////////////////////////////////////////////////////////////// //Using stable intersections and rational functions PolynomialSet buildH(PolynomialSet const &g, IntegerVector const &isGeneric, bool noHomog=false) { int sum=isGeneric.sum(); int n=isGeneric.size(); PolynomialRing coefRing(g.getRing().getField(),sum); FieldRationalFunctions2 coefField(coefRing); PolynomialRing R(coefField,n-sum); PolynomialRing R3=R.withVariablesAppended("H"); PolynomialSet ret(R); for(PolynomialSet::const_iterator p=g.begin();p!=g.end();p++) { Polynomial q(R); for(TermMap::const_iterator i=p->terms.begin();i!=p->terms.end();i++) { IntegerVector coefv(sum);int IC=0; IntegerVector expv(n-sum);int IE=0; for(int j=0;jfirst.exponent[j]; } else { expv[IE++]=i->first.exponent[j]; } q+=Term(coefField.polynomialToFraction(Polynomial(Term(i->second,Monomial(coefRing,coefv)))),Monomial(R,expv)); // Polynomial p(coefRing); // p+=Term(i->m.c,Monomial(coefv)); } ret.push_back(q); } if(noHomog)return ret; return ret.homogenization(R3); //We must make sure that the ideal remains homogeneous when turning some variables into parameters. } IntegerVector reconstruct(IntegerVector const &v1, IntegerVector const &isGeneric) { int n=isGeneric.size(); IntegerVector v2(n); int I=0; for(int i=0;i1) { assert(iisZero())if(i->usedVariables().divides(isGeneric)){ OK=false;break;} } if(!OK) { isGeneric[i]=0; } else { d--; } i++; } // debug<<"d="<generatorsOfLinealitySpace(); assert(l.size()==2); for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { if(!groebnerBasis.isHomogeneous(reconstruct(*i,isGeneric))) return reconstruct(*i,isGeneric); } pout< toKeep=groebnerBasis.multiDeHomogenizationToKeep(); PolynomialSet ideal2=groebnerBasis.multiDeHomogenization(); IntegerVector v=nonTrivialTropismInner(ideal2); IntegerVector ret(groebnerBasis.numberOfVariablesInRing()); int I=0; for(list::const_iterator i=toKeep.begin();i!=toKeep.end();i++,I++) ret[*i]=v[I]; return ret; } static void startingConeError() { fprintf(Stderr,"UNABLE TO COMPUTE STARTING CONE.\n"); fprintf(Stderr,"THE STARTING CONE ALGORITHM IN GFAN IS BASED ON HEURISTICS WHICH HAVE FAILED ON THIS EXAMPLE.\n"); assert(0); } PolynomialSet initialIdeal(PolynomialSet const &g, IntegerVector const &weight) //Assume homogeneous { PolynomialSet ret=g; WeightReverseLexicographicTermOrder T(weight); buchberger(&ret,T); return initialForms(ret,weight); } PolynomialSet initialIdealNonHomogeneous(PolynomialSet const &g, IntegerVector const &weight, bool allowSaturation) { // We use Theorem 4 page 379 of [Cox, Little, O'Shea] (book 1) to compute the homogenization IntegerVector w(IntegerVector::allOnes(g.getRing().getNumberOfVariables())); WeightReverseLexicographicTermOrder T(w); PolynomialSet g2=g; buchberger(&g2,T,allowSaturation); PolynomialRing R2(g.getRing().getField(),g.getRing().getNumberOfVariables()+1); PolynomialSet g3=g2.homogenization(R2,&w); // We now compute the initial ideal using Proposition 5.2.3 in [Jensen] (PhD thesis). IntegerVector weight2=concatenation(weight,IntegerVector(1)); WeightTermOrder/*WeightReverseLexicographicTermOrder*/ T2(weight2);// The proposition assumes that weight2 is tie-broken with a term order, but that is probably not necessary. However, the specifications of _this_ routine says that a GB must be returned. buchberger(&g3,T2,allowSaturation); PolynomialSet g4=initialFormsAssumeMarked(g3,weight2); return g4.deHomogenization(); } Polynomial initialFormAssumeMarked(Polynomial const &p, IntegerVector const &weight) { Polynomial r(p.getRing()); IntegerVector markedExponent=p.getMarked().m.exponent; for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { IntegerVector dif=markedExponent-i->first.exponent; if(dot(dif,weight)==0) r+=Polynomial(Term(i->second,i->first)); } r.mark(Monomial(p.getRing(),markedExponent)); return r; } PolynomialSet initialFormsAssumeMarked(PolynomialSet const &groebnerBasis, IntegerVector const &weight) { PolynomialRing theRing=groebnerBasis.getRing(); PolynomialSet r(theRing); for(PolynomialSet::const_iterator i=groebnerBasis.begin();i!=groebnerBasis.end();i++) { r.push_back(initialFormAssumeMarked(*i,weight)); } return r; } Polynomial initialForm(Polynomial const &p, IntegerVector const &weight) { if(p.isZero())return p; int64 a=dotLong(p.terms.begin()->first.exponent,weight); for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { int64 b=dotLong(i->first.exponent,weight); if(b>a)a=b; } Polynomial r(p.getRing()); bool ismarked=p.isMarked(); IntegerVector markedExponent; if(ismarked)markedExponent=p.getMarked().m.exponent; bool markedFound=false; for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { if(dotLong(i->first.exponent,weight)==a) { r+=Polynomial(Term(i->second,i->first)); if(ismarked)if((markedExponent-(i->first.exponent)).isZero())markedFound=true; } } if(markedFound) r.mark(Monomial(p.getRing(),markedExponent)); return r; } PolynomialSet initialForms(PolynomialSet const &groebnerBasis, IntegerVector const &weight) { PolynomialRing theRing=groebnerBasis.getRing(); PolynomialSet r(theRing); if(theRing.getNumberOfVariables()!=weight.size()) { cerr << "Error: Number of varaibles in polynomial ring "<h) { if(!containsMonomial(wall)) { log1 fprintf(Stderr,"Iterating recursively.\n"); //PolynomialSet initialIdeal=guessInitialIdealWithoutMonomial(wall,0); PolynomialSet initialIdeal=guessInitialIdealWithoutMonomial(wall,fullNeighbourBasis,onlyCheckRays); if(fullNeighbourBasis) { //*fullNeighbourBasis=liftBasis(initialIdeal,h2); *fullNeighbourBasis=liftBasis(*fullNeighbourBasis,h2); } result=true; return initialIdeal; } } } result=false; return groebnerBasis; } IntegerVectorList perturbedRelativeInteriorTropism(PolynomialSet const &groebnerBasis) { int n=groebnerBasis.getRing().getNumberOfVariables(); // If T(I) is just the origin, we return the empty list PolynomialRing R(groebnerBasis.getRing().getField(),n+1); PolynomialSet g=groebnerBasis.homogenization(R); saturatedIdeal(g); if(krullDimension(g)==1)return IntegerVectorList(); // If the homogeneity space is non-trivial find a basis of it and reduce dimension PolyhedralCone hom=homogeneitySpace(g); if(hom.dimension()>1) { FieldMatrix m=integerMatrixToFieldMatrix(rowsToIntegerMatrix(hom.getEquations(),n+1),Q); m.reduce(); list toKeep=m.pivotColumns(); PolynomialRing R2=PolynomialRing(g.getRing().getField(),toKeep.size()); PolynomialSet i2=g.embeddedInto(R2,&toKeep); IntegerVectorList rl=perturbedRelativeInteriorTropism(i2); IntegerVectorList eq;eq.push_back(IntegerVector::standardVector(n+1,n)); PolyhedralCone C(IntegerVectorList(),eq,n+1);C=intersection(C,hom);C.canonicalize(); IntegerVectorList ret=C.projection(n).generatorsOfLinealitySpace(); for(IntegerVectorList::const_iterator j=rl.begin();j!=rl.end();j++) { IntegerVector temp(n+1); int I=0; for(list::const_iterator i=toKeep.begin();i!=toKeep.end();i++,I++) temp[*i]=(*j)[I]; ret.push_back(temp.subvector(0,n)-temp[n]*IntegerVector::allOnes(n)); } return ret; } IntegerVector v=nonTrivialTropism(groebnerBasis); IntegerVectorList ret=perturbedRelativeInteriorTropism(initialIdealNonHomogeneous(groebnerBasis,v,true)); //At this point it would make sense to "dehomogenize w.r.t. v", so that v is not repeated in the recursion. We could also simply choose not to push v. ret.push_front(v); return ret; /* saturate if dim=0 return empty; compute homogeneity space if homog>0 reduce dimension of ring/ideal call recursively lift list return else return nontrivialtropism */ } PolynomialSet guessInitialIdealWithoutMonomial(PolynomialSet const &groebnerBasis, PolynomialSet *fullNeighbourBasis, bool onlyCheckRays) //ideal must be homogeneous // fullNeighbourBasis is set to a Groebner basis of the full ideal. The returned basis and fullNeighbourBasis have at least one termorder in common { if(1) { IntegerVectorList w=perturbedRelativeInteriorTropism(groebnerBasis); MatrixTermOrder T(w); PolynomialSet g=groebnerBasis; buchberger(&g,T);//assuming that g is homogeneous PolynomialSet ig=g; for(IntegerVectorList::const_iterator i=w.begin();i!=w.end();i++)ig=initialForms(ig,*i); assert(fullNeighbourBasis); *fullNeighbourBasis=g; return ig; } // log0 fprintf(Stderr,"A\n"); assert(groebnerBasis.isValid()); // log0 fprintf(Stderr,"B\n"); if(fullNeighbourBasis) { assert(fullNeighbourBasis->isValid()); } // log0 fprintf(Stderr,"C\n"); int n=groebnerBasis.numberOfVariablesInRing(); // log0 fprintf(Stderr,"D\n"); int h=dimensionOfHomogeneitySpace(groebnerBasis); // log0 fprintf(Stderr,"E\n"); int d=krullDimension(groebnerBasis); // log0 fprintf(Stderr,"F\n"); if(d==h) { if(fullNeighbourBasis)*fullNeighbourBasis=groebnerBasis; return groebnerBasis; } #if 0 // stable intersections/rational functions { IntegerVectorList toCheck; // pout<h) { if(nonEmptyStableIntersection(wall)) { log1 fprintf(Stderr,"Iterating recursively.\n"); //PolynomialSet initialIdeal=guessInitialIdealWithoutMonomial(wall,0); PolynomialSet initialIdeal=guessInitialIdealWithoutMonomialStably(wall,fullNeighbourBasis,onlyCheckRays); if(fullNeighbourBasis) { //*fullNeighbourBasis=liftBasis(initialIdeal,h2); // *fullNeighbourBasis=liftBasis(*fullNeighbourBasis,h2); *fullNeighbourBasis=groebnerBasis; fullNeighbourBasis->copyMarkings(initialIdeal); } result=true; return initialIdeal; } } } result=false; return groebnerBasis; } PolynomialSet guessInitialIdealWithoutMonomialStably(PolynomialSet const &groebnerBasis, PolynomialSet *fullNeighbourBasis, bool onlyCheckRays) //ideal must be homogeneous // fullNeighbourBasis is set to a Groebner basis of the full ideal. The returned basis and fullNeighbourBasis have at least one termorder in common { int n=groebnerBasis.numberOfVariablesInRing(); int h=dimensionOfHomogeneitySpace(groebnerBasis); int d=n-groebnerBasis.size();//krullDimension(groebnerBasis); debug<v.size(); LPColSet cols(width,width*height); DSVector c1(height); //Build Cols for(IntegerVectorList::const_iterator j=g.begin();j!=g.end();j++) { c1.clear(); for(int t=0;tv[t]!=0) c1.add(t,(double)(j->v[t])); if(j!=i) { Real obj=0; Real upper=infinity; Real lower=0; cols.add(obj,lower,c1,upper); } } LPRowSet rows(height,width*height); DSVector r1(width); //Change Rows for(int t=0;tv[t],r1,i->v[t]); addRows(rows); addCols(cols); changeSense(SPxLP::MINIMIZE); assert(isConsistent()); } void buildType2(int n, const IntegerVectorList &inequalities, const IntegerVectorList &equations) { int width=n; int nInequalities=inequalities.size(); int height=inequalities.size()+equations.size(); IntegerMatrix m=rowsToIntegerMatrix(inequalities,n); m.append(rowsToIntegerMatrix(equations,n)); LPColSet cols(width,width*height); DSVector c1(height); //Build Cols for(int i=0;i0)return false; return true; } /* for(IntegerVectorList::const_iterator j=g.begin();j!=g.end();j++) { /* double prod=0; for(int i=0;i=0)return false; for(int i=1;i solution(work.nCols()); for(int i=0;i solutionNum; int denominator; doubleVectorToFractions(solution,solutionNum,denominator); IntegerVector s(solution.size()); for(int i=0;i certificate(work.nRows()); for(int i=0;i certificateNum; int denominator; doubleVectorToFractions(certificate,certificateNum,denominator); IntegerVector c(certificate.size()); for(int i=0;i solution(work.nCols()); for(int i=0;i solutionNum; int denominator; doubleVectorToFractions(solution,solutionNum,denominator); IntegerVector s(solution.size()); for(int i=0;isize()==solution.size()); for(int j=0;jsize();j++)S+=solution[j]*(*i)[j]; if(S>-0.000001 && S<0.000001)A.push_back(*i); } FieldMatrix temp=integerMatrixToFieldMatrix(rowsToIntegerMatrix(A,solution.size()),Q); FieldMatrix temp2=temp.reduceAndComputeKernel(); for(int i=0;i certificate(work.nRows()); for(int i=0;i certificateNum; int denominator; doubleVectorToFractions(certificate,certificateNum,denominator); IntegerVector c(certificate.size()); for(int i=0;i #include #include "polyhedralcone.h" #include "polynomial.h" #include "printer.h" #include "matrix.h" class SymmetryGroup; typedef set PolyhedralConeList; typedef map IncidenceList; enum FanPrintingFlags{ FPF_conesCompressed=1, FPF_conesExpanded=2, FPF_cones=4, FPF_maximalCones=8, FPF_boundedInfo=16, FPF_values=32, FPF_group=64, FPF_multiplicities=128, FPF_xml=256, FPF_tPlaneSort=512, FPF_primitiveRays=1024, FPF_default=2+4+8 }; /** A PolyhedralFan is simply a collection of canonicalized PolyhedralCones. * It contains no combinatorial information in the sense of a polyhedral complex. * A cone being present in the PolyhedralFan corresponds to the cone and all its facets being present * in the mathematical object. * The intersection of cones in the fan must be a face of both. * In particular all cones in a PolyhedralFan have the same lineality space.*/ class PolyhedralFan { int n; PolyhedralConeList cones; public: static IntegerVector stableRay(PolyhedralCone const &c, SymmetryGroup const *sym); static IntegerVector stableRay(IntegerVector const &v, IntegerVectorList const &equations, IntegerVectorList const &inequalities, SymmetryGroup const *sym); static class PolyhedralFan bergmanOfPrincipalIdeal(Polynomial const &p); static class PolyhedralFan normalFanOfNewtonPolytope(Polynomial const &p); static class PolyhedralFan fullSpace(int n); static class PolyhedralFan halfSpace(int n, int i); static class PolyhedralFan facetsOfCone(PolyhedralCone const &c); /** This routine computes a fan F with minimal support with the following property: the cone can be inserted to (is compatible with) F and this will make F complete. The support of F is the closure of the complement of C. If includec is true then C is indeed inserted into F before returning. */ static class PolyhedralFan complementOfCone(PolyhedralCone const &c, bool includec=false); PolyhedralFan(int ambientDimension); void print(class Printer *p)const; //void printWithIndices(class Printer *p, SymmetryGroup *sym=0, const char *polymakeFileName=0)const; //fan must be pure vector renamingStrings(IntegerVectorList const &theVectors, IntegerVectorList const &originalRays, IntegerVectorList const &linealitySpace, SymmetryGroup *sym)const; void printWithIndices(class Printer *p, int flags=FPF_default, SymmetryGroup *sym=0, vector const *comments=0)const; // void printWithIndices(class Printer *p, bool printMultiplicities, SymmetryGroup *sym, bool group=false, bool ignoreCones=false, bool xml=false, bool tPlaneSort=false, vector const *comments=0)const; /* Read in a polyhedral fan, but with the cones containing w. If present, only read in cones among coneIndices. If sym is present, read COMPRESSED section and make w containment up to symmetry, taking all elements in the orbit that contains w into the fan. If onlyMaximal is set then only maximal cones are read in. */ static PolyhedralFan readFan(string const &filename, bool onlyMaximal=true, IntegerVector *w=0, set const *conesIndice=0, SymmetryGroup const *sym=0, bool readCompressedIfNotSym=false); int getAmbientDimension()const; int getMaxDimension()const; int getMinDimension()const; friend PolyhedralFan refinement(const PolyhedralFan &a, const PolyhedralFan &b, int cutOffDimension, bool allowASingleConeOfCutOffDimension, bool stable); friend PolyhedralFan product(const PolyhedralFan &a, const PolyhedralFan &b); IntegerVectorList getRays(int dim=1);//This can be called for other dimensions than 1. The term "Rays" still makes sense modulo the common linearity space IntegerVectorList getRelativeInteriorPoints(); PolyhedralCone const& highestDimensionalCone()const; //returns one of the cones in the fan with highest dimension PolyhedralCone convexHull()const; void insert(PolyhedralCone const &c); void insertFacetsOfCone(PolyhedralCone const &c); void remove(PolyhedralCone const &c); void removeAllExcept(int a); //deletes all except the first a cones void removeAllLowerDimensional(); /** Since the cones stored in a PolyhedralFan are cones of a polyhedral fan, it is possible to identify non maximal cones by just checking containment of relative interior points in other cones. This routine removes all non-maximal cones. */ void removeNonMaximal(); /** Returns the number of cones stored in the fan. This is not the number of cones in the fan in a mathematical sense. */ int size()const; int dimensionOfLinealitySpace()const; void makePure(); bool contains(PolyhedralCone const &c)const; /** * For a vector contained in the support of the fan represented by the fan object, this function * computes the cone that contains the vector in its relative interior. */ PolyhedralCone coneContaining(IntegerVector const &v)const; PolyhedralFan facetComplex()const; /** This routine computes all cones in the fan and returns them as a new PolyhedralFan. This routine is extremely slow. */ PolyhedralFan fullComplex()const; PolyhedralFan facetComplexSymmetry(SymmetryGroup const &sym, bool keepRays=false, bool dropLinealitySpace=false)const; PolyhedralFan rayComplexSymmetry(SymmetryGroup const &sym)const; IntegerVectorList getRaysInPrintingOrder(SymmetryGroup const *sym, bool upToSymmetry=false)const; IncidenceList getIncidenceList(SymmetryGroup *sym=0)const; bool isEmpty()const; bool isRefinementOf(PolyhedralFan const &f)const; /** Computes the link of the face containing w in its relative interior. */ PolyhedralFan link(IntegerVector const &w)const; PolyhedralFan link(IntegerVector const &w, SymmetryGroup *sym)const; /** If the cones have been assigned linear forms then this specifies a piecewise linear function on the support of the fan. This routine evaluates that linear function. */ int64 evaluatePiecewiseLinearFunction(IntegerVector const &x)const; typedef PolyhedralConeList::const_iterator coneIterator; PolyhedralFan::coneIterator conesBegin()const; PolyhedralFan::coneIterator conesEnd()const; /** Computes the volume of the d-dimensional cones stored in the fan. If the symmetry group is specified each volume of a cone is multiplied by the size of its orbit. */ FieldElement volume(int d, SymmetryGroup *sym=0)const; /** Assuming that the fan is pure, this function tests whether the fan is connected in codimension 1. IF SYMMETRY IS SPECIFIED THEN THE CHECK IS NOT COMPLETE AND IT WILL ONLY BE CHECKED IF THAT GIVEN TWO CONES THAT EXIST ELEMENTS IN THE TWO RESPECTIVE ORBITS WHICH ARE CONNECTED BY A RIDGE PATH. */ bool isConnected(SymmetryGroup *sym=0)const; PolyhedralFan negated()const; /** Checks if c can be inserted in the fan without violating the fan axioms. Very slow. */ bool isCompatible(PolyhedralCone const &c)const; /** Change the polyhedral structure of the fan and add in the cone c. Overlap of c and the cones are allowed. This routine is extremely slow. */ void merge(PolyhedralCone const &c); /** * Converts a PolyhedralFan into a SymmetricComplex. This is used for homology computations, but not for printing yet. */ class SymmetricComplex toSymmetricComplex(SymmetryGroup *sym); /** * This routine deletes the cones from the polyhedral fan and appends them to v. */ void moveConesToVector(vector &v); /** * Removes all lower dimensional faces of the fan and returns exactly the equations, * which the multiplicities of the facets must satisfy in order for the fan to be * tropically balanced. */ IntegerMatrix balancingEquations(); /** * Checks if w is contained in the support of the fan. */ bool containsInSupport(IntegerVector const &w); /** * Returns a triangulation of the fan. */ PolyhedralFan triangulation()const; }; PolyhedralFan refinement(const PolyhedralFan &a, const PolyhedralFan &b, int cutOffDimension=-1, bool allowASingleConeOfCutOffDimension=false, bool stable=false); void addFacesToSymmetricComplex(class SymmetricComplex &c, PolyhedralCone const &cone, IntegerVectorList const &facetCandidates, IntegerVectorList const &generatorsOfLinealitySpace); void addFacesToSymmetricComplex(SymmetricComplex &c, set const &indices, IntegerVectorList const &facetCandidates, int dimension, int multiplicity); #endif gfan0.6.2/src/app_tropicalbruteforce.cpp0000644000175000017500000000636013122232611017716 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "polyhedralfan.h" #include "breadthfirstsearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "timer.h" #include "dimension.h" #include "tropical.h" #include "tropical2.h" #include "log.h" class TropicalBruteForceApplication : public GFanApplication { //SimpleOption OptionTPlane; public: const char *helpText() { return "This program takes a marked reduced Groebner basis for a homogeneous ideal and computes the tropical " "variety of the ideal as a subfan of the Groebner fan. " "The program is slow but works for any homogeneous ideal. If " "you know that your ideal is prime over the complex numbers or you " "simply know that its tropical variety is pure and connected in " "codimension one then use gfan_tropicalstartingcone and " "gfan_tropicaltraverse instead.\n"; } TropicalBruteForceApplication() { registerOptions(); } const char *name()//: // OptionTPlane("--tplane","This option intersect the resulting { return "_tropicalbruteforce"; } int main() { FileParser p(Stdin); PolynomialRing r=p.parsePolynomialRing(); PolynomialSet G=p.parsePolynomialSet(r); if(!isMarkingConsistent(G)) { fprintf(Stderr,"Input polynomial set is not marked consistently.\n"); assert(0); } if(!isMarkedGroebnerBasis(G)) { fprintf(Stderr,"Input polynomial set is not a marked Groebner basis.\n"); assert(0); } autoReduce(&G, LexicographicTermOrder()); int homog=dimensionOfHomogeneitySpace(G); int n=r.getNumberOfVariables(); IntegerVector f=IntegerVector(n-homog+1); IntegerVector fTrop=IntegerVector(n-homog+1); // ReverseLexicographicTermOrder A; LexicographicTermOrder A; ReverseSearch rs(A); EnumerationTargetCollector C; rs.setEnumerationTarget(&C); rs.enumerate(G); PolynomialSetList glist=C.getList(); PolyhedralFan result(n); for(PolynomialSetList::const_iterator j=glist.begin();j!=glist.end();j++) { PolynomialSet g=*j; PolyhedralCone c=groebnerCone(g,true); PolyhedralFan F(n); F.insert(c); for(int i=0;i #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "breadthfirstsearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "field_rationalfunctions2.h" #include "gfanapplication.h" #include "timer.h" #include "log.h" #include "traverser_groebnerfan.h" class GroebnerFanApplication : public GFanApplication { SimpleOption optionInputIsGroebnerBasis; SimpleOption optionSymmetry; SimpleOption optionDisableSymmetryTest; StringOption optionRestrictingFan; //StringOption optionRestrictingFanSymmetry; IntegerOption optionParameters; SimpleOption optionIgnoreCones; InterruptOption optionInterrupt; public: const char *helpText() { return "This is a program for computing the Groebner fan of a polynomial ideal as a polyhedral complex. It takes a generating set for the ideal as input. If the ideal is symmetric the symmetry option is useful and enumeration will be done up to symmetry. The program needs a starting Groebner basis to do its computations. If the -g option is not specified it will compute one using Buchberger's algorithm.\n"; } GroebnerFanApplication(): optionInputIsGroebnerBasis("-g", "Tells the program that the input is already a Groebner basis (with the initial term of each polynomial being " "the first ones listed). Use this option if it takes too much time to compute " "the starting (standard degree lexicographic) Groebner basis and the input is already a Groebner basis.\n"), optionSymmetry("--symmetry", "Tells the program to read in generators for a group of symmetries (subgroup of $S_n$) after having read in the ideal. The program checks that the ideal stays fixed when permuting the variables with respect to elements in the group. The program uses breadth first search to compute the set of reduced Groebner bases up to symmetry with respect to the specified subgroup.\n"), optionDisableSymmetryTest("--disableSymmetryTest","When using --symmetry this option will disable the check that the group read off from the input actually is a symmetry group with respect to the input ideal.\n"), optionRestrictingFan("--restrictingfan","Specify the name of a file containing a polyhedral fan in Polymake format. The computation of the Groebner fan will be restricted to this fan. If the --symmetry option is used then this restricting fan must be invariant under the symmetry and the orbits in the file must be with respect to the specified group of symmetries. The orbits of maximal cones of the file are then read in rather than the maximal cones.\n",0), //optionRestrictingFan("--restrictingfansymmetry","Use this option to indicate that the restricting fan also has the same symmetries.\n",0), optionParameters("--parameters","With this option you can specify how many variables to treat as parameters instead of variables. This makes it possible to do computations where the coefficient field is the field of rational functions in the parameters.",0), optionIgnoreCones("--nocones","Tells the program not to output the CONES and MAXIMAL_CONES sections, but still output CONES_COMPRESSED and MAXIMAL_CONES_COMPRESSED if --symmetry is used.") { registerOptions(); } const char *name() { return "_groebnerfan"; } int main() { LexicographicTermOrder myOrder; PolynomialSet g=FileParser(Stdin).parsePolynomialSetWithRing(); if(optionParameters.getValue())g=makeVariablesParameters(makeVariablesParameters(g.getRing(),optionParameters.getValue()),g); int n=g.numberOfVariablesInRing(); if(optionInputIsGroebnerBasis.getValue()) { log1 fprintf(Stderr,"Minimizing and autoreducing input...\n"); minimize(&g); autoReduce(&g, LexicographicTermOrder()); } else { log1 fprintf(Stderr,"Computing Groebner Basis...\n"); buchberger(&g,StandardGradedLexicographicTermOrder()); log2 AsciiPrinter(Stderr).printPolynomialSet(g); } log1 fprintf(Stderr,"A reduced Groebner basis has been computed\n"); SymmetryGroup s(n); IntegerVectorList generators; if(optionSymmetry.getValue()) generators=FileParser(Stdin).parseIntegerVectorList(); if(!optionDisableSymmetryTest.getValue()) { for(IntegerVectorList::iterator i=generators.begin();i!=generators.end();i++) { assert(areIdealsEqual(g,SymmetryGroup::permutePolynomialSet(g,*i))); } } s.computeClosure(generators); s.createTrie(); log3 s.print(Stderr); SymmetricTargetFanBuilder target(n,s); if(!optionRestrictingFan.getValue()) { GroebnerFanTraverser traverser(g); SymmetricTargetCounterInterrupted target2(target,optionInterrupt.getValue()); symmetricTraverse(traverser,target2,&s); } else { //PolyhedralFan f1=PolyhedralFan::readFan(optionRestrictingFan.getValue()); //static PolyhedralFan readFan(string const &filename, bool onlyMaximal=true, IntegerVector *w=0, set const *conesIndice=0, SymmetryGroup const *sym=0, bool readCompressedIfNotSym=false); PolyhedralFan f1=PolyhedralFan::readFan(optionRestrictingFan.getValue(),true,0,0,/*optionSymmetry.getValue()?&s:0*/0,true); for(PolyhedralFan::coneIterator i=f1.conesBegin();i!=f1.conesEnd();i++) { static int t; log2 cerr<<"Processing Cone "<dimension()< #include "parser.h" #include "printer.h" #include "polynomial.h" #include "buchberger.h" #include "wallideal.h" #include "termorder.h" #include "gfanapplication.h" #include "determinantpoly.h" #include "log.h" using namespace std; class InitialDeterminantApplication : public GFanApplication { public: bool includeInDefaultInstallation() { return false; } SimpleOption optionTakeDerivatives; const char *helpText() { return "This program \n"; } InitialDeterminantApplication(): optionTakeDerivatives("-j","Take derivatives of input vector.") { registerOptions(); } const char *name() { return "_initialdeterminant"; } int main() { FileParser P(Stdin); PolynomialSet g=P.parsePolynomialSetWithRing(); if(optionTakeDerivatives.getValue()) { PolynomialSet G=P.parsePolynomialSet(g.getRing()); G.markAndScale(LexicographicTermOrder()); PolynomialSet::iterator I=g.begin(); for(PolynomialSet::const_iterator i=G.begin();i!=G.end();i++,I++) { *I=Term(i->getMarked().c,Monomial(g.getRing(),-(i->getMarked().m.exponent)))**I; } debug< rows=interval(g.size(),!optionTakeDerivatives.getValue()); list columns=interval(g.size(),!optionTakeDerivatives.getValue()); cerr< #include "parser.h" #include "printer.h" #include "polynomial.h" #include "buchberger.h" #include "wallideal.h" #include "termorder.h" #include "gfanapplication.h" #include "tropical2.h" #include "tropicaldeterminant.h" #include "log.h" using namespace std; class PolyMatrix { public: class PolyMatrixEntry { public: bool isZero; Polynomial p; int maxDegree,minDegree; vector forms; PolyMatrixEntry(Polynomial const &p_, IntegerVector const &w): p(p_), isZero(p_.isZero()) { if(p.isZero()) { maxDegree=-1; minDegree=0; return; } maxDegree=p_.degree(w); minDegree=-p_.degree(-w); // debug<first.exponent,w)]+=Term(i->second,i->first); } } }; list::iterator indexOfSparsestRow(list &rows, list const &columns) { list::iterator ret=rows.end(); int bestNumberOfZeros=-1; for(list::iterator i=rows.begin();i!=rows.end();i++) { int numberOfZeros=0; for(list::const_iterator j=columns.begin();j!=columns.end();j++)numberOfZeros+=data[*i][*j].isZero; if(numberOfZeros>bestNumberOfZeros) { bestNumberOfZeros=numberOfZeros; ret=i; } } // cerr<<":"< > data; PolynomialRing theRing; //constructor for Jacobi matrix PolyMatrix(PolynomialSet const &generators, IntegerVector const &w): theRing(generators.getRing()) { int n=generators.size(); PolynomialSet::const_iterator I=generators.begin(); for(int i=0;i row; for(int j=0;jderivative(j); // debug< l) { cerr<<"{"; for(list::const_iterator i=l.begin();i!=l.end();i++) cerr<<*i<<","; cerr<<"}\n"; } Polynomial determinantForm(list rows, list columns, int degree, int level) { Polynomial ret(theRing); if(rows.size()==1)return data[rows.front()][columns.front()].p; list::iterator chosenRowIterator=indexOfSparsestRow(rows, columns);//rows.begin(); int chosenrow=*chosenRowIterator; { list::iterator temp=chosenRowIterator;temp++; rows.erase(chosenRowIterator); //no need to update rows afterwards since it is stored on the stack } if(level==0)cerr<<"-"<::iterator i=columns.begin();i!=columns.end();i++) { int chosencol=*i; if(!data[chosenrow][chosencol].isZero) { list::iterator temp=i;temp++; columns.erase(i); i=temp; ret+=data[chosenrow][chosencol].p*determinantForm(rows,columns,degree,level+1)*theRing.getField().zHomomorphism(sign); columns.insert(i,chosencol); i--; } sign*=-1; } rows.push_front(chosenrow); return ret; } }; class InitialDeterminantApplication : public GFanApplication { public: const char *helpText() { return "This program \n"; } InitialDeterminantApplication() { registerOptions(); } char *name() { return "_initialdeterminant"; } list interval(int n) { list ret; for(int i=0;i rows=interval(g.size()); list columns=interval(g.size()); pout< #include "buchberger.h" #include "enumeration.h" #include "reversesearch.h" #include "wallideal.h" #include "printer.h" #include "parser.h" #include "newtonpolytope.h" #include "subspace.h" #include "lp.h" #include "log.h" static void saveList(IntegerVectorList const &l, char const *name) { FILE *f=fopen(name,"w"); if(f) { AsciiPrinter P(f); P<=1000) saveList(interiorPoints,"partialresult"); counter=0; } } }; /* This Cone processor saves memory when doing up to symmetry computations where orbits can be repeated */ class HalfOpenConeProcessorConeCollector : public HalfOpenConeProcessor { public: HalfOpenConeList theList; void process(HalfOpenCone const &c, IntegerVector const &chosenFans, IntegerVector const &chosenCone) { theList.push_back(c); } }; static void printHalfOpenCone(Printer &P, HalfOpenCone c) { P.printPolyhedralCone(c.closure()); } static void printHalfOpenConeList(Printer &P, HalfOpenConeList const &l) { P.printString("Begin HalfOpenConeList\n"); for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) printHalfOpenCone(P,*i); P.printString("End HalfOpenConeList\n"); } bool HalfOpenCone::contains(IntegerVector const &v)const { IntegerVectorList inequalityList=lifted.getHalfSpaces(); IntegerVectorList equationList=lifted.getEquations(); IntegerVectorList strict,nonstrict; for(IntegerVectorList::const_iterator i=inequalityList.begin();i!=inequalityList.end();i++) if((*i)[i->size()-1]<0) strict.push_back(*i); else if((*i)[i->size()-1]==0) nonstrict.push_back(*i); else {//CHANGED assert(i->subvector(0,i->size()-1).isZero()); strict.push_back(*i); } for(IntegerVectorList::const_iterator i=equationList.begin();i!=equationList.end();i++) if(dotLong(i->subvector(0,i->size()-1),v)!=0)return false; for(IntegerVectorList::const_iterator i=nonstrict.begin();i!=nonstrict.end();i++) if(dotLong(i->subvector(0,i->size()-1),v)<0)return false; for(IntegerVectorList::const_iterator i=strict.begin();i!=strict.end();i++) if(dotLong(i->subvector(0,i->size()-1),v)<=0)return false; return true; } void HalfOpenCone::appendList(IntegerVectorList &to, IntegerVectorList const &from, int appendValue) { for(IntegerVectorList::const_iterator i=from.begin();i!=from.end();i++) { IntegerVector v=*i; v.resize(v.size()+1); v[v.size()-1]=appendValue; to.push_back(v); } } HalfOpenCone::HalfOpenCone(int dimension_, PolyhedralCone const &lifted_): dimension(dimension_), liftedDimension(dimension_+1), lifted(lifted_) { // lifted.findFacets(); } HalfOpenCone::HalfOpenCone(int dimension_, IntegerVectorList const &equations, IntegerVectorList const &nonstrict, IntegerVectorList const &strict, bool findFacets, bool canonicalize): dimension(dimension_), liftedDimension(dimension_+1), lifted(dimension_+1) { IntegerVectorList equationList,inequalityList; appendList(equationList,equations,0); appendList(inequalityList,nonstrict,0); appendList(inequalityList,strict,-1); inequalityList.push_back(IntegerVector::standardVector(liftedDimension,dimension)); //CHANGED // AsciiPrinter(Stderr).printVectorList(inequalityList); // AsciiPrinter(Stderr).printVectorList(equationList); // AsciiPrinter(Stderr).printInteger(liftedDimension); lifted=PolyhedralCone(inequalityList,equationList,liftedDimension); if(findFacets)lifted.findFacets(); if(canonicalize)lifted.canonicalize(); } HalfOpenCone::HalfOpenCone(PolyhedralCone C, TermOrder const &t): dimension(C.ambientDimension()), liftedDimension(C.ambientDimension()+1), lifted(C.ambientDimension()+1) { HalfOpenConeList ret; C.findFacets(); assert(C.dimension()==C.ambientDimension()); IntegerVectorList facets=C.getHalfSpaces(); IntegerVectorList strictList,nonStrictList; for(IntegerVectorList::const_iterator i=facets.begin();i!=facets.end();i++) { if(t(*i,*i-*i)) strictList.push_back(*i); else nonStrictList.push_back(*i); } IntegerVectorList inequalityList; appendList(inequalityList,nonStrictList,0); appendList(inequalityList,strictList,-1); inequalityList.push_back(IntegerVector::standardVector(liftedDimension,dimension)); //CHANGED IntegerVectorList empty; lifted=PolyhedralCone(inequalityList,empty,liftedDimension); // if(findFacets)lifted.findFacets(); } HalfOpenCone::HalfOpenCone(int ambientDimension): dimension(ambientDimension), liftedDimension(ambientDimension+1), lifted(ambientDimension+1) { IntegerVectorList inequalityList; inequalityList.push_back(IntegerVector::standardVector(liftedDimension,dimension)); IntegerVectorList empty; lifted=PolyhedralCone(inequalityList,empty,liftedDimension); } static IntegerVectorList swapFirstLast(const IntegerVectorList &l) { IntegerVectorList ret; for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { IntegerVector v=*i; int t=v[0]; v[0]=v[v.size()-1]; v[v.size()-1]=t; ret.push_back(v); } return ret; } bool HalfOpenCone::isEmpty() { bool ret1=!hasHomogeneousSolution(liftedDimension, swapFirstLast(lifted.getHalfSpaces()), swapFirstLast(lifted.getEquations()) ); /* IntegerVectorList inequalityList; inequalityList.push_back(IntegerVector::standardVector(liftedDimension,dimension)); PolyhedralCone temp=intersection(lifted,PolyhedralCone(inequalityList,IntegerVectorList(),liftedDimension)); IntegerVector v=temp.getRelativeInteriorPoint(); // AsciiPrinter(Stderr).printVector(v); bool ret2=(v[dimension]==0); */ /* fprintf(Stderr,"Inequalities:\n"); AsciiPrinter(Stderr).printVectorList(lifted.getHalfSpaces()); fprintf(Stderr,"Equations:\n"); AsciiPrinter(Stderr).printVectorList(lifted.getEquations()); fprintf(Stderr,"hasSolution=%i\n",ret1); */ // assert(ret1==ret2); return ret1; } bool haveEmptyIntersection(const HalfOpenCone &a, const HalfOpenCone &b) { // {static int i;cerr<<"emptyintersectiontest"<<++i<<"\n";} assert(a.dimension==b.dimension); IntegerVectorList inequalityList=a.lifted.getHalfSpaces(); IntegerVectorList equationList=a.lifted.getEquations(); IntegerVectorList inequalityList2=b.lifted.getHalfSpaces(); IntegerVectorList equationList2=b.lifted.getEquations(); inequalityList.splice(inequalityList.begin(),inequalityList2); equationList.splice(equationList.begin(),equationList2); bool ret1=!hasHomogeneousSolution(a.liftedDimension,swapFirstLast(inequalityList),swapFirstLast(equationList)); /* HalfOpenCone c=intersection(a,b); if(c.isEmpty()!=ret1) { AsciiPrinter(Stderr).printVectorList(inequalityList); AsciiPrinter(Stderr).printVectorList(equationList); AsciiPrinter(Stderr).printVectorList(c.lifted.getHalfSpaces()); AsciiPrinter(Stderr).printVectorList(c.lifted.getEquations()); fprintf(Stderr,"hasHomogeneousSolution siger %i\n",!ret1); assert(0); } */ return ret1; } /*bool HalfOpenCone::isEmpty() { IntegerVector v(liftedDimension); v[dimension]=-1; IntegerVectorList equationList,inequalityList; inequalityList.push_back(v); PolyhedralCone c(inequalityList,equationList,liftedDimension); PolyhedralCone c2=intersection(c,lifted); lifted.canonicalize(); c2.canonicalize(); return !(c2!=lifted); }*/ HalfOpenCone intersection(const HalfOpenCone &a, const HalfOpenCone &b, bool findFacets) { assert(a.dimension==b.dimension); /* fprintf(Stderr,"-----------------------------------------------------------\n"); fprintf(Stderr,"Intersecting:\n"); AsciiPrinter P(Stderr); printHalfOpenCone(P,a); printHalfOpenCone(P,b); */ // {static int i;cerr<<++i<<"\n";} HalfOpenCone ret=HalfOpenCone(a.dimension,intersection(a.lifted,b.lifted)); { static int t; t++; if((!(t&7))||findFacets)ret.lifted.findFacets(); //1 4:53 //3 3:38 //7 } /* fprintf(Stderr,"Result:\n"); printHalfOpenCone(P,ret); fprintf(Stderr,"Is empty:%i\n",ret.isEmpty()); fprintf(Stderr,"-----------------------------------------------------------\n"); fprintf(Stderr,"States: %i,%i,%i\n",a.lifted.getState(),b.lifted.getState(),ret.lifted.getState()); fprintf(Stderr,"-----------------------------------------------------------\n"); */ return ret; } IntegerVectorList HalfOpenCone::shrink(const IntegerVectorList &l) { IntegerVectorList ret; for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) ret.push_back(i->subvector(0,i->size()-1)); return ret; } PolyhedralCone HalfOpenCone::closure() { lifted.findFacets(); return PolyhedralCone(shrink(lifted.getHalfSpaces()),shrink(lifted.getEquations()),dimension); } /* */ HalfOpenConeList orientedBoundary(PolyhedralCone C, TermOrder const &t, HalfOpenCone *restrictingCone) { int dimension=C.ambientDimension(); HalfOpenConeList ret; C.findFacets(); assert(C.dimension()==C.ambientDimension()); IntegerVectorList facets=C.getHalfSpaces(); IntegerVectorList strictList,nonStrictList; for(IntegerVectorList::const_iterator i=facets.begin();i!=facets.end();i++) { if(t(*i,*i-*i)) strictList.push_back(*i); else nonStrictList.push_back(*i); } // log0 AsciiPrinter(Stderr).printVectorList(strictList); // log0 AsciiPrinter(Stderr).printVectorList(nonStrictList); // Let's make the non-strict inequalities strict one at a time and add a cone for each iteration while(!nonStrictList.empty()) { // fprintf(Stderr,"NEWWALL\n"); IntegerVector v=nonStrictList.front(); nonStrictList.pop_front(); IntegerVectorList equationList; equationList.push_back(v); { HalfOpenCone c(dimension,equationList,nonStrictList,strictList,true); if(restrictingCone) c=intersection(*restrictingCone,c,true); if(!c.isEmpty())ret.push_back(c); } strictList.push_back(v); } return ret; } HalfOpenConeList tropicalHyperSurface(Polynomial const &p1) { PolynomialRing theRing=p1.getRing(); PolynomialRing theSecondRing=theRing.withVariablesAppended("H"); Polynomial p=p1.homogenization(theSecondRing); HalfOpenConeList ret; PolynomialSet g(theRing); g.push_back(p); buchberger(&g,LexicographicTermOrder()); EnumerationTargetCollector gfan; LexicographicTermOrder myTermOrder; ReverseSearch rs(myTermOrder); rs.setEnumerationTarget(&gfan); fprintf(Stderr,"Starting enumeratioin\n"); rs.enumerate(g); fprintf(Stderr,"Done\n"); PolynomialSetList theList=gfan.getList(); for(PolynomialSetList::const_iterator i=theList.begin();i!=theList.end();i++) { HalfOpenConeList temp=orientedBoundary(groebnerCone(i->deHomogenization(),false),myTermOrder); ret.splice(ret.begin(),temp); } // AsciiPrinter P(Stderr); // printHalfOpenConeList(P,ret); return ret; } static void buildFanFromPolynomial(Polynomial const &p1, HalfOpenConeList *fullDimCones, HalfOpenConeList *coDimOneCones, IntegerVector *parentList, HalfOpenCone *restrictingCone=0) { int n(p1.getRing().getNumberOfVariables()); IntegerVectorList empty; HalfOpenCone dummy(n,empty,empty,empty,true); if(restrictingCone==0)restrictingCone=&dummy; if(p1.isZero()) //If the polynomial is zero it makes most sense to return a complete fan consisting of one cone in both cases { IntegerVectorList empty; if(fullDimCones)fullDimCones->push_back(intersection(HalfOpenCone(n,empty,empty,empty),*restrictingCone)); if(coDimOneCones)coDimOneCones->push_back(intersection(HalfOpenCone(n,empty,empty,empty),*restrictingCone)); return; } LexicographicTermOrder myTermOrder; IntegerVectorList l=newtonPolytope(p1); // log0 AsciiPrinter(Stderr).printVectorList(l); assert(!l.empty()); removeNonExtremeVerticesOfPolytope(l); // log0 AsciiPrinter(Stderr).printVectorList(l); IntegerVector parents; int numberOfCoDimOneCones=0; int numberOfFullDimCones=0; for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { numberOfFullDimCones++; IntegerVectorList inequalities; for(IntegerVectorList::const_iterator j=l.begin();j!=l.end();j++) if(j!=i) inequalities.push_back(*i-*j); // log0 fprintf(Stderr,"ineq\n"); // log0 AsciiPrinter(Stderr).printVectorList(inequalities); inequalities=normalizedWithSumsAndDuplicatesRemoved(inequalities); //log0 fprintf(Stderr,"ineq\n"); //log0 AsciiPrinter(Stderr).printVectorList(inequalities); IntegerVectorList empty; PolyhedralCone C(inequalities,empty,n,PCP_impliedEquationsKnown); C.findFacets(); if(coDimOneCones || parentList) { HalfOpenConeList temp=orientedBoundary(C,myTermOrder,restrictingCone); // fprintf(Stderr,"TESTSET:%i\n",temp.size()); for(int i=0;iprint(P); } fprintf(Stderr,"-------------------------------------------------\n");*/ HalfOpenConeList::iterator k=coDimOneCones->end(); coDimOneCones->splice(k,temp); } } if(fullDimCones) { fullDimCones->push_back(intersection(HalfOpenCone(C,myTermOrder),*restrictingCone)); /* fprintf(Stderr,"Came from-------------------------------------------------\n"); AsciiPrinter P(Stderr); fullDimCones->back().print(P); fprintf(Stderr,"-------------------------------------------------\n"); */ } } if(parentList) *parentList=parents; } HalfOpenConeList tropicalHyperSurfaceFast(Polynomial const &p1) { HalfOpenConeList ret; buildFanFromPolynomial(p1,0,&ret,0); return ret; } HalfOpenConeList normalFanOfNewtonPolytope(Polynomial const &p1) { HalfOpenConeList ret; buildFanFromPolynomial(p1,&ret,0,0); return ret; } HalfOpenConeList refinement(HalfOpenConeList const &a, HalfOpenConeList const &b) { HalfOpenConeList ret; for(HalfOpenConeList::const_iterator i=a.begin();i!=a.end();i++) for(HalfOpenConeList::const_iterator j=b.begin();j!=b.end();j++) if(!haveEmptyIntersection(*i,*j)) { HalfOpenCone c=intersection(*i,*j); // c.isEmpty(); // c.isEmpty(); // if(!c.isEmpty()) ret.push_back(c); } return ret; } HalfOpenConeList tropicalHyperSurfaceIntersection2(int dimension, PolynomialSet const &g) { HalfOpenConeList intersection; IntegerVectorList empty; intersection.push_back(HalfOpenCone(dimension,empty,empty,empty)); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { HalfOpenConeList surface=tropicalHyperSurface(*i); fprintf(Stderr,"Number of cones in current intersection:%i\n",(int)intersection.size()); fprintf(Stderr,"Number of cones in next surface:%i\n",(int)surface.size()); fprintf(Stderr,"A\n"); intersection=refinement(intersection,surface); fprintf(Stderr,"B\n"); } fprintf(Stderr,"%i",(int)intersection.size()); return intersection; } void tropicalHyperSurfaceIntersectionWithProcessor(int dimension, PolynomialSet const &g, HalfOpenConeProcessor &myProcessor, PolyhedralCone *restrictingCone, bool expand, int intervalLow, int intervalHigh) { assert(expand || !restrictingCone);//Need to fix this if we don't want to expand. Add in a different HalfOpenConeProcessor. // HalfOpenConeList intersection; if(restrictingCone) { IntegerVectorList equations=restrictingCone->getEquations(); IntegerVectorList nonStrict=restrictingCone->getHalfSpaces(); IntegerVectorList strict; /**************************************************************** * REMOVE THE LINE BELOW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ // strict.push_back(IntegerVector::standardVector(g.getRing().getNumberOfVariables(),0));cerr<<"REMOVE THIS LINE\n"; HalfOpenCone restrictingCone2(dimension,equations,nonStrict,strict,true); //intersection= tropicalHyperSurfaceIntersectionInSubspace(dimension,g,&restrictingCone2,myProcessor,intervalLow,intervalHigh);//<<---here //intersection=tropicalHyperSurfaceIntersection(dimension,g,&restrictingCone2); } else { HalfOpenCone rCone(dimension); //intersection= tropicalHyperSurfaceIntersectionInSubspace(dimension,g,&rCone,myProcessor,intervalLow,intervalHigh);//<<---here /* PolyhedralFan intersectionOld=tropicalHyperSurfaceIntersection(dimension,g); AsciiPrinter P(Stderr); intersection.print(&P); intersectionOld.print(&P); */ } log2 fprintf(Stderr,"Halfopen intersection completed.\n"); } PolyhedralFan tropicalHyperSurfaceIntersectionClosed(int dimension, PolynomialSet const &g, PolyhedralCone *restrictingCone, bool expand, bool saveResult, int intervalLow, int intervalHigh) { HalfOpenConeProcessorPointCollector myProcessor; if(saveResult)myProcessor.setSave(); tropicalHyperSurfaceIntersectionWithProcessor(dimension,g,myProcessor,restrictingCone,expand,intervalLow,intervalHigh); if(saveResult)saveList(myProcessor.interiorPoints,"finalresult"); // AsciiPrinter P(Stderr); // printHalfOpenConeList(intersection, P); PolyhedralFan ret(dimension); // for(HalfOpenConeList::iterator i=intersection.begin();i!=intersection.end();i++) for(IntegerVectorList::const_iterator i=myProcessor.interiorPoints.begin();i!=myProcessor.interiorPoints.end();i++) { /*PolyhedralCone c=i->closure(); c.canonicalize(); if(expand) c=normalConeOfMinkowskiSum(g,c.getRelativeInteriorPoint()); ret.insert(c); */ ret.insert(normalConeOfMinkowskiSum(g,*i)); } /* AsciiPrinter P(Stderr); ret.print(&P); cerr<<"ETSTSETST------------------------------------------------------------------------------"; */ return ret; } void HalfOpenCone::splitIntoRelativelyOpenCones(list &l) { // fprintf(Stderr,"BEGIN\n"); // AsciiPrinter P(Stderr); // print(P); lifted.findFacets(); // print(P); /* { IntegerVector v=StringParser("(3,0,3,2,0,3)").parseIntegerVector(); if(contains(v))fprintf(Stderr,"??????????????????????????????????????????\n"); }*/ IntegerVectorList inequalityList=lifted.getHalfSpaces(); IntegerVectorList equationList=lifted.getEquations(); IntegerVectorList strict,nonstrict; for(IntegerVectorList::const_iterator i=inequalityList.begin();i!=inequalityList.end();i++) if((*i)[i->size()-1]<0) strict.push_back(*i); else if((*i)[i->size()-1]==0) nonstrict.push_back(*i); else {//CHANGED assert(i->subvector(0,i->size()-1).isZero()); strict.push_back(*i); } // AsciiPrinter(Stderr).printVectorList(nonstrict); // AsciiPrinter(Stderr).printVectorList(strict); // AsciiPrinter(Stderr).printVectorList(equationList); if(nonstrict.size()==0) { l.push_back(*this); } else { IntegerVector chosen=*nonstrict.begin(); nonstrict.pop_front(); strict.push_front(chosen); (*strict.begin())[strict.begin()->size()-1]=-1; IntegerVectorList a=nonstrict; IntegerVectorList tempa=strict; a.splice(a.begin(),tempa); // fprintf(Stderr,"New inequalities:\n"); // AsciiPrinter(Stderr).printVectorList(a); HalfOpenCone A(dimension,PolyhedralCone(a,equationList,liftedDimension)); A.splitIntoRelativelyOpenCones(l); equationList.push_front(chosen); strict.pop_front(); IntegerVectorList b=nonstrict; IntegerVectorList tempb=strict; b.splice(b.begin(),tempb); // fprintf(Stderr,"New inequalities:\n"); // AsciiPrinter(Stderr).printVectorList(b); // fprintf(Stderr,"New equationList:\n"); // AsciiPrinter(Stderr).printVectorList(equationList); HalfOpenCone B(dimension,PolyhedralCone(b,equationList,liftedDimension)); B.splitIntoRelativelyOpenCones(l); } // AsciiPrinter(Stderr).print // fprintf(Stderr,"END\n"); } void HalfOpenCone::print(class Printer &p)const { p.printString("Printing HalfOpenCone\n"); lifted.print(&p); p.printString("Done printing HalfOpenCone\n"); } HalfOpenConeList splitIntoRelativelyOpenCones(HalfOpenConeList const &l) { AsciiPrinter P(Stderr); HalfOpenConeList ret; for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) { fprintf(Stderr,"A"); HalfOpenCone temp=*i; HalfOpenConeList tempSplit; // fprintf(Stderr,"---------------------------------------------------------------\n"); // temp.print(P); // fprintf(Stderr,"---------------------------------------------------------------\n"); temp.splitIntoRelativelyOpenCones(tempSplit); // fprintf(Stderr,"Splits into:"); // for(HalfOpenConeList::const_iterator i=tempSplit.begin();i!=tempSplit.end();i++) // i->print(P); // fprintf(Stderr,"Splits into End."); ret.splice(ret.begin(),tempSplit); fprintf(Stderr,"B\n"); } return ret; } static bool isSubsetOf(IntegerVector const &v, IntegerVector const &u) { for(int i=0;i cones; for(HalfOpenConeList::iterator i=L.begin();i!=L.end();i++) cones.push_back(i->closure()); int homog=1000000; int largest=0; int ambientDimension=-1; for(list::const_iterator i=cones.begin();i!=cones.end();i++) { if(i->dimension()dimension(); if(i->dimension()>largest)largest=i->dimension(); ambientDimension=i->ambientDimension(); } assert(homog!=1000000); for(list::const_iterator i=cones.begin();i!=cones.end();i++) { assert(i->dimensionOfLinealitySpace()==homog); } fprintf(Stderr,"Ambient dimension: %i, maximal dimension: %i, dimension of lineality space: %i\n",ambientDimension,largest,homog); IntegerVectorList rays; for(list::iterator i=cones.begin();i!=cones.end();i++) if(i->dimension()==homog+1)rays.push_back(i->getRelativeInteriorPoint()); p.printString("Rays:\n"); p.printVectorList(rays,true); list subsets; for(int d=homog;d<=largest;d++) { IntegerVectorList thisDimension; list cones2; for(list::iterator i=cones.begin();i!=cones.end();i++) if(i->dimension()==d) cones2.push_back(*i); for(list::const_iterator i=cones2.begin();i!=cones2.end();i++) { IntegerVector v(0); int J=0; for(IntegerVectorList::const_iterator j=rays.begin();j!=rays.end();j++) { if(i->contains(*j)) { v.grow(v.size()+1); v[v.size()-1]=J; } J++; } thisDimension.push_back(v); } subsets.push_back(thisDimension); } list::const_iterator subsetIterator=subsets.begin(); list::const_iterator subsetIteratorNext=subsets.begin(); for(int d=homog;d<=largest;d++) { subsetIteratorNext++; IntegerVectorList maximal,nonmaximal; if(subsetIteratorNext!=subsets.end()) { for(IntegerVectorList::const_iterator i=subsetIterator->begin();i!=subsetIterator->end();i++) if(isSubsetOf(*i,*subsetIteratorNext)) nonmaximal.push_back(*i); else maximal.push_back(*i); } else maximal=*subsetIterator; p.printString("Printing ");p.printInteger(subsetIterator->size());p.printString(" ");p.printInteger(d);p.printString("-dimensional cones (");p.printInteger(maximal.size());p.printString(" maximal cones):\n"); p.printString("{"); { bool first=true; for(IntegerVectorList::const_iterator i=maximal.begin();i!=maximal.end();i++) { if(!first)p.printString(",\n"); p.printVector(*i); first=false; } if(!first && nonmaximal.size()!=0)p.printString(",\n"); p.printString("\n"); first=true; for(IntegerVectorList::const_iterator i=nonmaximal.begin();i!=nonmaximal.end();i++) { if(!first) p.printString(",\n"); p.printVector(*i); first=false; } } p.printString("}\n"); subsetIterator++; } /* for(int d=homog;d<=largest;d++) { list cones2; for(list::iterator i=cones.begin();i!=cones.end();i++) if(i->dimension()==d) cones2.push_back(*i); p.printString("Printing ");p.printInteger(cones2.size());p.printString(" ");p.printInteger(d);p.printString("-dimensional cones:\n"); p.printString("{"); for(list::const_iterator i=cones2.begin();i!=cones2.end();i++) { IntegerVector v(0); int J=0; for(IntegerVectorList::const_iterator j=rays.begin();j!=rays.end();j++) { if(i->contains(*j)) { v.grow(v.size()+1); v[v.size()-1]=J; } J++; } if(i!=cones2.begin())p.printString(",\n"); p.printVector(v); } p.printString("}\n"); } */ } class BitSet { vector v; public: BitSet() { } BitSet(int n): v(n) { for(int i=0;i=0 && n=0 && n v; int ambientSetSize; static int bitsSetInInt(int i) { if(BITSET_BITS_PER_WORD==32) { i=(i&0x55555555)+((i>>1)&0x55555555); i=(i&0x33333333)+((i>>2)&0x33333333); i=(i&0x0f0f0f0f)+((i>>4)&0x0f0f0f0f); i=(i)+((i>>8)); i=(i)+((i>>16)); return i&255; } int ret=0; while(i&(i-1)){i&=i-1;ret++;} return ret; } public: BitSet() { } BitSet(int n): ambientSetSize(n), v(((unsigned int)(ambientSetSize-1))/BITSET_BITS_PER_WORD+1) { for(int i=0;i=0 && n=0 && n > > table; public: Table(vector > const &l): table(l.size()) { int N=l.size(); for(int i=0;i > v(N); for(int j=0;j w(l[i].size()); for(int k=0;k > fanList; Table knownEmptyIntersectionInIntersection; Table knownNonEmptyIntersection; public: int numberOfSolvedLPs; RelationTable(vector > const &l): fanList(l), knownEmptyIntersectionInIntersection(l), knownNonEmptyIntersection(l), numberOfSolvedLPs(0) { } bool knownToIntersectTriviallyInIntersection(int fan1, int cone1, int fan2, int cone2) { assert(fan1 > fans; IntegerVector chosen; IntegerVector chosenFans; IntegerVector iterators; //just used for printing IntegerVector nCandidates; //just used for printing BitSet usedFans; int numberOfUsefulCalls; int totalNumberOfCalls; HalfOpenConeProcessor &processor; bool intervalSet; int intervalLow,intervalHigh; public: RelationTable table; RecursionData(vector > const &fans_, HalfOpenConeProcessor &processor_): table(fans_), fans(fans_), chosen(fans_.size()), chosenFans(fans_.size()), usedFans(fans_.size()), iterators(fans_.size()), nCandidates(fans_.size()), numberOfUsefulCalls(0), totalNumberOfCalls(0), processor(processor_), intervalSet(false) { } void setInterval(int lo, int hi) { intervalLow=lo; intervalHigh=hi; intervalSet=true; } // HalfOpenConeList ret; bool randBool()const { return 0; static int i; i++; return (i&3)==0; } BitSet computeCandidates(int index, int fanNumber) { /* BitSet nonCandidates(fans[fanNumber].size()); for(int i=0;iindex){debug<<"Payne's trick with index:"<1) { smallest=1000000; bx=-1; by=-1; for(int x=0;x=intervalHigh) { cerr << "SKIPPING CONE "<=current.lifted.dimension()-1)//Payne's trick { bool s=rek(index+1,next); success|=s; } // else //Payne's trick // cerr<<"Payne trick at level "< > L2; vector indicesOfNonUsedFans; vector > indicesOfCones; { for(int i=0;i L; indicesOfCones.push_back(vector()); for(int j=0;j > const &fans2, vector parentList) { int freeLPs=0; HalfOpenConeProcessorVoid dummy; RecursionData data2(fans2,dummy); data2.completeTable(); data2.transitiveClosure(); assert(fans.size()==fans2.size()); assert(fans.size()==parentList.size()); // data2.table.print(); for(int f1=0;f1 > fullDimFanList; vector > coDimOneFanList; vector parents(g.size()); // AsciiPrinter(Stderr) << g; // fprintf(Stderr,"GSIZE:%i\n",g.size()); { int I=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { HalfOpenConeList l,lf; buildFanFromPolynomial(*i, &lf, &l, &(parents[I]),restrictingCone); log2 AsciiPrinter(Stderr).printVector(parents[I]); log2 fprintf(Stderr,"\n"); vector L; for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) { L.push_back(*i); } vector F; for(HalfOpenConeList::const_iterator i=lf.begin();i!=lf.end();i++) { F.push_back(*i); } fullDimFanList.push_back(F); coDimOneFanList.push_back(L); //if(b==4)break; I++; } } RecursionData data(coDimOneFanList,processor); data.extractInformationFromFullFan(fullDimFanList,parents); // data.completeTable();//HERE // data.table.print();//HERE IntegerVectorList empty; data.rek(0, HalfOpenCone(dimension,empty,empty,empty)); log2 fprintf(Stderr,"LPs solved:%i for relation table\n",data.table.numberOfSolvedLPs); } HalfOpenConeList tropicalHyperSurfaceIntersection(int dimension, PolynomialSet const &g, HalfOpenCone *restrictingCone) { HalfOpenConeProcessorConeCollector collector; tropicalHyperSurfaceIntersection(dimension, g, restrictingCone, collector); return collector.theList; } #include "binomial.h" #include "linalg.h" //ignore last coordinate. Get rid of pivots static IntegerVectorList rewriteVectorList(IntegerVectorList const &l, list nonPivots, FieldMatrix const &A) { IntegerVectorList ret; int M=nonPivots.size(); for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { IntegerVector v(M+1); v[M]=(*i)[i->size()-1]; IntegerVector u=A.canonicalize(integerVectorToFieldVector(i->subvector(0,i->size()-1),Q)).primitive(); int J=0; for(list::const_iterator j=nonPivots.begin();j!=nonPivots.end();j++,J++)v[J]=u[*j]; ret.push_back(v); } return ret; } //add pivot columns static IntegerVectorList expandVectorList(IntegerVectorList const &l, list pivots) { IntegerVectorList ret; int pivotSize=pivots.size(); for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { int newSize=pivotSize+i->size(); IntegerVector v(newSize); list::const_iterator J1=pivots.begin(); int J2=0; for(int j=0;j chosen)const { chosen.push_back(dimension); PolyhedralCone newLifted=PolyhedralCone( subvectorsOfIntegerVectorList(lifted.getHalfSpaces(),chosen), subvectorsOfIntegerVectorList(lifted.getEquations(),chosen), chosen.size() ); return HalfOpenCone(chosen.size()-1,newLifted); } HalfOpenCone HalfOpenCone::rewrite(FieldMatrix const &A, list nonPivots)const { PolyhedralCone newLifted=PolyhedralCone( rewriteVectorList(lifted.getHalfSpaces(),nonPivots,A), rewriteVectorList(lifted.getEquations(),nonPivots,A), nonPivots.size()+1 ); return HalfOpenCone(nonPivots.size(),newLifted); } HalfOpenCone HalfOpenCone::rewriteExpand(list pivots, IntegerVectorList const &newEquations)const { IntegerVectorList equations=expandVectorList(lifted.getEquations(),pivots); for(IntegerVectorList::const_iterator i=newEquations.begin();i!=newEquations.end();i++) { IntegerVector v(i->size()+1); for(int j=0;jlifted.print(&P); } P << "Done printing half Open cone list-----------------------------------------------------------------\n"; } static void print2(vector const &l, Printer &P) { P << "Printing half Open cone list---------------------------------------------------------------\n"; for(vector::const_iterator i=l.begin();i!=l.end();i++) { i->lifted.print(&P); } P << "Done printing half Open cone list----------------------------------------------------------------!\n"; } static IntegerVectorList liftEquations(IntegerVectorList const &l, FieldMatrix const &B) { IntegerVectorList ret; list nonPivots=B.nonPivotColumns(); for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { FieldVector I=integerVectorToFieldVector(i->subvector(0,i->size()-1),Q); IntegerVector v(B.getWidth()+1); FieldVector v2(Q,B.getWidth()); for(int j=0;jsize()-1]; ret.push_back(v); } return ret; } HalfOpenCone liftEquations(HalfOpenCone const &c, FieldMatrix const &B) { PolyhedralCone newCone=PolyhedralCone( liftEquations(c.lifted.getHalfSpaces(),B), liftEquations(c.lifted.getEquations(),B), B.getWidth()+1 ); return HalfOpenCone(B.getWidth(),newCone); } /* Use full for transforming the cone back into original coordinates*/ class HalfOpenConeProcessorAffineChange : public HalfOpenConeProcessor { IntegerVectorList interiorPoints; HalfOpenConeProcessor &parent; list pivots; IntegerVectorList newEquations; FieldMatrix B; public: HalfOpenConeProcessorAffineChange(HalfOpenConeProcessor &parent_, list const &pivots_, IntegerVectorList const &newEquations_, FieldMatrix const &B_): parent(parent_), pivots(pivots_), newEquations(newEquations_), B(B_) { if(parent_.savePartialResult)setSave(); } void process(HalfOpenCone const &c, IntegerVector const &chosenFans, IntegerVector const &chosenCone) { HalfOpenCone c2=liftEquations(c.rewriteExpand(pivots,newEquations),B); parent.process(c2,chosenFans,chosenCone); } }; //HalfOpenConeList void tropicalHyperSurfaceIntersectionInSubspace(int dimension, PolynomialSet const &G, HalfOpenCone *restrictingCone, HalfOpenConeProcessor &processor, int intervalLow, int intervalHigh) { /* Removing the lineality space. (This could be carried out on the level of polyhedra, which may or may not be more efficient.) We first find generators for the linalityspace, write them as rows of a matrix B. We reduce B and wish to ignore the coordinates whose columns contains a pivot. Afterwards we need to expand the inequalities/equations to the entire space. The matrix B tels us how to project to lowerdimensional space (by taking normals forms). The equations are gotten as the pull-back of the lower dimensional equations by this normal form map. */ log2 cerr<<"Projecting Newton polytopes modulo the homogeneity space."; int N=G.getRing().getNumberOfVariables(); IntegerVectorList w=wallInequalities(G); FieldMatrix W=integerMatrixToFieldMatrix(rowsToIntegerMatrix(w,N),Q); if(restrictingCone) { PolyhedralCone temp=restrictingCone->closure(); W=combineOnTop(combineOnTop(W, integerMatrixToFieldMatrix(rowsToIntegerMatrix(temp.getEquations(),N),Q)), integerMatrixToFieldMatrix(rowsToIntegerMatrix(temp.getHalfSpaces(),N),Q)); } FieldMatrix B=W.reduceAndComputeKernel(); B.reduce(); list BNonPivots=B.nonPivotColumns(); PolynomialRing R(G.getRing().getField(),BNonPivots.size()); PolynomialSet g=G.embeddedInto(R,&BNonPivots); HalfOpenCone restrictedConeNew(0,PolyhedralCone(1)); if(restrictingCone) { restrictedConeNew=restrictingCone->withChosenCoordinates(BNonPivots); restrictingCone=&restrictedConeNew; } log2 cerr<<"Done projecting Newton polytopes modulo the homogeneity space."; /* Now do the computation with the new set of polynomials. */ /* Here follows restriction to subspace cut out by the binomials. */ log2 cerr<<"Restricting to subspace determined by binomials and computing tropical hypersurfaces."; int n=g.getRing().getNumberOfVariables(); IntegerVectorList equations; if(restrictingCone)//add those from the restricting cone { equations=restrictingCone->shrink(restrictingCone->lifted.getEquations()); } int numberOfNonBinomials=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { if(i->numberOfTerms()==2) equations.push_back(binomialToIntegerVector(*i)); else numberOfNonBinomials++; } FieldMatrix A=integerMatrixToFieldMatrix(rowsToIntegerMatrix(equations,n),Q); int npivots=A.reduceAndComputeRank(); // Coordinates to remove are those corresponding to pivots // We want to rewrite inequalities without the non-pivots // Unfortunatetly we need to compute the fans first // AsciiPrinter(Stderr)< nonPivots=A.nonPivotColumns(); // log0 cerr<<"Coordinates left "< > fullDimFanList; vector > coDimOneFanList; vector parents(numberOfNonBinomials); list pivots=A.pivotColumns(); int I=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) if(i->numberOfTerms()!=2) { log2 cerr << I; HalfOpenConeList l,lf; log2 cerr<< "Building fan"< L; for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) L.push_back(i->rewrite(A,nonPivots)); vector F; for(HalfOpenConeList::const_iterator i=lf.begin();i!=lf.end();i++) F.push_back(i->rewrite(A,nonPivots)); fullDimFanList.push_back(F); coDimOneFanList.push_back(L); log2 cerr<< "Done Building fan"<rewriteExpand(pivots,newEquations)); ret.push_back(liftEquations(i->rewriteExpand(pivots,newEquations),B)); } return ret; */ } PolyhedralFan faceComplexOfCone(HalfOpenCone &c) { PolyhedralFan ret(c.dimension); list h; c.splitIntoRelativelyOpenCones(h); for(list::iterator i=h.begin();i!=h.end();i++) { PolyhedralCone temp=i->closure(); temp.canonicalize(); ret.insert(temp); } return ret; } bool operator<(HalfOpenCone const &a, HalfOpenCone const &b) { return a.lifted > polynomialSetToHalfOpenCones(PolynomialSet const &g) { vector > coDimOneFanList; { int I=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { HalfOpenConeList l; PolynomialSet A(g.getRing()); A.push_back(*i); A.markAndScale(LexicographicTermOrder()); PolyhedralCone h=homogeneitySpace(A); h.canonicalize(); IntegerVectorList equations=h.getEquations(); for(IntegerVectorList::const_iterator j=equations.begin();j!=equations.end();j++) { IntegerVectorList eq2; eq2.push_back(*j); HalfOpenCone C(j->size(),eq2,IntegerVectorList(),IntegerVectorList()); l.push_back(C); } vector L; for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) { debug<<"----"<lifted.getEquations(); L.push_back(*i); } coDimOneFanList.push_back(L); debug<<"\n\n"; I++; } } return coDimOneFanList; } /** * Similar to polynomialSetToHalfOpenCones(), but here the polynomial is allowed to have repeated exponent vectors. * This, however, is not allowed by the Polynomial class. Therefore we use a list of lists of expnonent vectors. * Here d is the size of each exponent vector. */ static vector > exponentVectorsToHalfOpenCones(list > const &g, int d) { vector > coDimOneFanList; { int I=0; for(list >::const_iterator i=g.begin();i!=g.end();i++) { HalfOpenConeList l; IntegerVectorList homogeneitySpaceGenerators; for(list::const_iterator j=i->begin();j!=i->end();j++)homogeneitySpaceGenerators.push_back(*j-i->front()); //debug<size(),eq2,IntegerVectorList(),IntegerVectorList()); l.push_back(C); } vector L; for(HalfOpenConeList::const_iterator i=l.begin();i!=l.end();i++) { // debug<<"----"<lifted.getEquations(); L.push_back(*i); } coDimOneFanList.push_back(L); //debug<<"\n\n"; I++; } } return coDimOneFanList; } bool hasMixedCellOfDimension(PolynomialSet const &g, int D, int *maximalSeen, IntegerVectorList *affineSpanGenerators) { if(maximalSeen)*maximalSeen=-1; vector > coDimOneFanList=polynomialSetToHalfOpenCones(g); // vector > coDimOneFanList=exponentVectorsToHalfOpenCones(g,d); SingleSubspaceProcessor p(D); RecursionData data(coDimOneFanList,p); IntegerVectorList empty; data.rek(0, HalfOpenCone(g.getRing().getNumberOfVariables(),empty,empty,empty)); log2 fprintf(Stderr,"LPs solved:%i for relation table\n",data.table.numberOfSolvedLPs); if(maximalSeen)*maximalSeen=p.getMaximalDimensionFound(); // debug<push_back(c.getEquations().front()); } } return p.success(); } bool hasMixedCellOfDimension(list > const &g, int d, int D, int *maximalSeen, IntegerVectorList *affineSpanGenerators) { if(maximalSeen)*maximalSeen=-1; // vector > coDimOneFanList=polynomialSetToHalfOpenCones(g); vector > coDimOneFanList=exponentVectorsToHalfOpenCones(g,d); SingleSubspaceProcessor p(D); RecursionData data(coDimOneFanList,p); IntegerVectorList empty; data.rek(0, HalfOpenCone(/*g.getRing().getNumberOfVariables()*/d,empty,empty,empty)); log2 fprintf(Stderr,"LPs solved:%i for relation table\n",data.table.numberOfSolvedLPs); if(maximalSeen)*maximalSeen=p.getMaximalDimensionFound(); //debug<push_back(c.getEquations().front()); } } return p.success(); } /* * Could this be a bug in gcc 4.4.3? It is impossible to overload hasMixedCellOfDimension() to take only * two parameters with value =0 for the remaining. Also, below the cast of 0 cannot be avoided. */ //bool hasMixedCellOfDimension2(PolynomialSet const &g, int D) bool hasMixedCellOfDimension2(list > const &g, int d, int D) { return hasMixedCellOfDimension(g,d,D,0, (IntegerVectorList*)0); } /* This routine takes a choice of vectors from the linear affine span of each of the newton polytopes * of elements in g, and produces a choice of monomial pairs for each element in g with the property that * the dimension of the minkowskisum of the input vectors is smaller than or equal to the dimension of the minkowski sum of * the output vectors. The output is represented by specifying a 0 for each selected monomial and a 1 * otherwise. */ IntegerVector subspaceChoiceToMonomialPairChoice(PolynomialSet const &g, IntegerVectorList vectors) { int numberOfMonomials=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++)numberOfMonomials+=i->numberOfTerms(); IntegerVector ret=IntegerVector::allOnes(numberOfMonomials); int monomialIndex=0; IntegerVectorList::iterator I=vectors.begin(); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++,I++) { assert(i->numberOfTerms()>1); IntegerVectorList Icomplement; for(IntegerVectorList::const_iterator J=vectors.begin();J!=vectors.end();J++)if(J!=I)Icomplement.push_back(*J); Subspace Ic(Icomplement); if(Ic.contains(*I)) { // It does not matter which pair we choose ret[monomialIndex]=0; ret[monomialIndex+1]=0; TermMap::const_iterator a=i->terms.begin(); TermMap::const_iterator b=i->terms.begin();b++; *I=a->first.exponent-b->first.exponent; } else { int A=0; for(TermMap::const_iterator a=i->terms.begin();a!=i->terms.end();a++,A++) { int B=0; for(TermMap::const_iterator b=i->terms.begin();b!=a;b++,B++) { if(!Ic.contains(a->first.exponent-b->first.exponent)) { ret[monomialIndex+A]=0; ret[monomialIndex+B]=0; *I=a->first.exponent-b->first.exponent; goto done; } } } assert(0); done:; } monomialIndex+=i->numberOfTerms(); } return ret; } /* This routine takes a choice of vectors from the linear affine span of each of the newton polytopes * of elements in g, and produces a choice of monomial pairs for each element in g with the property that * the dimension of the minkowskisum of the input vectors is smaller than or equal to the dimension of the minkowski sum of * the output vectors. The output is represented by specifying a 0 for each selected monomial and a 1 * otherwise. */ IntegerVector subspaceChoiceToMonomialPairChoice(list > const &g, IntegerVectorList vectors) { int numberOfMonomials=0; for(list >::const_iterator i=g.begin();i!=g.end();i++)numberOfMonomials+=i->size(); IntegerVector ret=IntegerVector::allOnes(numberOfMonomials); int monomialIndex=0; IntegerVectorList::iterator I=vectors.begin(); for(list >::const_iterator i=g.begin();i!=g.end();i++,I++) { assert(i->size()>1); IntegerVectorList Icomplement; for(IntegerVectorList::const_iterator J=vectors.begin();J!=vectors.end();J++)if(J!=I)Icomplement.push_back(*J); Subspace Ic(Icomplement); if(Ic.contains(*I)) { // It does not matter which pair we choose ret[monomialIndex]=0; ret[monomialIndex+1]=0; IntegerVectorList::const_iterator a=i->begin(); IntegerVectorList::const_iterator b=i->begin();b++; *I=*a-*b; } else { int A=0; for(IntegerVectorList::const_iterator a=i->begin();a!=i->end();a++,A++) { int B=0; for(IntegerVectorList::const_iterator b=i->begin();b!=a;b++,B++) { if(!Ic.contains(*a-*b)) { ret[monomialIndex+A]=0; ret[monomialIndex+B]=0; *I=*a-*b; goto done; } } } assert(0); done:; } monomialIndex+=i->size(); } return ret; } bool nonEmptyStableIntersection(PolynomialSet const &g) { // return hasMixedCellOfDimension2(g,g.getRing().getNumberOfVariables()-g.size()); return hasMixedCellOfDimension2(g.exponents(),g.getRing().getNumberOfVariables(),g.getRing().getNumberOfVariables()-g.size()); } int coDimensionOfResultantVariety(PolynomialSet const &g, IntegerVector *choice) { int max; IntegerVectorList span; hasMixedCellOfDimension(g.exponents(),g.getRing().getNumberOfVariables(),1000000,&max,&span); // hasMixedCellOfDimension(g,1000000,&max,&span); // debug< > const &g, int d, IntegerVector *choice) { int max; IntegerVectorList span; hasMixedCellOfDimension(g,d,1000000,&max,&span); // debug< #include "parser.h" #include "printer.h" #include "polynomial.h" #include "buchberger.h" #include "reversesearch.h" #include "termorder.h" #include "genericwalk.h" #include "gfanapplication.h" #include "timer.h" #include "tropical2.h" #include "log.h" #include "field_rationals.h" class SPolynomialApplication : public GFanApplication { SimpleOption optionTakeInitialForms; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program takes a list of polynomials and a weight vector. The output is the set of all...\n"; } SPolynomialApplication(): optionTakeInitialForms("-f",".\n") { registerOptions(); } const char *name() { return "_spolynomial"; } int main() { PolynomialSet g=FileParser(Stdin).parsePolynomialSetWithRing(); IntegerVector w=FileParser(Stdin).parseIntegerVector(); // WeightReverseLexicographicTermOrder T(w); WeightTermOrder T(w); g.markAndScale(T); PolynomialSet out(g.getRing()); int I=0; for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++,I++) { int J=0; for(PolynomialSet::const_iterator j=g.begin();j!=i;j++,J++) { Polynomial s=sPolynomial(*i,*j); IntegerVector cancelingTerm=max(i->getMarked().m.exponent,j->getMarked().m.exponent); int cancelDegree=dotLong(cancelingTerm,w); if(optionTakeInitialForms.getValue()) { if(cancelDegree!=s.degree(w)) { out.push_back(initialForm(s,w)); if(initialForm(s,w).numberOfTerms()<=8)cerr<<"S("<numberOfTerms() << " "; if(i->numberOfTerms()<=8) { AsciiPrinter(Stdout)<<"\n"<< *i<<"\n"; out2.push_back(*i); } } out2.saturate(); out2=out2.embeddedInto(PolynomialRing(Q,15)); AsciiPrinter(Stdout).printPolynomialRing(out2.getRing()); AsciiPrinter(Stdout).printPolynomialSet(out2); return 0; } }; static SPolynomialApplication theApplication; gfan0.6.2/src/gfanlib_ordering.h0000644000175000017500000000776313122232611016130 0ustar andersanders#ifndef GFANLIB_ORDERING_H_INCLUDED #define GFANLIB_ORDERING_H_INCLUDED #include "gfanlib_vector.h" class Ordering { public: virtual int rowDot(int row, const IntegerVector &v)const=0; virtual bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const=0; // virtual bool operator()(IntegerVector const &a, IntegerVector const &b)const=0; virtual void print(Printer &p)const; }; class LexicographicOrdering : public Ordering { int largest; public: LexicographicTermOrder(int largest=0); int rowDot(int row, const IntegerVector &v)const; bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const; // bool operator()(const IntegerVector &a, const IntegerVector &b)const; void print(Printer &p)const; }; class ReverseLexicographicTermOrder : public TermOrder { int largest; int index(int row, const IntegerVector &a)const; public: ReverseLexicographicTermOrder(int largest=0); virtual int rowDot(int row, const IntegerVector &v)const; virtual bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const; // bool operator()(const IntegerVector &a, const IntegerVector &b)const; void print(Printer &p)const; }; class StandardGradedLexicographicTermOrder : public TermOrder { int largest; public: StandardGradedLexicographicTermOrder(int largest=0); //StandardGradedLexicographicTermOrder(const IntegerVector &order); virtual int rowDot(int row, const IntegerVector &v)const; virtual bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const; // bool operator()(const IntegerVector &a, const IntegerVector &b)const; void print(Printer &p)const; }; /*class StandardGradedReverseLexicographicTermOrder : public TermOrder { int largest; public: StandardGradedReverseLexicographicTermOrder(int largest=0); virtual int rowDot(int row, const IntegerVector &v)const; virtual bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const; void print(Printer &p)const; }; */ class WeightTermOrder : public TermOrder // tie broken with lexicographic { IntegerVector weight; // TermOrder &tieBreaker; // how do I implement tie breaking. pointer or ref... what happens when you copy a term order? public: WeightTermOrder(const IntegerVector weight_):weight(weight_){} // WeightTermOrder(const IntegerVector weight_, TermOrder ):weight(weight_),tieBreaker(0){} virtual int rowDot(int row, const IntegerVector &v)const; virtual bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const; // bool operator()(const IntegerVector &a, const IntegerVector &b)const; void print(Printer &p)const; }; class WeightReverseLexicographicTermOrder : public TermOrder // tie broken with reverse lexicographic { IntegerVector weight; public: IntegerVector getWeight()const; WeightReverseLexicographicTermOrder(const IntegerVector weight_):weight(weight_){} virtual int rowDot(int row, const IntegerVector &v)const; virtual bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const; // bool operator()(const IntegerVector &a, const IntegerVector &b)const; void print(Printer &p)const; }; class MatrixTermOrder : public TermOrder // tie broken with reverse lexicographic { IntegerVectorList weights; public: MatrixTermOrder(const IntegerVectorList weights_):weights(weights_){} virtual int rowDot(int row, const IntegerVector &v)const; virtual bool operator()(const IntegerVector &a, const IntegerVector &b, int scaleA=1, int scaleB=1, int perturbationDegree=-1)const; // bool operator()(const IntegerVector &a, const IntegerVector &b)const; void print(Printer &p)const; }; /*class EliminationTermOrder { public: }; */ #endif gfan0.6.2/src/tropicalbasis.h0000644000175000017500000000130413122232611015455 0ustar andersanders#ifndef TROPICALBASIS_H_INCLUDED #define TROPICALBASIS_H_INCLUDED #include "polynomial.h" #include "polyhedralfan.h" PolynomialSet tropicalBasisOfCurve(int n, PolynomialSet g, PolyhedralFan *intersectionFan=0, int linealitySpaceDimension=-1); /*Assuming g is homogeneous and has dimension 1 modulo homogeneous space. intersectionFan specifies a fan to use for the temporary hypersurface intersections. This is useful since we then don't have to call tropicalPrincipalIntersection to get the variety after having computed a tropical basis. No PolyhedralFan needs to be specified. If specified, the fan does not have to be initialized in any way. Its data is simply overwritten.*/ #endif gfan0.6.2/src/continuedfractions.cpp0000644000175000017500000000260213122232611017054 0ustar andersanders#include "continuedfractions.h" #include "vektor.h" #include "printer.h" #include #include void doubleToFraction(double f, int &numerator, int &denominator, int maksIter) { bool changeSign=f<0; if(changeSign)f*=-1; if(f<0.000001 || maksIter<1) { numerator=0; denominator=1; } else { double r=1/f; int R=int(r);//truncates r-=R; int n2,d2; doubleToFraction(r,n2,d2,maksIter-1); /* 1/f-R=r=n2/d2; => 1/f=(n2+d2*R)/d2; => f=d2/(n2+d2*R); */ numerator=d2; denominator=n2+d2*R; if(changeSign) numerator*=-1; } } void doubleVectorToFractions(vector const &v, vector &numerators, int &denominator) { int n=v.size(); numerators=vector(n); denominator=1; if(n==0)return; for(int i=0;i #include #include #include "gfanlib_polyhedralfan.h" #include "gfanlib_symmetriccomplex.h" namespace gfan{ /** * This class represents a Polyhedral fan with the combined features of a SymmetricComplex, and * a PolyhedralFan (which we regards as some collection of cones of the fan with the property that every cone * of the fan is a face of these (up to action by the group)). * It is important to distinguis between the cones of the collection, the cones of the fan as a mathematical object, and the orbits of cones of the fan. * * * TEMPLATES SHOULD BE HIDDEN */ class ZFan { mutable PolyhedralFan *coneCollection; mutable SymmetricComplex *complex; mutable std::vector > cones; mutable std::vector > maximalCones; mutable std::vector > multiplicities; // for maximal cones only mutable std::vector > coneOrbits; mutable std::vector > maximalConeOrbits; mutable std::vector > multiplicitiesOrbits; // for maximal cones orbits only // SymmetryGroup sym; /** * Functions that makes the symmetric complex invalid: * insert() and construction * * Functions that make the cone collection invalid: * readFan() * */ void ensureConeCollection()const; void ensureComplex()const; void killComplex()const; public: std::vector > &table(bool orbit, bool maximal)const; ~ZFan(); ZFan(): coneCollection(0), complex(0) {} ZFan(ZFan const& f); /** * * To read from string, do the following: * std::string test="TEST"; * std::istringstream s(test); * ZFan G(s); * */ ZFan(std::istream &f); ZFan& operator=(ZFan const &f); /** * Creates an empty fan in the ambient space of dimension n. * It is a mistake to: * specify a negative ambientDimension. */ ZFan(int ambientDimension); /** * Creates an empty fan in the ambient space with dimension equal to the number of elements being permuted by the group. * The fan will have the symmmetries given by sym_ associated. */ ZFan(SymmetryGroup const &sym_); /** * Creates the fan in dimension n consisting of the n-dimensional space. */ static ZFan fullFan(int n); /** * Creates the full space as a fan in the ambient space with dimension equal to the number of elements being permuted by the group. * The fan will have the symmetries given by sym_ associated. */ static ZFan fullFan(SymmetryGroup const &sym_); /** * Reads from stream */ // static ZFan readFan(string const &filename, bool onlyMaximal=true, IntegerVector *w=0, set const *conesIndice=0, SymmetryGroup const *sym=0, bool readCompressedIfNotSym=false); /** * Writes to string */ std::string toString(int flags=0)const; /** * Returns the dimension of the ambient space. */ int getAmbientDimension()const; /** * Returns the largest dimension of a cone in the fan. If the fan is empty, then -1 is returned. */ int getDimension()const; /** * Returns the smallest codimension of a cone in the fan. If the fan is empty, then -1 is returned. */ int getCodimension()const; /** * Returns the dimension of the lineality space of the fan. Notice that the lineality space of the * empty fan is the ambient space. */ int getLinealityDimension()const; /** * Returns the f-Vector of the fan. */ ZVector getFVector()const; /** * Returns true, if the fan is simplicial. False otherwise. */ bool isSimplicial()const; /** * Returns true, if the fan is pure. False otherwise. */ bool isPure()const; /** * Inserts c into the fan. * It is a mistake to insert a cone which live in a space of the wrong dimension. * It is a mistake to insert a cone which does not result in a fan satisfying the nice intersection properties of a fan. * However, the second mistake will not cause the code to crash, but only give undefined results. * * The method insert() is expensive in the sense that calling it may require part of the representation * of the fan to be recomputed. The recomputation only happens on request. Therefore it is expensive * to have alternating calls to for example "insert()" and "numberOfConesOfDimension()". * * Notice that insert() has the effect of reordering cones, orbits and rays of the fan. */ void insert(ZCone const &c); void remove(ZCone const &c); /** * Returns the number of cones of dimension d in the collection. */ int numberOfConesOfDimension(int d, bool orbit, bool maximal)const; int numberOfConesInCollection()const; /** * Returns the cone in the collection given by the index. It is a mistake to specify an index which * is out of range. */ // ZCone const &getConeInCollection(int index)const; /** * Returns the cone in the cone of the fan */ ZCone getCone(int dimension, int index, bool orbit, bool maximal)const; IntVector getConeIndices(int dimension, int index, bool orbit, bool maximal)const; // ZFan expand()const; // SymmetryGorup recoverAllSymmetries()const; /* typedef PolyhedralConeList::const_iterator coneIterator; PolyhedralFan::coneIterator conesBegin()const; PolyhedralFan::coneIterator conesEnd()const; */ }; } #endif #endif /* GFANLIB_ZFAN_H_ */ gfan0.6.2/src/app_tropicalvarietyspan.cpp0000644000175000017500000000462113122232611020121 0ustar andersanders#include #include #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "polyhedralcone.h" #include "gfanapplication.h" #include "saturation.h" #include "field_rationals.h" #include "field_zmodpz.h" #include "field_rationalfunctions.h" #include "symmetry.h" #include "linalg.h" #include "fieldlp.h" #include "integer.h" #include "polynomialgcd.h" #include "packedmonomial.h" #include "gfanlib_zcone.h" using namespace gfan; class TropicalVarietySpanApplication : public GFanApplication { public: bool includeInDefaultInstallation() // Not included since the program does not follow the specifications of the help text. Moreover, doing this using Hadamard products is extremely slow. This should be replaced by the algorithm in the paper by Kahle, Katthan and Jensen. { return false; } const char *helpText() { return "This program takes a ring and an ideal as input and computes the span of the tropical variety defined by the ideal.\n"; } TropicalVarietySpanApplication() { registerOptions(); } const char *name() { return "_tropicalvarietyspan"; } PolynomialSet hadamardProduct(PolynomialSet const &I, PolynomialSet const &J) { PolynomialRing R=I.getRing(); int n=R.getNumberOfVariables(); PolynomialRing bigRing(R.getField(),n*3); vector var1; vector var2; for(int i=0;i #include #include "cstdio" using namespace std; namespace linalgfloat { std::ostream& operator<<(std::ostream& s, const Vector &v) { s<<"("; for(int j=0;jlast) { ret[i++]=v[++last]; // cerr<<"("<<(i-1)<<","< static Matrix simplex(int n, mvtyp d) { Matrix ret(n,n+1); for(int i=0;i class SingleTropicalHomotopyTraverser{ class InequalityComparisonResult{//actual comparison functions were moved to the InequalityTable public: bool empty; int configurationIndex;//used for finding best int columnIndex;//used for finding best }; class InequalityTable //circuit table // This table has been moved inside the IntegersectionTraverser simply because it is used nowhere else and is specific to mixed cells in Cayley configurations. { /* All methods are marked to show if they can overflow without throwing/asserting. * Overflowing methods at the moment are: * replaceFirstOrSecond: subroutine calls may overflow (dotDivVector) * compareInequalities: only if target entries are too big * dotVector: only if target entries are too big * setChoicesFromEarlierHomotopy: only if tuple entries are too big */ std::vector > tuple; std::vector offsets; std::vector > choices; Matrix A;//one row for each potential inequality, to store entries with indices in chosen Vector tempA; Vector Abounds;// a negative bound for each row of A, bounding the absolute value of the rows; std::vector svec;//used locally int subconfigurationIndex; mvtyp denominator; int m; int k; bool isLegalIndex(int subconfigurationIndex, int columnIndex)const {// Cannot overflow return choices[subconfigurationIndex].first!=columnIndex && choices[subconfigurationIndex].second!=columnIndex; } mvtyp dotVector(int subconfigurationIndex, int columnIndex, Vector const &target, int onlyK=-1)const { // May overflow if entries of target are too big. //if onlyK!=-1 then only the onlyKth subconfiguration is considered mvtypDouble ret; if(onlyK!=-1) { if(onlyK==subconfigurationIndex) { int i=subconfigurationIndex; ret+=extendedMultiplication(A.UNCHECKEDACCESS(i,columnIndex+offsets[subconfigurationIndex]),target.UNCHECKEDACCESS((choices)[i].second+offsets[i])); ret-=extendedMultiplication(A.UNCHECKEDACCESS(i,columnIndex+offsets[subconfigurationIndex]),target.UNCHECKEDACCESS((choices)[i].first+offsets[i])); ret-=extendedMultiplication(denominator,target.UNCHECKEDACCESS((choices)[i].first+offsets[i]));// the multiplication can be merged with multiplication above except that that could cause and overflow. ret+=extendedMultiplication(denominator,target.UNCHECKEDACCESS(columnIndex+offsets[i])); return ret.castToSingle(); } else { int i=onlyK; if(target.UNCHECKEDACCESS((choices)[i].first+offsets[i]).isNonZero()) { ret+=extendedMultiplication(A.UNCHECKEDACCESS(i,columnIndex+offsets[subconfigurationIndex]),target.UNCHECKEDACCESS((choices)[i].second+offsets[i])); ret-=extendedMultiplication(A.UNCHECKEDACCESS(i,columnIndex+offsets[subconfigurationIndex]),target.UNCHECKEDACCESS((choices)[i].first+offsets[i])); } return ret.castToSingle(); } } for(int i=0;i const &target, int onlyK=-1) {// Cannot overflow int J=0; for(int i=0;ib]=a; v[b>a]=b; return 2; } int sort3uniquely(int *v, int a, int b, int c)const//a and b and c different {// Cannot overflow v[(a>b)+int(a>c)]=a; v[(b>a)+int(b>c)]=b; v[(c>a)+int(c>b)]=c; return 3; } int sort4uniquely(int *v, int a, int b, int c, int d)const// a and b different and different from c and d, but c may equal d {// Cannot overflow if(c!=d) { v[(a>b)+int(a>c)+int(a>d)]=a; v[(b>a)+int(b>c)+int(b>d)]=b; v[(c>a)+int(c>b)+int(c>d)]=c; v[(d>a)+int(d>b)+int(d>c)]=d; return 4; } else return sort3uniquely(v,a,b,c); } bool compareReverseLexicographicInverted(int i1, int j1, int i2, int j2, mvtyp s1, mvtyp s2)const//s1 and s2 are always negative {// cannot overflow for(int i=0;i0; } } int indices[4]; int F=choices[i].first; int S=choices[i].second; int toCheck; if(i1==i) if(i2==i) toCheck=sort4uniquely(indices,F,S,j1,j2); else toCheck=sort3uniquely(indices,F,S,j1); else if(i2==i) toCheck=sort3uniquely(indices,F,S,j2); else toCheck=sort2uniquely(indices,F,S); for(int J=0;J0) return true; else if(temp<0) return false; } } return false; } mvtyp getVolume() {// Cannot overflow return denominator; } void replaceFirstOrSecond(bool first, int subconfigurationIndex, int newIndex, Vector const &target)__attribute__ ((always_inline))//updates the inequality table according to replacing first or second by newIndex in the subconfigurationIndex'th configuration {// Cannot overflow int newIndex2=newIndex;for(int i=0;i const &target){replaceFirstOrSecond(true,subconfigurationIndex,newIndex,target);} void replaceSecond(int subconfigurationIndex, int newIndex, Vector const &target){replaceFirstOrSecond(false,subconfigurationIndex,newIndex,target);} InequalityTable(std::vector > const &tuple_, int subconfigurationIndex_): tempA(tuple_.size()+Flags::computeDotProductInMatrix), tuple(tuple_), choices(tuple_.size()), subconfigurationIndex(subconfigurationIndex_), offsets(tuple_.size()) {// Cannot overflow k=tuple.size(); m=0; for(int i=0;i(k+Flags::computeDotProductInMatrix,m); {int offset=0;for(int i=0;i(k+Flags::computeDotProductInMatrix); } void setChoicesInitially() {// Cannot overflow //THIS WILL ONLY WORK FOR THE STARTING CONFIGURATION //sets denominators,A and choices (these must have been initialized to the right sizes) for(int i=0;i (i+0,i+1); for(int i=0;ii+1) for(int ii=i;ii const &target, int onlyK=-1) {// Can only overflow if target entries are too big. Actually it seems that it is not this function that will overflow but dotVector. bool empty=true; int bestConfigurationIndex=-1; int bestColumnIndex=-1; mvtyp targetDotBest=0; for(int i=0;i::const_RowRef Ak=const_cast&>(A)[k]; gfan::Matrix::const_RowRef Ak=const_cast&>(A)[k]; int offsetsi=offsets[i]; int tupleiwidth=tuple[i].getWidth(); if(onlyK!=-1)if(i!=onlyK)continue; for(int j=0;j0); } void setChoicesFromEarlierHomotopy(InequalityTable const &parent, mvtyp degreeScaling, Vector const &target) { // Overflows may happen, but only if the tuple entries are too big. // Notice that the code below has overflow checks everywhere, except in the loop marked with a comment. //sets denominators,A and choices (these must have been initialized to the right sizes //columns have been added to configuration this->subconfigurationIndex //for that reason we need to introduce new circuits. Old circuits are preserved. //chioices are "relative" so no update is needed. choices=parent.choices; int numberToDrop=(subconfigurationIndex!=0) ? numberToDrop=k+1 : 0; choices[subconfigurationIndex-1].first-=numberToDrop; choices[subconfigurationIndex-1].second-=numberToDrop; denominator=parent.denominator; int offsetOld=0; int offsetNew=0; for(int i=0;i=0) A.UNCHECKEDACCESS(subconfigurationIndex,offsetNew+j).msubWithOverflowChecking(tuple[i].UNCHECKEDACCESS(b,j),denominator); } for(int a=0;a > choices; Vector target; bool useFirstChanged; bool useSecondChanged; std::vector stack; int eliminatedK; int eliminatedKOffset; std::vector > tuple; std::vector offsets; int m; InequalityComparisonResult result; InequalityTable inequalityTable; void constructInequalityTableFromParent(InequalityTable const &parentTable, mvtyp degreeScaling) { inequalityTable.setChoicesFromEarlierHomotopy(parentTable, degreeScaling, target); } void constructInequalityTableInitially(mvtyp degreeScaling) { std::vector > tempTuple;for(int i=0;i(tuple.size(),1)); InequalityTable tempTable(tempTuple,-1); tempTable.setChoicesInitially(); constructInequalityTableFromParent(tempTable,degreeScaling); } SingleTropicalHomotopyTraverser(std::vector > const &tuple_, int m_, std::vector > const &choices_, Vector const &target_, int eliminatedK_): choices(choices_), target(target_), eliminatedK(eliminatedK_), tuple(tuple_), m(m_), inequalityTable(tuple,eliminatedK), offsets(tuple_.size()) { eliminatedKOffset=0;for(int i=0;i class TropicalRegenerationTraverser{ // The following class is an attempt to separate homotopy data from the traversal logic. class Data{ static mvtyp degree(Matrix const &m)//assumes entries of m are non-negative { mvtyp ret=0; for(int i=0;i > targets; std::vector > tuple; std::vector > > tuples; Vector degrees; bool isFiniteIndex(int level, int index) { return index>=tuple[0].getHeight()+1; } std::vector > produceIthTuple(int i) { int n=tuple[0].getHeight(); std::vector > ret; for(int j=0;j(n,degree(tuple[j])),tuple[j])); if(j>i)ret.push_back(simplex(n,1)); } return ret; } Data(std::vector > const &tuple_):tuple(tuple_) { int n=tuple[0].getHeight(); {//adjusting to positive orthant for(int i=0;i targ; for(int j=0;j::allOnes(n+1),Vector(tuple[i].getWidth()))); else targ=concatenation(targ,Vector(tuples[i][j].getWidth())); } targets.push_back(targ); } }; std::vector > firstIntersection() { std::vector > ret; for(int i=0;i(i+0,i+1)); return ret; } void castToNextLevel(std::vector > const &choices, int i, int S, std::vector > &ret) { assert(ret.size()==choices.size()); for(int j=0;j=S); assert(ret[i].second>=S); ret[i].first-=S; ret[i].second-=S; } }; static int cayleyConfigurationWidth(std::vector > const &tuple) { int m2=0; for(int i=0;i MySingleTropicalHomotopyTraverser; std::vector traversers; Data fullData; int level; bool deadEnd; bool isLevelLeaf; bool isSolutionVertex; std::vector isLevelLeafStack; TropicalRegenerationTraverser(std::vector > const &tuple_): fullData(tuple_),counter(0),depth(0) { assert(tuple_.size()); for(int i=0;i class SpecializedRTraverser: public Traverser { public: typedef TropicalRegenerationTraverser MyTropicalRegenerationTraverser; MyTropicalRegenerationTraverser T; mvtypDouble mixedVolume; int numberOfExpensiveSteps; SpecializedRTraverser(std::vector > const &tuple_): mixedVolume(), numberOfExpensiveSteps(0), T(tuple_) //Constructor my throw if input is too big. { numberOfExpensiveSteps++; T.findOutgoingAndProcess(false); } int getEdgeCountNext( void ) { if(!aborting) { try{ return T.numberOfChildren(); } catch(...){abort();} } return 0; } int moveToNext( int index, bool collect_info ) { if(!aborting) { try{ T.goToNthChild(index); numberOfExpensiveSteps++; T.findOutgoingAndProcess(false); } catch(...){abort();} } return 0; } void moveToPrev( int index ) { if(!aborting) { try{ T.goBack(); //index ignored } catch(...){abort();} } } void collectInfo( void ) { if(!aborting) { try{ if(T.isSolutionVertex) mixedVolume.addWithOverflowCheck(T.traversers[T.level].inequalityTable.getVolume().extend()); } catch(...){abort();} } } void printState( void ) { T.print(); } }; } #endif /* GFANLIB_TROPICALHOMOTOPY_H_ */ gfan0.6.2/src/renderer.cpp0000644000175000017500000000644213122232611014767 0ustar andersanders#include "renderer.h" #include int StandardMonomialRenderer::getOffsetX() { return boxSize*maxEntry*(1+2*(position%numberOfDrawingsPerLine)); } int StandardMonomialRenderer::getOffsetY() { return boxSize*maxEntry*(1+2*(position/numberOfDrawingsPerLine)); } bool StandardMonomialRenderer::isInInitialIdeal(const PolynomialSet &s,int x, int y, int z) { IntegerVector v(3); v[0]=x; v[1]=y; v[2]=z; PolynomialSet::const_iterator i; for(i=s.begin();i!=s.end();i++) if(i->getMarked().m.exponent.divides(v))break; return i!=s.end(); } int StandardMonomialRenderer::trace(const PolynomialSet &s, int x, int y, int z, int d) { int pos=0; while(1) { bool wasIn=isInInitialIdeal(s,x,y,z); if(!wasIn)return -1; switch(d) { case 0: pos=x; x--; break; case 1: pos=y; y--; break; case 2: pos=z; z--; break; } if(x<0 || y<0 || z<0)break; bool isIn=isInInitialIdeal(s,x,y,z); if(!isIn && wasIn) return pos; } return 0; } void StandardMonomialRenderer::putPoint(float x, float y, int rotation, float size) { //rotation is clockwise fprintf(f," %i %i",getOffsetX()+int(x+size*sin(rotation*3.1415927f/3)),getOffsetY()+int(y-size*cos(rotation*3.1415927f/3))); } void StandardMonomialRenderer::drawQuad(int x, int y, int z, int rotation, int color, int intensity) { fprintf(f,"2 3 0 1 0 %i 50 0 %i 0.000 0 0 -1 0 0 5\n ",color, intensity); putPoint((x-y)*boxSize*sqrt(0.75),boxSize*(0.5*(x+y)-z),0,0); putPoint((x-y)*boxSize*sqrt(0.75),boxSize*(0.5*(x+y)-z),rotation,boxSize); putPoint((x-y)*boxSize*sqrt(0.75),boxSize*(0.5*(x+y)-z),rotation+1,boxSize); putPoint((x-y)*boxSize*sqrt(0.75),boxSize*(0.5*(x+y)-z),rotation+2,boxSize); putPoint((x-y)*boxSize*sqrt(0.75),boxSize*(0.5*(x+y)-z),0,0); fprintf(f,"\n"); } StandardMonomialRenderer::StandardMonomialRenderer(FILE *f): numberOfDrawingsPerLine(5), maxEntry(8), position(0), boxSize(120) { this->f=f; fprintf(f,"#FIG 3.2\n" "Landscape\n" "Center\n" "Inches\n" "Letter\n" "100.00\n" "Single\n" "-2\n" "1200 2\n"); } void StandardMonomialRenderer::setMaxEntry(int maxEntry) { this->maxEntry=maxEntry; } void StandardMonomialRenderer::setBoxSize(int boxSize) { this->boxSize=boxSize; } void StandardMonomialRenderer::setNumberOfDrawingsPerLine(int numberOfDrawingsPerLine) { this->numberOfDrawingsPerLine=numberOfDrawingsPerLine; } void StandardMonomialRenderer::render(const PolynomialSet &s) { int x,y,z; bool color=false; x=maxEntry; for(y=0;y=0) { if(color) drawQuad(pos,y,z,4,pos?15:7); else drawQuad(pos,y,z,4,7,pos?10:20);//dark } } y=maxEntry; for(x=0;x=0) { if(color) drawQuad(x,pos,z,0,pos?17:7); else drawQuad(x,pos,z,0,7,pos?12:20); } } z=maxEntry; for(x=0;x=0) { if(color) drawQuad(x,y,pos,2,pos?3:7); else drawQuad(x,y,pos,2,7,pos?14:20);//light } } position++; } gfan0.6.2/src/enumeration.h0000644000175000017500000000367313122232611015157 0ustar andersanders#ifndef ENUMERATION_H_INCLUDED #define ENUMERATION_H_INCLUDED #include "polynomial.h" class EnumerationTarget { public: virtual void beginEnumeration(const PolynomialSet &groebnerBasis)=0; virtual void endEnumeration()=0; virtual bool basis(const PolynomialSet &groebnerBasis)=0; /* return false to break enumaration */ }; class EnumerationTargetCollector: public EnumerationTarget { public: PolynomialSetList theList; void beginEnumeration(const PolynomialSet& g); void endEnumeration(); bool basis(const PolynomialSet &groebnerBasis); PolynomialSetList getList(); }; class EnumerationPrinter: public EnumerationTarget { }; class EnumerationFilePrinter: public EnumerationPrinter { FILE *initialisedFile; protected: string filename; FILE *file; public: EnumerationFilePrinter(); ~EnumerationFilePrinter(); void open(std::string filename); void open(FILE *file); void close(); virtual void onOpened()=0; virtual void onClose()=0; virtual void onClosed()=0; virtual string extension(); }; class EnumerationAlgorithm { protected: EnumerationTarget *target; int progressCounter; virtual void printProgress(int step=1); void targetBeginEnumeration(const PolynomialSet &groebnerBasis){if(target)target->beginEnumeration(groebnerBasis);} void targetEndEnumeration(){if(target)target->endEnumeration();} bool targetBasis(const PolynomialSet &groebnerBasis){bool ret=true;if(target)ret=target->basis(groebnerBasis);printProgress();return ret;} public: EnumerationAlgorithm(){target=0;progressCounter=0;} void setEnumerationTarget(EnumerationTarget *target){this->target=target;} virtual void enumerate(const PolynomialSet &groebnerBasis){} }; // The following is used to glue the old code to the new code #include "symmetrictraversal.h" class TargetGlue:public SymmetricTarget { EnumerationTarget ⌖ public: TargetGlue(EnumerationTarget &target_); bool process(ConeTraverser &traverser); }; #endif gfan0.6.2/src/monomial.h0000644000175000017500000000121213122232611014427 0ustar andersanders#ifndef MONOMIAL_H_INCLUDED #define MONOMIAL_H_INCLUDED #include #include "vektor.h" #include "polynomialring.h" using namespace std; class Monomial { PolynomialRing theRing; public: int testtest; IntegerVector exponent; Monomial(PolynomialRing const &r): theRing(r), exponent(r.getNumberOfVariables())/* In Gfan 0.4 the exponent was not initialized. Does this slow the program now?*/ { } Monomial(PolynomialRing const &r, IntegerVector const &v); PolynomialRing const &getRing()const{return theRing;} string toString(bool alwaysWriteSign, bool writeIfOne, bool latex/*, bool mathMode*/)const; }; #endif gfan0.6.2/src/traverser_sphere.cpp0000644000175000017500000000652613122232611016547 0ustar andersanders#include "traverser_sphere.h" #include "determinant.h" #include "printer.h" //void updatePolyhedralCone(); SphereTraverser::SphereTraverser(vector const &cones_, map > const &adjacency_, IntegerVector const &startCone, IntegerVector const &normal): ConeTraverser(normal.size()), adjacency(adjacency_), cones(cones_) { currentConeIndex=0; for(;currentConeIndex const &candidates=adjacency[ridgeVector]; for(list::const_iterator i=candidates.begin();i!=candidates.end();i++) { PolyhedralCone l=cones[*i].link(ridgeVector); if(l.contains(rayVector)) { IntegerVectorList M; M.push_back(cones[currentConeIndex].getRelativeInteriorPoint()); M.push_back(currentNormal); currentConeIndex=*i; IntegerVectorList eq=cones[*i].getEquations(); assert(eq.size()==1); MatrixTermOrder T(M); if(!T(*eq.begin(),currentNormal-currentNormal))//HERE // if(dotLong(currentNormal,*eq.begin())>0) {currentNormal=*eq.begin();} else {currentNormal=-*eq.begin();} break; } // assert(0); } } IntegerVectorList SphereTraverser::link(IntegerVector const &ridgeVector) { list const &candidates=adjacency[ridgeVector]; PolyhedralCone ridge=cones[currentConeIndex].faceContaining(ridgeVector); ridge.canonicalize(); // IntegerVectorList partialBasis=ridge.getEquations(); IntegerVectorList partialBasis=ridge.link(ridge.getRelativeInteriorPoint()).dualCone().getEquations(); IntegerVector myRay=cones[currentConeIndex].link(ridgeVector).getUniquePoint(); partialBasis.push_back(currentNormal); partialBasis.push_back(myRay); int sign=determinantSign(partialBasis); partialBasis.pop_back(); partialBasis.pop_back(); IntegerVectorList c2; for(list::const_iterator i=candidates.begin();i!=candidates.end();i++) { // debug << "TESTET\n"; PolyhedralCone temp=cones[*i].link(ridgeVector); IntegerVector v=temp.getUniquePoint(); if(dotLong(v,currentNormal)>=0)c2.push_back(v); } assert(c2.size()>0); IntegerVectorList ret2; ret2.push_back(myRay); IntegerVector ret; for(IntegerVectorList::const_iterator i=c2.begin();i!=c2.end();i++) if(*i!=myRay){ ret=*i; break; } if(ret.size()==0) { PolyhedralFan f(theCone.ambientDimension()); f.insert(theCone); f.printWithIndices(&pout); pout< #include #include #include "gmp.h" #include "gfanlib_z.h" namespace gfan{ class Rational { mpq_t value; public: static bool isField() { return true; } Rational() { mpq_init(value); } Rational(signed long int value_) { mpq_init(value); // mpz_init_set_si(mpq_numref(value), value_); // mpz_init_set_ui(mpq_denref(value), 1); mpz_set_si(mpq_numref(value), value_); mpz_set_ui(mpq_denref(value), 1); mpq_canonicalize(value); } Rational(Rational const & value_) { mpq_init(value); mpq_set(value,value_.value); } Rational(mpq_t value_) { mpq_init(value); mpq_set(value,value_); } explicit Rational(Integer const & value_) { mpq_init(value); // mpz_init_set(mpq_numref(value), value_.value); // mpz_init_set_ui(mpq_denref(value), 1); mpz_set(mpq_numref(value), value_.value); mpz_set_ui(mpq_denref(value), 1); mpq_canonicalize(value); } ~Rational() { mpq_clear(value); } Rational& operator=(const Rational& a) { const Rational *A=(const Rational*)&a; if (this != A) { mpq_clear(value); mpq_init(value); mpq_set(value,a.value); } return *this; } bool isZero()const{ return mpz_sgn(mpq_numref(value))==0; } friend std::ostream &operator<<(std::ostream &f, Rational const &a) { void (*freefunc)(void *, size_t); mp_get_memory_functions(0,0,&freefunc); char *str=mpq_get_str(0,10,a.value); f< #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "breadthfirstsearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "timer.h" #include "log.h" #include "matrix.h" #include "lll.h" #include "polyhedralfan.h" #include "linalg.h" #include "determinant.h" #include "triangulation.h" #include "intsinpolytope.h" #include "graph.h" #include "halfopencone.h" #include "myassert.h" #include "triangulation2.h" #include "bsptree.h" #include "traverser_secondaryfan.h" #include "traverser_resultantfan.h" #include "traverser_resultantfanspecialization.h" #include "symmetrictraversal.h" #include "traverser_bsptree.h" #include #include class ResultantFanApplication : public GFanApplication { // StringOption inputOption; SimpleOption oldOption; SimpleOption optionCodimension; SimpleOption symmetryOption; SimpleOption optionIgnoreCones; SimpleOption optionSpecialization; SimpleOption optionVectorInput; SimpleOption optionProjection; SimpleOption optionPrettyPrint; public: const char *helpText() { return "This program computes the resultant fan as defined in \"Computing Tropical Resultants\" by Jensen and Yu. The input is a polynomial ring followed by polynomials, whose coefficients are ignored. The output is the fan of coefficients such that the input system has a tropical solution.\n"; } ResultantFanApplication(): // inputOption("-i","Specify the name of the input file.",0), symmetryOption("--symmetry","Tells the program to read in generators for a group of symmetries (subgroup of $S_n$) after having read in the vector configuration. The program DOES NOT checks that the configuration stays fixed when permuting the variables with respect to elements in the group. The output is grouped according to the symmetry.\n"), optionIgnoreCones("--nocones","Tells the program not to output the CONES and MAXIMAL_CONES sections, but still output CONES_COMPRESSED and MAXIMAL_CONES_COMPRESSED if --symmetry is used.\n"), oldOption("--old","Use old stupid algorithm"), optionCodimension("--codimension","Compute only the codimension of the resultant fan and return.\n"), optionSpecialization("--special","Read in a zero-one vector from the standard input and specialize all variables with a one. That is, compute the stable intersection of the resultant fan with the subspace where the variables with a one in the vector are forced to zero. AT THE MOMENT ALSO A RELATIVE INTERIOR POINT OF A STARTING CONE IS READ.\n"), optionVectorInput("--vectorinput","Read in a list of point configurations instead of a polynomial ring and a list of polynomials.\n"), optionProjection("--projection","Use the projection method to compute the resultant fan. This works only if the resultant fan is a hypersurface. If this option is combined with --special, then the output fan lives in the subspace of the non-specialized coordinates.\n"), optionPrettyPrint("--pretty","Pretty print point configuration in TeX math and exit.\n") { oldOption.hide(); optionPrettyPrint.hide(); registerOptions(); } const char *name() { return "_resultantfan"; } vector > tupleToIntervals(IntegerVectorListList const &tuple) { vector > ret; int last=0; for(IntegerVectorListList::const_iterator i=tuple.begin();i!=tuple.end();i++) { ret.push_back(pair(last,last+i->size())); last+=i->size(); } return ret; } int findD(IntegerVectorListList const &tuple) { int d=0; for(IntegerVectorListList::const_iterator i=tuple.begin();i!=tuple.end();i++) for(IntegerVectorList::const_iterator j=i->begin();j!=i->end();j++) {d=j->size();goto leave;} leave: for(IntegerVectorListList::const_iterator i=tuple.begin();i!=tuple.end();i++) for(IntegerVectorList::const_iterator j=i->begin();j!=i->end();j++) {assert(d==j->size());} return d; } IntegerVectorList toNonSpecialSubspace(IntegerVectorList const &l, IntegerVector const &special) { int n=special.size(); int nnonspecial=n-special.sum(); IntegerVectorList ret; for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { IntegerVector temp(nnonspecial); int J=0; for(int j=0;jsum()!=1))|| (!special && codim!=1)) if(codim!=1) { debug<<"The --projection option only works for hypersurfaces.\n"; assert(0); } IntegerMatrix A=cayleyConfiguration(tuple,findD(tuple)); int N=A.getHeight();//big ambientdim int n=A.getHeight(); if(special)n-=special->sum(); vector > intervals=tupleToIntervals(tuple); IntegerVectorList nonSpecialGenerators; IntegerVectorList specialGenerators; if(special) for(int i=0;isize();i++) if(!(*special)[i]) nonSpecialGenerators.push_back(IntegerVector::standardVector(N,i)); else specialGenerators.push_back(IntegerVector::standardVector(N,i)); SelectionIterator iter(intervals); IntegerVectorList linealityGen=A.transposed().getRows(); vector F; do { IntegerVectorList gen; int I=0; for(int i=0;i a=BSPTree::buildPointers(F); BSPTree tree(n,a,0,false); // debug<<"Number of regions"< > intervals=tupleToIntervals(tuple);//polynomialSetToIntervals(g); // debug<<"Cayley configuration:"< exponentsA=g.exponents(); IntegerVectorListList exponentsA=tuple; log1 debug<<"FRONT"< > intervals; int I=0; for(list::const_iterator i=exponentsA.begin();i!=exponentsA.end()) { intervals.push_back(pair(I,I+i->size()); I+=i->size(); }*/ for(list::const_iterator i=exponentsA.begin();i!=exponentsA.end();i++)for(IntegerVectorList::const_iterator j=i->begin();j!=i->end();j++)exponentsL.push_back(*j); IntegerMatrix exponentMatrix=rowsToIntegerMatrix(exponentsL).transposed(); if(isSpecializedResultantEmpty(exponentMatrix,intervals,special)) { debug<<"The specialized resultant variety is empty\n"; assert(0); } /* * Find generic starting point omega. */ PolyhedralCone toBeAvoided=intersection(specializedToSubspace(special),PolyhedralCone::givenByRays(IntegerVectorList(),A.transposed().getRows(),A.getHeight())); IntegerVectorList l=perturbationSequenceRek(exponentMatrix,intervals,IntegerVector::allOnes(exponentsL.size()),special,toBeAvoided); log1 D(l); IntegerMatrix cayley=cayleyConfiguration(exponentsA,D).transposed(); Triangulation2::makeConfigurationFullDimensional(cayley); PolyhedralCone secondaryCone=perturbationSequenceToVectorInSecondaryCone(l, cayley); IntegerVector omega=intersection(secondaryCone,specializedToSubspace(special)).getRelativeInteriorPoint(); // D(secondaryCone); /* { IntegerVector omega; int codimension=coDimensionOfResultantVariety(tuple,findD(tuple),&omega); if(secondaryCone.dimension()+codimension!=secondaryCone.ambientDimension()) } */ ResultantFanSpecializationTraverser traverser(tuple,D,A,intervals,special,omega,special.size()-special.sum()-coDimensionOfResultantVariety(tuple,findD(tuple),0)); int n=traverser.refToPolyhedralCone().ambientDimension(); SymmetryGroup s(n); SymmetricTargetFanBuilder target(n,s); symmetricTraverse(traverser,target,&s); target.getFanRef().printWithIndices(&pout, (symmetryOption.getValue()?FPF_group|FPF_conesCompressed:0)| (optionIgnoreCones.getValue()?0:FPF_conesExpanded)| FPF_maximalCones|FPF_cones, &s); } return 0; } // PolynomialSet g=FileParser(Stdin).parsePolynomialSetWithRing(); // IntegerVectorListList tuple=g.exponents(); log1 debug<getRelativeInteriorPoint(); log1 {static int t;t++;if(!(t&127))debug< T=Triangulation::triangulate(A); for(list::const_iterator i=T.begin();i!=T.end();i++) { IntegerVector v=i->size(); int J=0; for(Triangulation::Cone::const_iterator j=i->begin();j!=i->end();j++,J++) v[J]=*j; t.bases.insert(v); } } WeightReverseLexicographicTermOrder T(w); t.changeToTriangulationInducedBy(T); // t.print(debug); map > equivalenceClasses; for(set::const_iterator i=t.bases.begin();i!=t.bases.end();i++) { IntegerVectorList M; IntegerVector temp(1); for(int j=0;jsize();j++) {temp[0]=w[(*i)[j]];M.push_back(concatenation(A[(*i)[j]],temp));} IntegerMatrix M2=rowsToIntegerMatrix(M); IntegerVector normal=vectorInKernel(M2); for(int j=0;jsize();j++)equivalenceClasses[normal].insert((*i)[j]); } bool someOK=false; for(map >::const_iterator i=equivalenceClasses.begin();i!=equivalenceClasses.end();i++) { bool OK=true; int first=0; assert(0);//FIX THE CODE BELOW WHEN THERE IS NO g /* for(PolynomialSet::const_iterator j=g.begin();j!=g.end();j++) { int last=first+j->numberOfTerms(); int numberFound=0; for(int k=first;ksecond.count(k))numberFound++; if(numberFound<2)OK=false; first=last; }*/ if(OK)someOK=true; } if(someOK)f3.insert(*ii); } } f3.printWithIndices(&pout); return 0; } }; static ResultantFanApplication theApplication; gfan0.6.2/src/traverser_tropical.cpp0000644000175000017500000001426313122232611017073 0ustar andersanders#include "traverser_tropical.h" #include #include "bergman.h" #include "tropical.h" #include "division.h" #include "wallideal.h" #include "groebnerengine.h" #include "tropical2.h" #include "multiplicity.h" #include "buchberger.h"//in time use groebnerengine.h instead #include "log.h" static void checkSameLeadingTerms(PolynomialSet const &a, PolynomialSet const &b) { assert(a.size()==b.size()); PolynomialSet::const_iterator A=a.begin(); for(PolynomialSet::const_iterator B=b.begin();B!=b.end();B++,A++) assert(A->getMarked().m.exponent==B->getMarked().m.exponent); } TropicalTraverser::TropicalTraverser(PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &idealGroebnerBasis_): ConeTraverser(coneGroebnerBasis_.getRing().getNumberOfVariables()), coneGroebnerBasis(coneGroebnerBasis_), idealGroebnerBasis(idealGroebnerBasis_), theCone(coneGroebnerBasis_.getRing().getNumberOfVariables()) { n=coneGroebnerBasis_.getRing().getNumberOfVariables(); updatePolyhedralCone(); PolyhedralCone homogeneitySpac=homogeneitySpace(coneGroebnerBasis); d=homogeneitySpac.dimensionOfLinealitySpace(); } void TropicalTraverser::updatePolyhedralCone() { //AsciiPrinter(Stderr)<getMarked(); P.printPolynomial(m); if(division(m,temp,T).isZero()){cerr<<"YES";} cerr<theCone; rayCone.canonicalize(); { if(rayCone.getUniquePoint().isZero())trouble=true; } rays.push_back(rayCone.getUniquePoint()); } if(trouble) { // b.print(P); // P<size(); SymmetryGroup s(n); s.computeClosure(generators); s.print(Stderr); fprintf(Stderr,"\n"); IntegerVectorList vList=P.parseIntegerVectorList(); IntegerVectorList rep; for(IntegerVectorList::const_iterator i=vList.begin();i!=vList.end();i++) { bool found=false; for(IntegerVectorList::const_iterator j=rep.begin();j!=rep.end();j++) { if(i->sum()==j->sum()) { for(SymmetryGroup::ElementContainer::const_iterator k=s.elements.begin();k!=s.elements.end();k++) if(SymmetryGroup::compose(*k,*j)==*i) { found=true; break; } } if(found)break; } if(!found)rep.push_back(*i); } p.printVectorList(rep); return 0; } }; static RepresentativesApplication theApplication; gfan0.6.2/src/fieldlp.cpp0000644000175000017500000001651013122232611014575 0ustar andersanders#include "fieldlp.h" FieldVector FieldLP::subvector(FieldVector const &v, set const &b) { FieldVector ret(v.getField(),b.size()); int I=0; for(set::const_iterator i=b.begin();i!=b.end();i++,I++) ret[I]=v[*i]; return ret; } FieldMatrix FieldLP::submatrix(FieldMatrix const &m, set const &b) { FieldMatrix ret(m.getField(),b.size(),m.getWidth()); int I=0; for(set::const_iterator i=b.begin();i!=b.end();i++,I++) ret[I]=m[*i]; return ret; } FieldVector FieldLP::edgeDirection(int i)const { set basis2=basis; assert(basis2.count(i)); basis2.erase(i); FieldMatrix A2=submatrix(A,basis2); FieldMatrix ker=A2.reduceAndComputeKernel(); assert(ker.getHeight()==1); FieldVector e=ker[0]; if(dot(A[i],e).sign()<0)return e; return theField.zHomomorphism(-1)*e; } bool FieldLP::isImprovingDirection(int i)const { return dot(edgeDirection(i),w).sign()>0; } FieldElement FieldLP::improvement(int i, int &newBasisMember)const { FieldVector e=edgeDirection(i); FieldElement ew=dot(e,w); FieldElement ret(theField); bool first=true; newBasisMember=-1; for(int s=0;s=0;s--)//This is _the_ line where an anticycling rule is implemented { FieldElement denominator=dot(A[s],e); if(denominator.sign()>0) { FieldElement imp=(b[s]-dot(A[s],x))*denominator.inverse()*ew; if(first){ret=imp;newBasisMember=s;first=false;} if((imp-ret).sign()<=0){newBasisMember=s;ret=imp;} } } return ret; } int FieldLP::step() { FieldElement impBest(theField); int bestIndex=-1; int bestNewElement=-1; for(set::const_iterator i=basis.begin();i!=basis.end();i++) { // AsciiPrinter P(Stderr); // edgeDirection(*i).print(P); if(isImprovingDirection(*i)) { //fprintf(Stderr,"IMPROVING DIRECTION\n"); int newBasisElement; FieldElement imp=improvement(*i,newBasisElement); //P.printFieldElement(imp); //P.printNewLine(); if(newBasisElement==-1)return -1; //UNBOUNDED if((imp-impBest).sign()>=0)//needed for perturbation { impBest=imp; bestIndex=*i; bestNewElement=newBasisElement; } } } if(bestIndex==-1) return 0; //OPTIMAL set basis2=basis; //fprintf(Stderr,"REMOVING %i INSERTING %i\n",bestIndex,bestNewElement); basis2.erase(bestIndex); basis2.insert(bestNewElement); setCurrentBasis(basis2); return 1; } FieldLP::FieldLP(FieldMatrix const &A_, FieldVector const &b_): A(A_), b(b_), theField(A_.getField()), x(A_.getField(),0), w(A.getField(),A_.getWidth()) { // if(A.getHeight()!=b.size())fprintf(Stderr,"%i %i",A.getHeight(),b.size()); assert(A.getHeight()==b.size()); } void FieldLP::setObjectiveFunction(FieldVector const &w_) { w=w_; assert(A.getWidth()==w.size()); } FieldVector FieldLP::basisToPoint(set const &basis)const { AsciiPrinter P(Stdout); // FieldMatrix AT=A.transposed(); // AT.printMatrix(P); FieldMatrix A2(A.getField(),basis.size(),A.getWidth()); FieldVector b2(A.getField(),basis.size()); int I=0; for(set::const_iterator i=basis.begin();i!=basis.end();i++,I++) { A2[I]=A[*i]; b2[I]=b[*i]; } //A2.printMatrix(P); //b2.print(P); FieldMatrix s=A2.solver(); //fprintf(Stderr,"%i %i\n",s.getWidth(),b2.size()+A.getHeight()); //s.printMatrix(P); //concatenation(b2,FieldVector(b2.getField(),A.getWidth())).print(P); FieldVector r=s.canonicalize(concatenation(b2,FieldVector(b2.getField(),A.getWidth()))); //r.print(P); assert(r.subvector(0,basis.size()).isZero()); return r.subvector(basis.size(),r.size()); } void FieldLP::setCurrentBasis(set const &basis_) { basis=basis_; x=basisToPoint(basis); } void FieldLP::print(Printer &P)const { P.printString("LPprogram\n"); P.printString("A:\n"); A.printMatrix(P); P.printString("w:\n"); w.print(P); P.printString("b:\n"); b.print(P); P.printString("current basis:\n"); for(set::const_iterator i=basis.begin();i!=basis.end();i++)P.printInteger(*i); P.printString("x:\n"); x.print(P); } FieldMatrix FieldLP::computeLinealitySpace() { FieldMatrix temp=A; return temp.reduceAndComputeKernel(); } FieldLP FieldLP::buildLPForFeasibilityCheck() { assert(computeLinealitySpace().getHeight()==0); set S; { FieldMatrix temp=A.flipped().transposed();//important that inequalities which do not appear in basis set are temp.reduce(); int i=-1; int j=-1; while(temp.nextPivot(i,j)) { S.insert(A.getHeight()-1-j);//perturbed furthest //fprintf(Stderr,"INSERTING %i\n",A.getHeight()-1-j); } } FieldMatrix AS=submatrix(A,S); FieldMatrix ASSolver=AS.solver(); FieldVector xs2=ASSolver.canonicalize(concatenation(subvector(b,S),FieldVector(b.getField(),A.getWidth()))).subvector(S.size(),S.size()+A.getWidth()); set inequalitiesWithSlack; for(int i=0;i0) { inequalitiesWithSlack.insert(i); //fprintf(Stderr,"adding slack variable\n"); } } FieldMatrix newA=combineOnTop( combineLeftRight( A, FieldMatrix( theField, A.getHeight(), inequalitiesWithSlack.size() ) ), FieldMatrix( theField, inequalitiesWithSlack.size(), A.getWidth()+inequalitiesWithSlack.size() ) ); FieldVector newW(theField,inequalitiesWithSlack.size()+A.getWidth()); int I=0; for(set::const_iterator i=inequalitiesWithSlack.begin();i!=inequalitiesWithSlack.end();i++,I++) { newA[*i][I+A.getWidth()]=theField.zHomomorphism(-1); // int sign=dot(A[*i],xs2).sign(); newA[I+A.getHeight()][I+A.getWidth()]=theField.zHomomorphism(-1);//(sign>0)?-1:1); newW[I+A.getWidth()]=theField.zHomomorphism(-1);//(sign>0)?-1:1); } set newBasis; // for(int i=0;i::const_iterator i=S.begin();i!=S.end();i++)newBasis.insert(*i); for(set::const_iterator i=inequalitiesWithSlack.begin();i!=inequalitiesWithSlack.end();i++)newBasis.insert(*i); FieldLP ret(newA,concatenation(b,FieldVector(theField,inequalitiesWithSlack.size()))); ret.setObjectiveFunction(newW); ret.setCurrentBasis(newBasis); return ret; } bool FieldLP::findFeasibleBasis() { FieldLP A2=buildLPForFeasibilityCheck(); AsciiPrinter Q(Stdout); int status; do { //A2.print(Q); status=A2.step(); } while(status==1); fprintf(Stderr,status?"LP is unbounded.\n":"Optimal solution found.\n"); //A2.print(Q); set newBasis; for(set::const_iterator i=A2.basis.begin();i!=A2.basis.end();i++) { if(*i S; { FieldMatrix temp=A; temp.reduce(); int i=-1; int j=-1; while(temp.nextPivot(i,j))S.insert(j); } // FieldMatrix(theField,A.getHeight(),S.size()); FieldLP ret(submatrix(A.transposed(),S).transposed(),b); //fprintf(Stderr,"New height=%i New width=%i\n",ret.A.getHeight(),ret.A.getWidth()); // AsciiPrinter P(Stderr); //ret.print(P); if(w.size())ret.setObjectiveFunction(subvector(w,S)); return ret; } gfan0.6.2/src/application.h0000644000175000017500000002364113122232611015131 0ustar andersanders#ifndef APPLICATION_H_INCLUDED #define APPLICATION_H_INCLUDED #include #include // A general application. // This could solve several problems: // - the help text could be automatically generated // - duplicate main code could be removed // - it would be easy to parse options // - all applications could be linked to a single file thereby saving disk-space /** @brief A command line application. The class Application describes the general command line application. The compiled Gfan executable consists of several command line applications. When the static main() is run it is decided which application to invoke by investigating argv[0] and other command line options. A command line application will register itself during construction. Typically the Appliction is a static object. Therefore the Application has been registered when main() is executed. The static main() is a friend of Application which makes it possible for main() to search through the linked list of Applications. The Application::next member is used as a next pointer in the linked list of registered Application s. An Application can have a set of associated Option s. When an Option is constructed it is put into a static temporary linked list. When an Application has constructed all its Options it should call registerOptions() to move the linked list of Options into the Application s linked lists of Option s. */ class Application{ // Nested Option Classes /** The general commmand line option. */ protected: /** This abstract superclass describes the general Option. An Option object is intended to be part of an Application object. Before the Application::main() is run the command line is parsed by matching argv[1], argv[2]... with the Option s of the Application in question. The matches() method is called with argv[i] and by the return value the Option tells if it matches the argv[i] string. If this is the case then the parseValue() method will be called to let the Option take values from argv[i+1], argv[i+2]... as it likes. All this has already been taken care of in the code of the subclasses of this class. These subclasses can be used without worrying about the implementation details. See the documentation for the respective subclasses. */ class Option{ bool hidden; protected: /** The base pointer for a temporary linked list of Option s. When an Option is created it is added to the list by its constructor. The content of this list is later moved to a linked list for the Application of which the Option is a part. */ static Option *constructionList; public: Option(); /** An Option can be hidden which means that it does not show up in the help text of the Application. This function tells whether the Option is hidden or not. */ bool isHidden()const; /** This method hides the Option. See isHidden(). */ void hide(bool b=true); /** This method tells whether the Option matches a given string or not. Notice that a Option may match more than a single string allowing command line parameters such as -n2 and -n7 to match the same Option. @param s The string to be matched. */ virtual bool matches(const char *s)=0; /** @todo document this method */ virtual void onOptionsParsed(); /** This function returns a string that will be used in the documentation to denote the Option. */ virtual std::string documentationMatchString()=0; /** This function returns the a string describing the Option to be used for documentation. */ virtual std::string documentationDescription()=0; /** When this method is called the Option has the possibility to read off its value from the command line through argv[]. This only happens if the Option already accepted the argv[t] string as a match through matches(). How many additional strings the Option reads its value from is written to *numberOfArguments. @param t the index of the matching command line string. @param argv the command line strings. @param ok is considered to be a return value telling whether the commandline strings were parsed correctly. The pointer is not allowed to be null. @param numberOfArguments is considered to be return value telling how many additional (besides argv[t]) command line strings the method parsed. This allows each option to "eat" a different number of command line strings. The pointer is not allowed to be null. */ virtual void parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed)=0; static Option *getOptionList(); Option *next; }; class StringMatchingOption: public Option { protected: const char *matchString; const char *description; bool isExactMatch(const char *s); public: virtual std::string documentationMatchString(); virtual std::string documentationDescription(); StringMatchingOption(const char *s, const char *description_=""); bool matches(const char *s); }; class SimpleOption: public StringMatchingOption{ bool value; public: SimpleOption(const char *s, const char *description); void parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed); bool getValue(); }; class ValueOption: public StringMatchingOption{ public: virtual std::string documentationMatchString(); virtual void assignValue(const char *s)=0; ValueOption(const char *s, const char *description); void parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed); }; class StringOption: public ValueOption{ const char *value; public: StringOption(const char *s, const char *description, const char *initialValue=0); void assignValue(const char *s); const char *getValue(); }; class IntegerOption: public ValueOption{ int value; bool hasRange; int lower,upper; public: IntegerOption(const char *s, const char *description, int initialValue=0); IntegerOption(const char *s, const char *description, int initialValue, int lower, int upper); void assignValue(const char *s); int getValue(); }; class ZeroOneOption: public IntegerOption{ public: ZeroOneOption(const char *s, const char *description, int initialValue=0); }; // Application members private: static class Application *applicationList; static class Application *findApplication(char *name); protected: static std::list getSortedApplicationList(); /** This static procedure makes a symbolic link (on the file system) for registered Application s to the Gfan executable in the specified path. This procedure is supposed to be called during the installation of Gfan. @param name The name of the Gfan executable. @param all If false an Application only gets a symbolic link if its includeInDefaultInstallation() returns true. @param path The path to the Gfan executable and directory of the symbolic links. Must be terminated by a '/'. */ static void makeSymbolicLinks(const char *name, bool all, const char *path); /** This procedure produces the list of Gfan Application s in the appendix of the Gfan user's manual. The contents is written as LaTeX to stdout. The output contains one subsection for each Application. An application is not included in the list if its includeInDefaultInstallation() returns false. @param all Forces all Application s to be documented. */ static void produceLatexDocumentation(bool all); /** The base pointer for a the linked list of the Option s of the Application. */ class Application::Option* optionList; public: /** Superconstructor. Adds the Application to the static linked list of Application s. */ Application(); /** The next pointer for the linked list of existing Application s. */ class Application *next; /** This procedure parses the arguments for the static main() and assigns values of the appropriate Option s of the Application. @param argc The number of arguments on the command line (including the name of the command). See K&R:"The C Programming Language". @param argv The arguments. See K&R:"The C Programming Language". @param argumentsToSkip The number of arguments to skip (excluding the name of the executable). Usually no options are skipped, but if the program is not invoked using a symbolic link, the first (index 0) argument is the executable name and the second (index 1) argument is the Application name which should be skipped when parsing Option s. */ bool parseOptions(int argc, char **argv, int argumentsToSkip); /** @return true if the Application should appear in the documentation / be installed during default installation of Gfan. */ virtual bool includeInDefaultInstallation(); /** After construction of its Application::Option s an Application should call this procedure to collect the Option s in the optionList. */ void registerOptions(); /** This procedure writes the help text of the Application to stderr and lists the Option s. */ virtual void printHelp(); /** This virtual method contains the code to be executed when the Application is run. @return The value to be passed to the shell when the program finishes execution. */ virtual int main()=0; virtual void onExit(); /** @return The help text for the documentation. The format is usual ASCII. */ virtual const char *helpText()=0; friend int main(int argc, char *argv[]); /** This function returns the name of the Application. This name is used for matching with arg[0] and other options to decide which application to run. */ virtual const char *name()=0; }; #endif gfan0.6.2/src/gfanlib_paralleltraverser.h0000644000175000017500000000546213122232611020043 0ustar andersanders// Parallel abstract graph traverser. Contributed by Bjarne Knudsen. #ifndef __traverser_h__ #define __traverser_h__ /* This file defines a Traverser interface. A Traverser can be used for going through an underlying structure of states. At each state, there is a number of next states. Moving the traverser to a next state changes its internal state. When constructing a Traverser, it should be in the start state (i.e. it should have no previous states). The traversal is over when there are no more next states. The state space should be a directed acyclic graph, so several previous states to a given state are allowed. There may be any number of end points, but only one start point. When traversing in a multi threaded fashion, each Traverser receives some of the collected information. It is up to the user of this interface to join that information when the traversal is done. */ namespace gfan{ class Traverser { public: bool aborting; // Added by Anders void abort(){aborting=true;} // Added by Anders Traverser():aborting(false){} // Added by Anders // Virtual destructor virtual ~Traverser( void ) {}; // Get the number of next states. virtual int getEdgeCountNext( void ) = 0; // The return value is the index for moving to the same previous // state again. The indexing of the previous state can be arbitrary, // but zero should be one of the previous index values. The // collect_info parameter will be true once for every edge in the // state graph during the traversal. This allows te traverser to // collect information along its edges. virtual int moveToNext( int index, bool collect_info ) = 0; // Go back to a previous state. Due to the return value of // moveToNext(), the state will be unchanged after calling // movetoPrev(moveToNext(index)) with a legal next index. virtual void moveToPrev( int index ) = 0; // This function will be called once for every state in a traversal. virtual void collectInfo( void ) = 0; // Function for printing the state to cout for debug purposes. virtual void printState( void ) = 0; }; // Traverse a structure in a single threaded way. The traverser should // be in the start state. The traverser may not be in the start state // when this function returns. void traverse_simple( Traverser* traverser ); // Traverse a structure using several traversers in several // threads. The traversers should all be in the start state. Several // traversers may go through the same state, but collectInfo() is only // called once for each state. The traversers may not be in the start // state when this function returns. void traverse_threaded( Traverser** traverser, int count, int step_count ); } #endif // __traverser_h__ gfan0.6.2/src/app_substitute.cpp0000644000175000017500000000224613122232611016232 0ustar andersanders#include "vektor.h" #include "printer.h" #include "parser.h" #include "gfanapplication.h" typedef list StringList; class SubstituteApplication : public GFanApplication { public: const char *helpText() { return "This program changes the variable names of a polynomial ring. The input is a polynomial ring, a polynomial set in the ring and a new polynomial ring with the same coefficient field but different variable names. The output is the polynomial set written with the variable names of the second polynomial ring.\n" "Example:\n" "Input:\n" "Q[a,b,c,d]{2a-3b,c+d}Q[b,a,c,x]\n" "Output:\n" "Q[b,a,c,x]{2*b-3*a,c+x}\n"; } SubstituteApplication() { registerOptions(); } const char *name() { return "_substitute"; } int main() { FileParser P(Stdin); PolynomialRing r=P.parsePolynomialRing(); PolynomialSet s=P.parsePolynomialSet(r); PolynomialRing r2=P.parsePolynomialRing(); AsciiPrinter(Stdout).printPolynomialRing(r2); AsciiPrinter(Stdout).printNewLine(); AsciiPrinter(Stdout).printPolynomialSet(s.embeddedInto(r2)); return 0; } }; static SubstituteApplication theApplication; gfan0.6.2/src/app_tropicalbasis.cpp0000644000175000017500000000606313122232611016657 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "polyhedralcone.h" #include "polyhedralfan.h" #include "tropical.h" #include "tropical2.h" #include "tropicalbasis.h" #include "log.h" class TropicalBasisApplication : public GFanApplication { SimpleOption optionHomogenize; public: const char *helpText() { return "This program computes a tropical basis for an ideal defining a tropical curve. Defining a tropical curve means that the Krull dimension of R/I is at most 1 + the dimension of the homogeneity space of I where R is the polynomial ring. The input is a generating set for the ideal. If the input is not homogeneous option -h must be used.\n"; } TropicalBasisApplication(): optionHomogenize("-h","Homogenise the input before computing a tropical basis and dehomogenise the output. This is needed if the input generators are not already homogeneous.") { registerOptions(); } const char *name() { return "_tropicalbasis"; } int main() { FileParser P(Stdin); /* StringParser P1("{1+76*a2*b*c+6*a2*c4+72*a*b3*c3," "46*b3*c+68*b3*a2*c+42*a3*c4+47*b6*a2}"); StringParser P2("{1-79ab^4-27b^3c^2+32a^4b^2c," "-36c-35b^3c^3+11a^4b^2c^2+90a^3b^6}"); */ PolynomialSet theInput=P.parsePolynomialSetWithRing(); PolynomialRing originalRing=theInput.getRing(); if(optionHomogenize.getValue()) { log1 fprintf(Stderr,"Homogenizing...\n"); IntegerVector grading=IntegerVector::allOnes(theInput.numberOfVariablesInRing()); /* { // It is not necessary to compute the true homogenization WeightReverseLexicographicTermOrder t(grading); buchberger(&theInput,t); }*/ PolynomialSet h=theInput.homogenization(theInput.getRing().withVariablesAppended("H")); wallInequalities(h); log1 fprintf(Stderr,"The homogenized ideal:\n"); log1 AsciiPrinter(Stderr).printPolynomialSet(h); theInput=h; } int n=theInput.numberOfVariablesInRing(); int homog=-1; { log1 debug.printString("Computing homogeneity space\n"); PolynomialSet idealGroebnerBasis=theInput; IntegerVector grading=IntegerVector::allOnes(theInput.numberOfVariablesInRing()); WeightReverseLexicographicTermOrder t(grading); buchberger(&idealGroebnerBasis,t); PolyhedralCone hspace=homogeneitySpace(idealGroebnerBasis); IntegerVectorList hv=hspace.dualCone().getEquations(); homog=hv.size(); log1 debug.printString("..done homogeneity space.\n"); } PolynomialSet theOutput=tropicalBasisOfCurve(n,theInput,0,homog); if(optionHomogenize.getValue()) { theOutput=theOutput.embeddedInto(originalRing); } AsciiPrinter(Stdout).printPolynomialRing(theOutput.getRing()); AsciiPrinter(Stdout).printNewLine(); AsciiPrinter(Stdout).printPolynomialSet(theOutput); return 0; } }; static TropicalBasisApplication theApplication; gfan0.6.2/src/app_evaluate.cpp0000644000175000017500000000265613122232611015632 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "buchberger.h" #include "wallideal.h" #include "termorder.h" #include "gfanapplication.h" #include "tropical2.h" #include "matrix.h" #include class EvaluationApplication : public GFanApplication { SimpleOption optionComplex; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program evaluates a list of polynomials in a point.\n"; } EvaluationApplication(): optionComplex("--complex","Read and evaluate using complex numbers rather than real numbers.") { registerOptions(); } const char *name() { return "_evaluation"; } int main() { FileParser P(Stdin); PolynomialSet g=P.parsePolynomialSetWithRing(); if(0){ for(int i1=1;i1<20;i1++) for(int i2=1;i2<20;i2++) for(int i3=1;i3<20;i3++) { FloatVector v(4); v[0]=i1/20.0; v[1]=i2/20.0; v[2]=i3/20.0; v[3]=1-v[1]-v[2]-v[0]; pout.printFloatVector(g.evaluateFloat(v)); } } if(optionComplex.getValue()) { ComplexVector x=P.parseComplexVector(); pout.printComplexVector(g.evaluateComplex(x)); } else { FloatVector x=P.parseFloatVector(); pout.printFloatVector(g.evaluateFloat(x)); } pout<<"\n"; return 0; } }; static EvaluationApplication theApplication; gfan0.6.2/src/subspace.h0000644000175000017500000000254013122232611014426 0ustar andersanders#ifndef SUBSPACE_H_INCLUDED #define SUBSPACE_H_INCLUDED #include "vektor.h" #include "polynomial.h" #include "linalg.h" Polynomial vectorToPolynomial(PolynomialRing const &r, IntegerVector const &v); /** @brief A subspace of Q^n. An object of this class represents a linear subspace of Q^n. All functionality is already available in the class FieldMatrix. However, the Subspace class is different in two ways: a Subspace cannot be changed after construction and the Subspace class provides operator< for sorting and distinguishing mathematical subspaces. */ class Subspace { int n;//ambient dimension // PolynomialSet basis; FieldMatrix basis2; IntegerVectorList integerRep;//REMOVE THIS public: /** Constructs a subspace given a generating set. @param generators generators for the subspace. @param ambientDimension the dimension of the ambient space. This number must equal the sizes of the vectors in generators. */ Subspace(IntegerVectorList const &generators, int ambientDimension=-1); bool contains(IntegerVector const &v)const; int dimension(); friend Subspace sum(Subspace const &a, Subspace const &b); int ambientDimension()const; IntegerVectorList getRepresentation()const; IntegerVector canonicalizeVector(IntegerVector const &v)const; bool operator<(Subspace const &b)const; }; #endif gfan0.6.2/src/gfanlib_tropicalintersection.h0000644000175000017500000000520713122232611020552 0ustar andersanders#include "gfanlib_matrix.h" #include "gfanlib_zcone.h" #include "gfanlib_zfan.h" namespace gfan{ class HalfOpenZCone { ZCone lifted; HalfOpenZCone(ZCone const &_lifted); public: int ambientDimension()const{return lifted.ambientDimension()-1;} HalfOpenZCone fromZCone(ZCone const &C, TermOrder const &t); HalfOpenCone(int dimension_, ZMatrix const &equations, ZMatrix const &nonstrict, ZMatrix const &strict, bool findFacets=false, bool canonicalize=false); HalfOpenCone(int ambientDimension);//full space bool isEmpty(); friend HalfOpenCone intersection(const HalfOpenZCone &a, const HalfOpenZCone &b, bool findFacets=false); friend bool haveEmptyIntersection(const HalfOpenZCone &a, const HalfOpenZCone &b); ZCone closure(); bool contains(IntegerVector const &v)const; #if 0 void splitIntoRelativelyOpenCones(list &l); void print(class Printer &p)const; friend bool operator<(HalfOpenZCone const &a, HalfOpenZCone const &b); void canonicalize(){lifted.canonicalize();} /** Remove all coordinates from the space except those listed in chosen. */ HalfOpenCone withChosenCoordinates(list chosen)const; HalfOpenCone rewrite(FieldMatrix const &A, list nonPivots)const; HalfOpenCone rewriteExpand(list pivots, IntegerVectorList const &newEquations)const; #endif }; class HalfOpenZConeProcessor { public: virtual bool process(HalfOpenZCone const &c); // Return true to abort. }; typedef std::vector HalfOpenZConeVector; void intersectHalfOpenFansUsingIntersectionTable(int ambientDimension, std::vector > const &newtonPolytopes, HalfOpenZConeProcessor *processor, HalfOpenZCone const *restrictingCone=0, class IntersectionTable); // if a cone in the intersection void intersectHalfOpenFans(int ambientDimension, std::vector > const &newtonPolytopes, HalfOpenZConeProcessor *processor, HalfOpenZCone const *restrictingCone=0); // if a cone in the intersection void intersectTropicalHypersurfaces(int ambientDimension, std::vector const &newtonPolytopes, HalfOpenZConeProcessor *processor, HalfOpenZCone const *restrictingCone=0); // if a cone in the intersection std::vector tropicalHypersurfaceIntersection(int ambientDimension, std::vector const &newtonpolytopes, HalfOpenZCone const *restrictingCone=0); std::vector decomposedTropicalHypersurface(ZMatrix const &newtonPolytope); std::vector intersection(std::vector const &A, std::vector const &B); } gfan0.6.2/src/field_rationals.h0000644000175000017500000000521313122232611015760 0ustar andersanders#ifndef FIELD_RATIONALS_H_INCLUDED #define FIELD_RATIONALS_H_INCLUDED #include #include /* Always include cstdio before gmp.h.*/ #include //remove? #include "vektor.h" #include "field.h" class FieldRationalsImplementation : public FieldImplementation { FieldElementImplementation *zHomomorphismImplementation(int n);/* Creates FieldElementImplementation object with refcount1 */ FieldElement zHomomorphism(int n); const char *name(); std::string toString()const; public: virtual bool isRationals()const; int getCharacteristic()const; FieldRationalsImplementation(); }; /* class FieldRationals : public Field { public: FieldRationals(); }; */ //extern FieldRationals Q; extern Field Q; extern Field QQ;//to replace Q. Uses int64 until overflow IntegerVector primitiveVector(vector const &v); IntegerVector toIntegerVector(vector const &v);// MUST HAVE INTEGER ENTRIES int toInteger(FieldElement const &a);// MUST BE INTEGER mpq_t *fieldElementToGmp(FieldElement const &c); double fieldElementToFloatingPoint(FieldElement const&c); /** * Will create a new FieldElement containing the value of c. The gmp representation of c is copied, * so c must be destructed by the caller. */ FieldElement fieldElementFromGmp(mpq_t *c); /** * Will create a new FieldElement containing the value of c. The gmp representation of c is copied, * so c must be destructed by the caller. */ FieldElement fieldElementFromGmpZ(const mpz_t *c); FieldElement gcd(FieldElement const &a, FieldElement const &b, FieldElement &s, FieldElement &t); /** * Assumes that a and b are integers in the field of rational numbers. * Assumes that b is non-zero. * The remainder (if pointer is non-zero) is set to the remainder * of a divided by b in the interval [0,B[, where B=abs(b)=max(b,-b). * The return value equals the integer (a-remainder)/b. */ FieldElement integerDivision(FieldElement const &a, FieldElement const &b, FieldElement *remainder=0); /**************************************************************************** * Here follows the inmplementation of the field, where num and den are * stored as int64 when possible. Otherwise, gmp integers are used. * In time this will replace the rational field above. */ class FieldRationals2Implementation : public FieldImplementation { FieldElementImplementation *zHomomorphismImplementation(int n);/* Creates FieldElementImplementation object with refcount1 */ FieldElement zHomomorphism(int n); const char *name(); std::string toString()const; public: virtual bool isRationals()const; int getCharacteristic()const; FieldRationals2Implementation(); }; #endif gfan0.6.2/src/app_idealproduct.cpp0000644000175000017500000000207013122232611016471 0ustar andersanders#include "parser.h" #include "printer.h" #include "saturation.h" #include "gfanapplication.h" #include "lp.h" class IdealProductApplication : public GFanApplication { FieldOption theFieldOption; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program computes the product IJ of ideals generated by sets of polynomials given in the input.\n"; } IdealProductApplication() { registerOptions(); } const char *name() { return "_idealproduct"; } int main() { LpSolver::printList(Stderr); lpSetSolver("cddgmp"); FileParser P(Stdin); PolynomialRing theRing=P.parsePolynomialRing(); PolynomialSet a=P.parsePolynomialSet(theRing); PolynomialSet b=P.parsePolynomialSet(theRing); PolynomialSet ret(theRing); for(PolynomialSet::const_iterator i=a.begin();i!=a.end();i++) for(PolynomialSet::const_iterator j=b.begin();j!=b.end();j++) { ret.push_back(*i * *j); } pout< union PODInteger { mpz_t *p; int64 v; }; class Integer { PODInteger data; void setValue(int64 v_) { data.v=(v_<<1)+1; } bool fits(int64 v) { // if(v>10)return false; // if(v<-10)return false; return ((v<<1)>>1)==v; } bool fitsIn32(int64 v) { return (int64)((((int)v)<<1)>>1)==v; } bool isImmediate()const { return data.v&1; } void extendToGmp() { int64 v=data.v>>1; data.p=(mpz_t*)malloc(sizeof(mpz_t)); mpz_init(*data.p); mpz_set_si(*data.p,v); } public: void shrink() { if(!isImmediate())if(mpz_fits_sint_p(*data.p)){*this=Integer(mpz_get_si(*data.p));} } Integer() { setValue(0); } Integer(const char *s) { data.p=(mpz_t*)malloc(sizeof(mpz_t)); mpz_init(*data.p); mpz_set_str(*data.p,s,10); } Integer(int64 v) { if(fits(v)) setValue(v); else { data.p=(mpz_t*)malloc(sizeof(mpz_t)); mpz_init(*data.p); mpz_set_si(*data.p,v); } } Integer(Integer const & value_) { if(value_.isImmediate()) { data.v=value_.data.v; } else { data.p=(mpz_t*)malloc(sizeof(mpz_t)); mpz_init_set(*data.p,*value_.data.p); } } ~Integer() { if(!isImmediate()) { mpz_clear(*data.p); free(data.p); } } Integer& operator=(const Integer& a) { const Integer *A=(const Integer*)&a; if (this != A) { if(!isImmediate()) { mpz_clear(*data.p); free(data.p); } if(!a.isImmediate()) { data.p=(mpz_t*)malloc(sizeof(mpz_t)); mpz_init_set(*data.p, *a.data.p); } else data.v=a.data.v; } return *this; } bool isZero()const{ if(isImmediate()) return data.v==1; return mpz_sgn(*data.p)==0; } friend std::ostream &operator<<(std::ostream &f, Integer const &a) { if(a.isImmediate()) f<<(a.data.v>>1); else { void (*freefunc)(void *, size_t); mp_get_memory_functions(0,0,&freefunc); char *str=mpz_get_str(0,10,*a.data.p); f<>1)+(data.v>>1); if(fits(res)) data.v=(res<<1)+1; else *this=(res); } else { if((a.data.v>>1)>=0) mpz_add_ui(*data.p,*data.p,a.data.v>>1); else mpz_sub_ui(*data.p,*data.p,-(a.data.v>>1)); } } else { if(isImmediate()) { int64 temp=data.v>>1; *this=a; if(temp>=0) mpz_add_ui(*data.p,*data.p,temp); else mpz_sub_ui(*data.p,*data.p,-temp); } else { mpz_add(*data.p,*data.p,*a.data.p); } } return *this; } Integer& operator-=(const Integer& a) { if(a.isImmediate()) { if(isImmediate()) { int64 res=(data.v>>1)-(a.data.v>>1); //cerr<<"\nRES:"<>1)>=0) mpz_sub_ui(*data.p,*data.p,a.data.v>>1); else mpz_add_ui(*data.p,*data.p,-(a.data.v>>1)); } } else { if(isImmediate()) { int64 temp=data.v>>1; *this=a; if(temp>=0) mpz_sub_ui(*data.p,*data.p,temp); else mpz_add_ui(*data.p,*data.p,-temp); mpz_neg(*data.p,*data.p); } else { mpz_sub(*data.p,*data.p,*a.data.p); } } return *this; } Integer& operator*=(const Integer& a) { if(a.isImmediate()) { if(isImmediate()) { // cerr<<"HERE0\n"; if(fitsIn32(a.data.v>>1)&&fitsIn32(data.v>>1)) { data.v=(((a.data.v>>1)*(data.v>>1))<<1)+1; return *this; } int64 temp=data.v>>1; data.p=(mpz_t*)malloc(sizeof(mpz_t)); mpz_init(*data.p); mpz_set_si(*data.p,temp); mpz_mul_si(*data.p,*data.p,a.data.v>>1); //cerr<<"HERE1\n"; //shrink? } else { mpz_mul_si(*data.p,*data.p,a.data.v>>1); } } else { if(isImmediate()) { int64 temp=data.v>>1; *this=a; mpz_mul_si(*data.p,*data.p,temp); } else { mpz_mul(*data.p,*data.p,*a.data.p); } } return *this; } Integer& operator/=(const Integer& a) { if(a.isImmediate()) { assert(a.data.v!=1);//division by zero if(isImmediate()) { data.v=(((data.v>>1)/(a.data.v>>1))<<1)+1; } else { if((a.data.v>>1)>0) mpz_div_ui(*data.p,*data.p,a.data.v>>1); else { mpz_div_ui(*data.p,*data.p,-(a.data.v>>1)); mpz_mul_si(*data.p,*data.p,-1);//TODO: improve } } } else { if(isImmediate()) { extendToGmp(); // cerr<<*this; // if(isZero()) assert(0);//Not implemented yet because this is unlikely to happen???? } // else { mpz_div(*data.p,*data.p,*a.data.p); } } return *this; } friend Integer operator-(const Integer &b) { Integer ret; ret-=b; return ret; } Integer operator+(const Integer &a)const { Integer ret(*this); ret+=a; return ret; } Integer operator-(const Integer &a)const { Integer ret(*this); ret-=a; return ret; } Integer operator*(const Integer &a)const { Integer ret(*this); ret*=a; return ret; } Integer operator/(const Integer &a)const { Integer ret(*this); ret/=a; return ret; } #if 0 void madd(const Integer &a,const Integer &b) { mpz_t temp; mpz_init(temp); mpz_mul(temp,a.value,b.value); mpz_add(value,value,temp); mpz_clear(temp); } #endif #if 0 bool operator<(const Integer &a)const { return mpz_cmp(value,a.value)<0; } bool operator==(const Integer &a)const { return mpz_cmp(value,a.value)==0; } #endif #if 0 bool operator!=(const Integer &a)const { return mpz_cmp(value,a.value)!=0; } #endif int sign()const { if(isImmediate()) { if(data.v<0)return -1; if((data.v>>1)>0)return 1; return 0; } return mpz_sgn(*data.p); } #if 0 static Integer gcd(Integer const &a, Integer const &b, Integer &s, Integer &t) { mpz_t r; mpz_init(r); mpz_gcdext(r,s.value,t.value,a.value,b.value); Integer ret(r); mpz_clear(r); return ret; } /** * Assigns the value to z. z must have been initialized as a gmp variable. */ void setGmp(mpz_t z)const { mpz_set(z,value); } /** * Returns a value which is useful for computing hash functions. */ signed long int hashValue()const { return mpz_get_si(value); } bool fitsInInt()const { mpz_t v; mpz_init(v); this->setGmp(v); bool ret=(mpz_fits_sint_p(v)!=0); mpz_clear(v); return ret; } #endif int64 toInt()const //repair this function { if(isImmediate()) return data.v>>1; if(mpz_fits_sint_p(*data.p)) return mpz_get_si(*data.p); assert(0); return 0; /* mpz_t v; mpz_init(v); this->setGmp(v); int ret=0; if(mpz_fits_sint_p(v)) ret=mpz_get_si(v); // else // ok=false; mpz_clear(v); return ret;*/ } string toString()const { stringstream s; if(isImmediate()) { //cerr<>1); } else { void (*freefunc)(void *, size_t); mp_get_memory_functions(0,0,&freefunc); char *str=mpz_get_str(0,10,*data.p); s<>1)==1)return 1; if(s.isImmediate()) { // if((s.data.v>>1)==1)return 1; int64 R=r.data.v>>1; int64 S=s.data.v>>1; if(R<0) R=-R; if(S<0)S=-S; if(S>1; if(a<0)a=-a; return Integer(mpz_gcd_ui(0,*s.data.p,a)); } } else { if(!s.isImmediate()) { Integer t; t.data.p=(mpz_t*)malloc(sizeof(mpz_t)); mpz_init(*t.data.p); mpz_gcd(*t.data.p,*s.data.p,*r.data.p); return t; } else { if((s.data.v>>1)==1)return 1; int64 a=s.data.v>>1; if(a<0)a=-a; return Integer(mpz_gcd_ui(0,*r.data.p,a)); } } // cerr<<"R"< #include "gfanlib_matrix.h" #include "gfanlib_z.h" namespace gfan{ Integer mixedVolume(std::vector const &tuple, int nthreads=0, int steps=500); namespace MixedVolumeExamples{ std::vector cyclic(int n); std::vector noon(int n); std::vector chandra(int n); std::vector katsura(int n); std::vector gaukwa(int n); std::vector eco(int n); } } #endif /* GFANLIB_MIXEDVOLUME_H_ */ gfan0.6.2/src/gfanlib_polymakefile.cpp0000644000175000017500000002313013122232611017315 0ustar andersanders/* * gfanlib_polymakefile.cpp * * Created on: Nov 17, 2010 * Author: anders */ #include "gfanlib_polymakefile.h" #include #include #include #include using namespace std; static void eatComment2(int &c, stringstream &s) { if(c=='#') { do c=s.get(); while(c!='\n' && !s.eof()); } } static void eatComment(stringstream &s) { int c=s.get(); while(c==' '||c=='\t')c=s.get(); eatComment2(c,s); s.unget(); } static string readUntil(istream &f, int c) { stringstream ret; int c2; c2=f.get(); // c2=fgetc(f); // while(c2!=c && c2!=EOF) while(c2!=c && !f.eof()) { ret< readIntList(istream &s) { list ret; int c=s.peek(); while(((c>='0') && (c<='9'))|| (c==' ')) { // fprintf(Stderr,"?\n"); int r; s >> r; ret.push_back(r); c=s.peek(); } return ret; } namespace gfan{ PolymakeProperty::PolymakeProperty(const std::string &name_, const std::string &value_): value(value_), name(name_) { } void PolymakeFile::open(std::istream &f) { isXml=false; // fileName=string(fileName_); // FILE *f=fopen(fileName.c_str(),"r"); // if(!f)//fprintf(Stderr,"Could not open file:\"%s\"\n",fileName_); // assert(f); int c=f.get();//fgetc(f); while(!f.eof()) { if(c=='_') { readUntil(f,'\n'); } else if(c!='\n') { f.unget(); // ungetc(c,f); string name=readUntil(f,'\n'); // fprintf(Stderr,"Reading:\"%s\"\n",name.c_str()); stringstream value; while(1) { string l=readUntil(f,'\n'); if(l.size()==0)break; value << l <\n"); for(list::const_iterator i=properties.begin();i!=properties.end();i++) { fprintf(f,"\n",i->name.c_str()); fprintf(f,"%s",i->value.c_str()); fprintf(f,"\n"); } fprintf(f,"\n"); } else { fprintf(f,"_application %s\n",application.c_str()); fprintf(f,"_version 2.2\n"); fprintf(f,"_type %s\n",type.c_str()); for(list::const_iterator i=properties.begin();i!=properties.end();i++) { fprintf(f,"\n%s\n",i->name.c_str()); fprintf(f,"%s",i->value.c_str()); } } fclose(f); } void PolymakeFile::writeStream(ostream &file) { if(isXml) { file << "\n"; for(list::const_iterator i=properties.begin();i!=properties.end();i++) { file << "name.c_str() << "\">\n"; file << i->value.c_str(); file << "\n"; } file << "\n"; } else { file << "_application " << application << endl; file << "_version 2.2\n"; file << "_type " << type << endl; for(list::const_iterator i=properties.begin();i!=properties.end();i++) { file << endl << i->name.c_str() << endl; file << i->value; } } } list::iterator PolymakeFile::findProperty(const char *p) { string s(p); for(list::iterator i=properties.begin();i!=properties.end();i++) { if(s==i->name)return i; } return properties.end(); } void PolymakeFile::writeProperty(const char *p, const string &data) { if(hasProperty(p)) { assert(0); } properties.push_back(PolymakeProperty(string(p),data)); } bool PolymakeFile::hasProperty(const char *p, bool doAssert) { if(doAssert) if(findProperty(p)==properties.end()) { fprintf(stderr,"Property: \"%s\" not found in file.\n",p); assert(0); } return findProperty(p)!=properties.end(); } Integer PolymakeFile::readCardinalProperty(const char *p) { assert(hasProperty(p,true)); list::iterator prop=findProperty(p); stringstream s(prop->value); int ret; s>>ret; return ret; } void PolymakeFile::writeCardinalProperty(const char *p, Integer n) { stringstream t; t<::iterator prop=findProperty(p); stringstream s(prop->value); // for(int i=0;i>v; if(s.eof())goto done; w[j]=v; } ret.appendRow(w); } done: if(height>=0)assert(ret.getHeight()==height); // cerr<>v; // while(!s.eof())std::cerr< *comments) { stringstream t; if(comments)assert((int)comments->size()>=m.getHeight()); if(isXml) { t << "\n"; for(int i=0;i"; for(int j=0;j\n"; } t << "\n"; } else { for(int i=0;i > PolymakeFile::readMatrixIncidenceProperty(const char *p) { vector > ret; assert(hasProperty(p,true)); list::iterator prop=findProperty(p); stringstream s(prop->value); while((s.peek()!=-1)&&(s.peek()!='\n')&&(s.peek()!=0)) { // fprintf(Stderr,"!\n"); int c=s.get(); //fprintf(Stderr,"%i",c); assert(c=='{'); ret.push_back(readIntList(s)); c=s.get(); assert(c=='}'); c=s.get(); while(c==' ' || c=='\t')c=s.get(); eatComment2(c,s); assert(c=='\n'); } return ret; } void PolymakeFile::writeIncidenceMatrixProperty(const char *p, const vector > &m) { stringstream t; if(isXml) { t<<""; for(unsigned i=0;i"; list temp=m[i]; temp.sort(); for(list::const_iterator j=temp.begin();j!=temp.end();j++) { if(j!=temp.begin())t<<' '; t<< *j; } t<<"\n"<\n"; } else { for(unsigned i=0;i temp=m[i]; temp.sort(); for(list::const_iterator j=temp.begin();j!=temp.end();j++) { if(j!=temp.begin())t<<' '; t<< *j; } t<<'}'<::iterator prop=findProperty(p); stringstream s(prop->value); list temp=readIntList(s); ZVector ret(temp.size()); int I=0; for(list::const_iterator i=temp.begin();i!=temp.end();i++,I++)ret[I]=*i; return ret; } void PolymakeFile::writeCardinalVectorProperty(const char *p, ZVector const &v) { stringstream t; if(isXml) { t<<""; for(unsigned i=0;i\n"; } else { for(unsigned i=0;i #include #include "division.h" #include "printer.h" #include "timer.h" #include "linalg.h" #include "wallideal.h" #include "division.h"//used for Polynomial::divides() //static Timer polynomialTimer("Polynomial subtraction",10); //static Timer polynomialTimer1("Polynomial monomial multiplication",1); //----------------------------------------- // Polynomial //----------------------------------------- Polynomial::Polynomial(const Term &t): marked(t), sugar(0), theRing(t.getRing()) { // terms[t.m]=t.c; if(!t.c.isZero()) { terms.insert(std::pair(t.m,t.c)); isMarkedBool=true; } else isMarkedBool=false; } Polynomial::Polynomial(PolynomialRing const &r): theRing(r), sugar(0), marked(r) { isMarkedBool=false; } Polynomial Polynomial::half(bool secondHalf)const { Polynomial ret(theRing); int numberOfTerms=terms.size(); int splitIndex=numberOfTerms/2; int I=0; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++,I++) if((secondHalf)!=(Ifirst.exponent,i->first.exponent))best=i; i++; } marked=Term(best->second,best->first); isMarkedBool=true; } else { TermMap::iterator i=terms.begin(); if(i!=terms.end()) { Term best=Term(i->second,i->first); for(;i!=terms.end();i++) if(termOrder(best.m.exponent,i->first.exponent))best=Term(i->second,i->first); marked=best; } isMarkedBool=true; } } void Polynomial::mark(Monomial const &monomial) { assert(!terms.empty()); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) if(i->first.exponent==monomial.exponent) { marked=Term(i->second,monomial); isMarkedBool=true; return; } fprintf(Stderr,"Monomial "); AsciiPrinter(Stderr).printMonomial(monomial); fprintf(Stderr," not found in "); AsciiPrinter(Stderr).printPolynomial(*this); fprintf(Stderr,"\n"); assert(0); } void Polynomial::copyMarking(Polynomial const &p) { mark(p.marked.m); } bool Polynomial::checkMarking(TermOrder const &termOrder)const { if(!isMarked())return false; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { // if(!termOrder(i->first.exponent,marked.m.exponent))return false; if(termOrder(marked.m.exponent,i->first.exponent))return false; } return true; } bool Polynomial::isHomogeneous(IntegerVector const &v)const { if(isZero())return true; return degree(v)==-degree(-v); } bool Polynomial::isHomogeneous()const { if(isZero())return true; IntegerVector v=IntegerVector::allOnes(theRing.getNumberOfVariables()); return degree(v)==-degree(-v); } void Polynomial::scaleMarkedCoefficientToOne() { assert(isMarked()); FieldElement a=marked.c.inverse(); *this*=a; marked.c=marked.c.one(); } int Polynomial::getNumberOfVariables()const { TermMap::const_iterator i=terms.begin(); if(i==terms.end())return 0; return i->first.exponent.size(); } void Polynomial::changeNumberOfVariables(PolynomialRing const &newRing) { Polynomial q(newRing); for(TermMap::iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; v.resize(newRing.getNumberOfVariables()); FieldElement e=i->second; q+=Term(e,Monomial(newRing,v)); } if(isMarked())marked.m.exponent.resize(newRing.getNumberOfVariables()); terms=q.terms; this->theRing=newRing;//This is bad style } void Polynomial::madd(const Term &m, const Polynomial &p) { if(p.terms.empty())return; //added May 7 2005 int sugar2=p.getSugar()+m.m.exponent.sum(); if(sugar2>sugar)sugar=sugar2; TermMap::iterator i=terms.lower_bound(Monomial(theRing,p.terms.begin()->first.exponent+m.m.exponent)); for(TermMap::const_iterator j=p.terms.begin();j!=p.terms.end();j++) { while(i!=terms.end() && TermMapCompare()(i->first,Monomial(theRing,j->first.exponent+m.m.exponent)))i++; if(i==terms.end()) { terms.insert(i,TermMap::value_type(Monomial(theRing,j->first.exponent+m.m.exponent),j->second*m.c)); } else { if(!TermMapCompare()(Monomial(theRing,j->first.exponent+m.m.exponent),i->first)) { // they must be equal FieldElement c=i->second+j->second*m.c; if(c.isZero()) { TermMap::iterator oldI=i; i++; terms.erase(oldI); } else { i->second=c; } } else { terms.insert(i,TermMap::value_type(Monomial(theRing,j->first.exponent+m.m.exponent),j->second*m.c)); } } } } void Polynomial::operator+=(const Polynomial &p) { if(p.terms.empty())return; //added May 7 2005 if(p.getSugar()>sugar)sugar=p.getSugar(); // fast addition // TimerScope ts(&polynomialTimer); TermMap::iterator i=terms.lower_bound(p.terms.begin()->first); for(TermMap::const_iterator j=p.terms.begin();j!=p.terms.end();j++) { while(i!=terms.end() && (terms.value_comp()(*i,*j)))i++; if(i==terms.end()) { terms.insert(i,TermMap::value_type(j->first,j->second)); } else { if(!terms.value_comp()(*j,*i)) { // they must be equal FieldElement c=i->second+j->second; if(c.isZero()) { TermMap::iterator oldI=i; i++; terms.erase(oldI); } else { i->second=c; } } else { terms.insert(i,TermMap::value_type(j->first,j->second)); } } } // slow addition /* for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { if(terms.count(i->first)==1) { terms[i->first]=terms[i->first]+i->second; if(terms[i->first].isZero())terms.erase(i->first); } else terms[i->first]=i->second; } */ } void Polynomial::operator-=(const Polynomial &p) { if(p.terms.empty())return; //added May 7 2005 if(p.getSugar()>sugar)sugar=p.getSugar(); // fast subtraction //TimerScope ts(&polynomialTimer); TermMap::iterator i=terms.lower_bound(p.terms.begin()->first); for(TermMap::const_iterator j=p.terms.begin();j!=p.terms.end();j++) { while(i!=terms.end() && (terms.value_comp()(*i,*j)))i++; if(i==terms.end()) { terms.insert(i,TermMap::value_type(j->first,-j->second)); } else { if(!terms.value_comp()(*j,*i)) { // they must be equal FieldElement c=i->second-j->second; if(c.isZero()) { // if(i->fist.exponent==marked.exponent)marked=Term); TermMap::iterator oldI=i; i++; terms.erase(oldI); } else { i->second=c; } } else { terms.insert(i,TermMap::value_type(j->first,-j->second)); } } } // slow subtraction /* for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { if(terms.count(i->first)==1) { terms[i->first]=terms[i->first]-i->second; if(terms[i->first].isZero())terms.erase(i->first); } else terms[i->first]=-i->second; } */ } Polynomial operator+(const Polynomial &p, const Polynomial &q) { Polynomial r(p); r+=q; return r; } Polynomial operator-(const Polynomial &p, const Polynomial &q) { Polynomial r(p); r-=q; return r; } void Polynomial::operator*=(const Term &t) { sugar+=t.m.exponent.sum(); #if 0 Polynomial p(theRing); for(TermMap::iterator i=terms.begin();i!=terms.end();i++) { FieldElement prod=i->second; prod*=t.c; p.terms.insert(p.terms.end(),TermMap::value_type(Monomial(theRing,i->first.exponent+t.m.exponent),prod)); } terms=p.terms; #else //This might violate the C++ standard but will work for any sane implementation of STL. for(TermMap::iterator i=terms.begin();i!=terms.end();i++) { (IntegerVector &)(i->first.exponent)+=t.m.exponent; i->second*=t.c; } #endif } void Polynomial::operator*=(const Monomial &m) { sugar+=m.exponent.sum(); #if 0 Polynomial p(theRing); for(TermMap::iterator i=terms.begin();i!=terms.end();i++) { FieldElement prod=i->second; p.terms.insert(p.terms.end(),TermMap::value_type(Monomial(theRing,i->first.exponent+m.exponent),prod)); } terms=p.terms; #else //This might violate the C++ standard but will work for any sane implementation of STL. for(TermMap::iterator i=terms.begin();i!=terms.end();i++)(IntegerVector &)(i->first.exponent)+=m.exponent; #endif } void Polynomial::operator*=(FieldElement const &c) { for(TermMap::iterator i=terms.begin();i!=terms.end();i++) { i->second*=c; } } void Polynomial::operator*=(Polynomial const &p) { Polynomial r(theRing); #if 0 if(terms.size()>p.terms.size()) {Polynomial q=p;q*=*this;*this=q;} else if(isZero()) *this=Polynomial(theRing); else if(terms.size()==1) *this=p*Term(terms.begin()->second,terms.begin()->first); else { Polynomial A=half(true); Polynomial B=half(false); A*=p; B*=p; *this=A+B; } #else if(terms.size()>p.terms.size()) { Polynomial q=p;q*=*this;*this=q; } else { for(TermMap::iterator i=terms.begin();i!=terms.end();i++) { r+=p*Term(i->second,i->first); } *this=r; } #endif } Polynomial operator*(const Polynomial &p, Term const &t) { Polynomial r(p); r*=t; return r; } Polynomial operator*(const Polynomial &p, Monomial const &m) { Polynomial r(p); r*=m; return r; } Polynomial operator*(const Polynomial &p, FieldElement const &c) { Polynomial r(p); r*=c; return r; } Polynomial operator*(const Polynomial &p, const Polynomial &q) { Polynomial r(p); r*=q; return r; } bool Polynomial::divides(const Polynomial &p, Polynomial *result)const { // debug<first.exponent.isZero() && terms.begin()->second.isOne(); } int Polynomial::numberOfTerms()const { return terms.size(); } IntegerVector Polynomial::exponentsSum()const { IntegerVector sum(numberOfVariablesInRing()); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) sum+=i->first.exponent; return sum; } IntegerVectorList Polynomial::exponents()const { IntegerVectorList ret; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) ret.push_back(i->first.exponent); return ret; } IntegerVector Polynomial::greatestCommonMonomialDivisor()const { assert(!isZero()); IntegerVector ret=terms.begin()->first.exponent; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) ret=min(ret,i->first.exponent); return ret; } IntegerVector Polynomial::degreeVector()const { IntegerVector ret(this->getRing().getNumberOfVariables()); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) ret=max(ret,i->first.exponent); return ret; } bool Polynomial::isMonomial()const { return terms.size()==1;//could it be faster to compare begin and end iterators? } int Polynomial::totalDegree()const { int d=-1; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) if(i->first.exponent.sum()>d)d=i->first.exponent.sum(); return d; } int64 Polynomial::degree(IntegerVector const &w)const { bool first=true; int64 d=0; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { if(first||dotLong(i->first.exponent,w)>d)d=dotLong(i->first.exponent,w); first=false; } assert(!first); return d; } Polynomial Polynomial::homogenization(PolynomialRing const &newRing, IntegerVector const *w)const //does not compute sugar { int degree; Polynomial ret(newRing); if(w) degree=this->degree(*w); else degree=totalDegree(); IntegerVector m; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; int d; if(w) d=dot(v,*w); else d=v.sum(); IntegerVector a(v.size()); a.grow(a.size()+1); v.grow(v.size()+1); a[a.size()-1]=degree-d; v+=a; ret+=Term(i->second,Monomial(newRing,v)); if(isMarked())if(marked.m.exponent==i->first.exponent)m=v; } if(isMarked()) { IntegerVector v=m; /* if(m.size()+1==newRing.getNumberOfVariables()) { v.grow(m.size()+1); v[m.size()]=degree-v.sum(); ret.mark(Monomial(newRing,v)); }*/ if(m.size()==newRing.getNumberOfVariables()) { ret.mark(Monomial(newRing,v)); } // assert(m.size()==newRing.getNumberOfVariables()); // ret.mark(Monomial(newRing,m)); assert(ret.isMarked()); } return ret; } Polynomial Polynomial::torusAct(FieldVector const &w)const { Polynomial ret=*this; int n=theRing.getNumberOfVariables(); assert(w.size()==n); for(TermMap::iterator i=ret.terms.begin();i!=ret.terms.end();i++) { FieldElement c=theRing.getField().zHomomorphism(1); for(int j=0;jfirst.exponent[j];k++) c*=w[j]; i->second=i->second*c; } if(isMarked()) { ret.mark(marked.m); } return ret; } /*Polynomial Polynomial::derivative()const { Polynomial ret(theRing); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; assert(v.size()==1); if(v[0]!=0) { v[0]--; ret+=Term(i->second*theRing.getField().zHomomorphism(v[0]+1),Monomial(theRing,v)); } } return ret; }*/ Polynomial Polynomial::derivative(int j)const { Polynomial ret(theRing); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; if(v[j]!=0) { v[j]--; ret+=Term(i->second*theRing.getField().zHomomorphism(v[j]+1),Monomial(theRing,v)); } } return ret; } Polynomial Polynomial::deHomogenization(PolynomialRing const &r)const { Polynomial ret=*this; int n=numberOfVariablesInRing(); assert(n>0); ret.changeNumberOfVariables(r); return ret; } Polynomial Polynomial::deHomogenizationInSameRing()const { Polynomial ret(getRing()); int n=getRing().getNumberOfVariables(); assert(n>0); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; v[n-1]=0; FieldElement e=i->second; ret+=Term(e,Monomial(theRing,v)); } if(isMarked()) { ret.marked.m.exponent=marked.m.exponent.subvector(0,n-1); ret.isMarkedBool=true; } return ret; } int Polynomial::numberOfVariablesInRing()const { return theRing.getNumberOfVariables(); // assert(terms.size()!=0); // return terms.begin()->first.exponent.size(); } void Polynomial::saturate(int variableNum)//does not compute sugar { // Should use greatestCommonMonomialDivisor() and operator* instead. if(!terms.empty()) { IntegerVector smallest=terms.begin()->first.exponent; for(TermMap::iterator i=terms.begin();i!=terms.end();i++) smallest=min(smallest,i->first.exponent); if(variableNum!=-1) { for(int j=0;jfirst.exponent-smallest),i->second)); terms=p.terms; //for(TermMap::iterator i=terms.begin();i!=terms.end();i++)i->first.exponent-=smallest; Would be faster but does not compile if(isMarked()) { marked.m.exponent-=smallest; } } } } void Polynomial::computeInitialSugar() { sugar=totalDegree(); } int Polynomial::getSugar()const { return sugar; } bool Polynomial::isMarked()const { return isMarkedBool; // return marked.m.exponent.size()!=0; } bool Polynomial::isValid(int numberOfVariables)const { if(!terms.empty()) { if(numberOfVariables==-1)numberOfVariables=numberOfVariablesInRing(); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { if(i->first.exponent.size()!=numberOfVariables) { fprintf(Stderr,"Polynomial::isValid failed!!!!\n"); return false; } } if(isMarked()) { assert(marked.m.exponent.size()==numberOfVariables); } } return true; } FieldElement Polynomial::evaluate(const FieldElement &x)const { FieldElement r=x-x; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; assert(v.size()==1); FieldElement s=theRing.getField().zHomomorphism(1); for(int j=0;jsecond*s; } return r; } int Polynomial::maximalIndexOfVariableInSupport()const { int ret=-1; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; for(int j=ret+1;jfirst.exponent.supportAsZeroOneVector()); } return ret; } Polynomial Polynomial::embeddedInto(PolynomialRing const &r2, list const *chosenVariables)const { Polynomial q(r2); if(chosenVariables) { assert(chosenVariables->size()==r2.getNumberOfVariables()); } for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; if(chosenVariables) v=v.subvector(*chosenVariables); else v.resize(r2.getNumberOfVariables()); FieldElement e=i->second; q+=Term(e,Monomial(r2,v)); } if(isMarked()) { IntegerVector m=marked.m.exponent; //AsciiPrinter(Stderr)<<*this<<"\n"; if(chosenVariables) m=m.subvector(*chosenVariables); else m.resize(r2.getNumberOfVariables()); q.mark(Monomial(r2,m)); } // q.marked.m.exponent.resize(r2.getNumberOfVariables()); return q; } Polynomial Polynomial::embeddedInto2(PolynomialRing const &r2, vector const &positionOfVariables)const { Polynomial q(r2); assert(positionOfVariables.size()==getRing().getNumberOfVariables()); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector v=i->first.exponent; v=v.expanded(r2.getNumberOfVariables(),positionOfVariables); FieldElement e=i->second; q+=Term(e,Monomial(r2,v)); } if(isMarked()) { IntegerVector m=marked.m.exponent; m=m.expanded(r2.getNumberOfVariables(),positionOfVariables); q.mark(Monomial(r2,m)); } return q; } Polynomial Polynomial::withRestrictedVariables(IntegerVector const &keepVariable, PolynomialRing const &r2)const { assert(theRing.getNumberOfVariables()==keepVariable.size()); assert(r2.getNumberOfVariables()==keepVariable.sum()); Polynomial q(r2); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) q+=Term(i->second,Monomial(r2,i->first.exponent.subvectorSubsetBoolean(keepVariable))) ; return q; } Polynomial Polynomial::withExpandedVariables(IntegerVector const &wasKeptVariables, PolynomialRing const &r1)const { assert(theRing.getNumberOfVariables()==wasKeptVariables.sum()); assert(r1.getNumberOfVariables()==wasKeptVariables.size()); Polynomial q(r1); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) q+=Term(i->second,Monomial(r1,i->first.exponent.expandedBoolean(wasKeptVariables))); return q; } int Polynomial::numberOfVariablesInUseConsecutive()const { int ret=0; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { int a=i->first.exponent.indexOfLargestNonzeroEntry()+1; if(a>ret)ret=a; } return ret; } string Polynomial::toString(bool latex/*, bool mathMode*/)const { stringstream s; /* if(latex && !mathMode) s << "$"; */ bool first=true; if(terms.empty()) { s << "0"; return s.str(); } // If the polynomial has a marked term it is written first // printString("_"); IntegerVector e=getMarked().m.exponent; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) if(e==i->first.exponent) { s << i->second.toString(i->first.exponent.isZero(),!first,latex); if((!i->first.exponent.isZero())&&(!i->second.isOne())&&(!(-(i->second)).isOne()))s<<"*"; s << i->first.toString(false,false,latex); first=false; } // printString("_"); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) if(e!=i->first.exponent) { s << i->second.toString(i->first.exponent.isZero(),!first,latex); if((!i->first.exponent.isZero())&&(!i->second.isOne())&&(!(-(i->second)).isOne()))s<<"*"; s << i->first.toString(false,false,latex); /* printFieldElement(i->second,i->first.exponent.isZero(),!first); if((!i->first.exponent.isZero())&&(!i->second.isOne())&&(!(-(i->second)).isOne()))printString("*"); printMonomial(i->first,false,false);*/ first=false; } /* if(latex && !mathMode) s << "$"; */ return s.str(); } bool Polynomial::checkExponentVectors()const { int n=getRing().getNumberOfVariables(); for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) if(i->first.exponent.v.size()!=n) { // log1 { // AsciiPrinter(Stderr)<<"Exponent vector length does not match ring\n"<<*this; assert(0); } return false; } return true; } double Polynomial::evaluateFloat(FloatVector const &x)const { int n=getRing().getNumberOfVariables(); assert(x.size()==n); double ret=0; for(TermMap::const_iterator i=terms.begin();i!=terms.end();i++) { IntegerVector const v=i->first.exponent; double m=i->second.floatingPointApproximation(); for(int i=0;ifirst.exponent; ComplexNumber m=i->second.floatingPointApproximation(); for(int i=0;isecond,Monomial(r2,j->first.exponent.withIthCoordinateRemoved(i))); for(int k=0;kfirst.exponent[i];k++) temp*=Term(v,Monomial(r2)); ret+=temp; } return ret; } Polynomial Polynomial::modularRepresentative(PolynomialRing const &r2)const { Polynomial ret(r2); for(TermMap::const_iterator j=terms.begin();j!=terms.end();j++) { ret+=Term(j->second.modularRepresentative(r2.getField()),Monomial(r2,j->first.exponent)); } return ret; } Polynomial Polynomial::integralRepresentative(PolynomialRing const &r2)const { Polynomial ret(r2); for(TermMap::const_iterator j=terms.begin();j!=terms.end();j++) { ret+=Term(r2.getField().zHomomorphism(j->second.getIntegerRepresentation()),Monomial(r2,j->first.exponent)); } return ret; } bool Polynomial::operator==(Polynomial const &q)const { return !PolynomialCompare()(*this,q) && !PolynomialCompare()(*this,q); } //----------------------------------------- // PolynomialSet //----------------------------------------- void PolynomialSet::saturate(int variableNum) { for(iterator i=begin();i!=end();i++) i->saturate(variableNum); } PolynomialSet PolynomialSet::polynomialRingIntersection(PolynomialRing const &newRing, list const *chosenVariables)const { PolynomialSet ret(newRing); if(chosenVariables==0) { for(PolynomialSet::const_iterator i=begin();i!=end();i++) if(i->maximalIndexOfVariableInSupport()embeddedInto(newRing)); } } else { int n=theRing.getNumberOfVariables(); IntegerVector allowedVariables(n); for(list::const_iterator i=chosenVariables->begin();i!=chosenVariables->end();i++)allowedVariables[*i]=1; for(PolynomialSet::const_iterator i=begin();i!=end();i++) { if(i->usedVariables().divides(allowedVariables)) { ret.push_back(i->embeddedInto(newRing,chosenVariables)); } } } return ret; } void PolynomialSet::changeNumberOfVariables(PolynomialRing const &r2) { /* int numberOfVariables=0; if(n==-1) { for(PolynomialSet::const_iterator i=begin();i!=end();i++) { if(i->getNumberOfVariables()>numberOfVariables)numberOfVariables=i->getNumberOfVariables(); } } else { numberOfVariables=n; } // fprintf(Stderr,"numberOFva%i\n",numberOfVariables); for(iterator i=begin();i!=end();i++) { i->changeNumberOfVariables(numberOfVariables); } */ for(iterator i=begin();i!=end();i++) { i->changeNumberOfVariables(r2); } this->theRing=r2;//bad style } void PolynomialSet::mark(class TermOrder const &termOrder) { for(iterator i=begin();i!=end();i++) i->mark(termOrder); } void PolynomialSet::markAndScale(TermOrder const &termOrder) { mark(termOrder); scaleMarkedCoefficientsToOne(); } void PolynomialSet::copyMarkings(PolynomialSet const &g) { PolynomialSet::const_iterator j=g.begin(); for(PolynomialSet::iterator i=begin();i!=end();i++,j++) i->copyMarking(*j); } void PolynomialSet::scaleMarkedCoefficientsToOne() { for(iterator i=begin();i!=end();i++) i->scaleMarkedCoefficientToOne(); } bool PolynomialSet::checkMarkings(TermOrder const &termOrder)const { for(const_iterator i=begin();i!=end();i++) if(!i->checkMarking(termOrder))return false; return true; } bool PolynomialSet::containsInClosedGroebnerCone(IntegerVector const &v)const { for(const_iterator i=begin();i!=end();i++) { if(i->degree(v)>dotLong(v,i->getMarked().m.exponent))return false; } return true; } bool PolynomialSet::isHomogeneous(IntegerVector const &v)const { for(const_iterator i=begin();i!=end();i++) { if(!i->isHomogeneous(v))return false; } return true; } bool PolynomialSet::isHomogeneous()const { IntegerVector v=IntegerVector::allOnes(theRing.getNumberOfVariables()); return isHomogeneous(v); } void PolynomialSet::unionPolynomial(const Polynomial &p) { const_iterator j; for(j=begin();j!=end();j++) if((p-*j).isZero())break; if(j==end())push_back(p); } void PolynomialSet::unionSet(const PolynomialSet &s) { for(const_iterator i=s.begin();i!=s.end();i++) unionPolynomial(*i); } bool PolynomialCompare::operator()(const Polynomial &a, const Polynomial &b)const { if(a.terms.size()first.exponent,j->first.exponent))return true; if(LexicographicTermOrder()(j->first.exponent,i->first.exponent))return false; } if((a-b).isZero())return false; if((a+b).isZero())return false; // we need some way of comparing field elements /* AsciiPrinter(Stderr).printPolynomial(a); fprintf(Stderr,"\n"); AsciiPrinter(Stderr).printPolynomial(b); */ i=a.terms.begin(); for(TermMap::const_iterator j=b.terms.begin();j!=b.terms.end();j++,i++) { int s=(i->second - j->second).sign();//TODO: Make this work for fields which are not ordered if(s==1)return false; if(s==-1)return true; } // assert("Polynomial compare must be improved to handle this case"==0); return false; } PolynomialCompareMarkedTerms::PolynomialCompareMarkedTerms(TermOrder const &termOrder_): termOrder(termOrder_) { } bool PolynomialCompareMarkedTerms::operator()(const Polynomial &a, const Polynomial &b)const { return termOrder(a.getMarked().m.exponent,b.getMarked().m.exponent); } PolynomialCompareMarkedTermsReverse::PolynomialCompareMarkedTermsReverse(TermOrder const &termOrder_): termOrder(termOrder_) { } bool PolynomialCompareMarkedTermsReverse::operator()(const Polynomial &a, const Polynomial &b)const { return termOrder(b.getMarked().m.exponent,a.getMarked().m.exponent); } bool PolynomialCompareNumberOfTermsStable::operator()(const Polynomial &a, const Polynomial &b)const { return a.numberOfTerms()totalDegree())d=i->totalDegree(); return d; } void PolynomialSet::sort_() { sort(PolynomialCompare()); } void PolynomialSet::simplestPolynomialsFirst() { sort(PolynomialCompareNumberOfTermsStable()); } int PolynomialSet::numberOfVariablesInRing()const { return theRing.getNumberOfVariables(); // assert(size()!=0); // return begin()->numberOfVariablesInRing(); } bool operator==(PolynomialSet const &a, PolynomialSet const &b) { return b.isEqualTo(a); } bool PolynomialSet::isEqualTo(PolynomialSet const &a)const { if(a.size()!=size())return false; PolynomialSet::const_iterator j=begin(); for(PolynomialSet::const_iterator i=a.begin();i!=a.end();i++) { if(!(*i-*j).isZero())return false; j++; } return true; } bool PolynomialSet::isUnitIdeal()const { return division(theRing.one(),*this,StandardGradedLexicographicTermOrder()).isZero(); } IntegerVector PolynomialSet::exponentsSum()const { IntegerVector sum(numberOfVariablesInRing()); for(const_iterator i=begin();i!=end();i++) sum+=i->exponentsSum(); return sum; } PolynomialSet PolynomialSet::markedTermIdeal()const { PolynomialSet LT(theRing); for(const_iterator i=begin();i!=end();i++) { LT.push_back(Polynomial(i->getMarked())); } return LT; } void PolynomialSet::computeInitialSugar() { for(iterator i=begin();i!=end();i++) i->computeInitialSugar(); } bool PolynomialSet::isMarked()const { for(const_iterator i=begin();i!=end();i++) if(!i->isMarked())return false; return true; } PolynomialSet PolynomialSet::torusAct(FieldVector const &w)const { PolynomialSet ret(theRing); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->torusAct(w)); return ret; } PolynomialSet PolynomialSet::homogenization(PolynomialRing const &newRing, IntegerVector const *w)const { PolynomialSet ret(newRing); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->homogenization(newRing,w)); return ret; } list PolynomialSet::multiDeHomogenizationToKeep()const { int n=getRing().getNumberOfVariables(); FieldMatrix m=integerMatrixToFieldMatrix(rowsToIntegerMatrix(wallInequalities(*this),n),Q); m.reduce(); return m.pivotColumns(); } PolynomialSet PolynomialSet::multiDeHomogenization()const { int n=getRing().getNumberOfVariables(); list toKeep=multiDeHomogenizationToKeep(); PolynomialRing R2=PolynomialRing(getRing().getField(),toKeep.size()); return embeddedInto(R2,&toKeep); } PolynomialSet PolynomialSet::deHomogenization()const { PolynomialSet ret(PolynomialRing(theRing.getField(),theRing.getNumberOfVariables()-1)); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->deHomogenization(ret.getRing())); return ret; } PolynomialSet PolynomialSet::deHomogenizationInSameRing()const { PolynomialSet ret(theRing); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->deHomogenizationInSameRing()); return ret; } bool PolynomialSet::isValid()const { if(size()!=0) { int n=numberOfVariablesInRing(); for(const_iterator i=begin();i!=end();i++) if(!i->isValid(n))return false; } return true; } PolynomialSet PolynomialSet::embeddedInto(PolynomialRing const &r2, list const *chosenVariables)const { PolynomialSet ret(r2); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->embeddedInto(r2,chosenVariables)); return ret; } PolynomialSet PolynomialSet::embeddedInto2(PolynomialRing const &r2, vector const &positionsOfVariables)const { PolynomialSet ret(r2); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->embeddedInto2(r2,positionsOfVariables)); return ret; } PolynomialSet PolynomialSet::withRestrictedVariables(IntegerVector const &keepVariable, PolynomialRing const &r2)const { assert(theRing.getNumberOfVariables()==keepVariable.size()); assert(r2.getNumberOfVariables()==keepVariable.sum()); PolynomialSet ret(r2); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->withRestrictedVariables(keepVariable,r2)); return ret; } PolynomialSet PolynomialSet::withExpandedVariables(IntegerVector const &wasKeptVariables, PolynomialRing const &r1)const { assert(theRing.getNumberOfVariables()==wasKeptVariables.sum()); assert(r1.getNumberOfVariables()==wasKeptVariables.size()); PolynomialSet ret(r1); for(const_iterator i=begin();i!=end();i++) ret.push_back(i->withExpandedVariables(wasKeptVariables,r1)); return ret; } int PolynomialSet::numberOfVariablesInUseConsecutive()const { int ret=0; for(const_iterator i=begin();i!=end();i++) { int a=i->numberOfVariablesInUseConsecutive(); if(a>ret)ret=a; } return ret; } int PolynomialSet::totalNumberOfTerms()const { int ret=0; for(const_iterator i=begin();i!=end();i++) ret+=i->numberOfTerms(); return ret; } list PolynomialSet::exponents()const { list ret; for(const_iterator i=begin();i!=end();i++)ret.push_back(i->exponents()); return ret; } FloatVector PolynomialSet::evaluateFloat(FloatVector const &x)const { assert(x.size()==numberOfVariablesInRing()); FloatVector ret(size()); int I=0; for(const_iterator i=begin();i!=end();i++,I++) ret[I]=i->evaluateFloat(x); return ret; } ComplexVector PolynomialSet::evaluateComplex(ComplexVector const &x)const { assert(x.size()==numberOfVariablesInRing()); ComplexVector ret(size()); int I=0; for(const_iterator i=begin();i!=end();i++,I++) ret[I]=i->evaluateComplex(x); return ret; } PolynomialSet PolynomialSet::withIthVariableSubstituted(PolynomialRing const &r2, int i, FieldElement const &v)const { PolynomialSet ret(r2); for(const_iterator j=begin();j!=end();j++) ret.push_back(j->withIthVariableSubstituted(r2,i,v)); return ret; } void PolynomialSet::removeZeros() { for(PolynomialSet::iterator i=begin();i!=end();i++) { if(i->isZero()) { PolynomialSet::iterator j=i; j++; erase(i); j--; i=j; } } } void PolynomialSet::removeDuplicates() { sort_(); unique(); } PolynomialSet PolynomialSet::modularRepresentative(PolynomialRing const &r2)const { PolynomialSet ret(r2); for(PolynomialSet::const_iterator i=begin();i!=end();i++) ret.push_back(i->modularRepresentative(r2)); return ret; } gfan0.6.2/src/app_exponentlattice.cpp0000644000175000017500000000210413122232611017216 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "wallideal.h" #include "termorder.h" #include "gfanapplication.h" #include "matrix.h" #include "linalg.h" class ExponentLatticeApplication : public GFanApplication { public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program computes a list of generators for the lattice generated by the exponent differences of monomials of the same polynomial in the input list of polynomials.\n"; } ExponentLatticeApplication() { registerOptions(); } const char *name() { return "_exponentlattice"; } int main() { FileParser P(Stdin); PolynomialSet g=P.parsePolynomialSetWithRing(); int n=g.getRing().getNumberOfVariables(); IntegerVectorList l=exponentDifferences(g); FieldMatrix L=integerMatrixToFieldMatrix(rowsToIntegerMatrix(l,n),Q); L.reduce(false,true); L.removeZeroRows(); pout<begin(); for(PolynomialSet::iterator k=g.begin();k!=g.end();k++) { k->mark(Monomial(theRing,*j)); j++; } IntegerVectorList normals=wallInequalities(g); if(hasInteriorPoint(normals,true)) { if(isMarkedGroebnerBasis(g)) { AsciiPrinter(Stderr).printPolynomialSet(g); isGroebnerBasis=true; if(!optionUGBTest.getValue())break; } else { fprintf(Stderr,"Marking is not a Groebner basis\n"); if(optionUGBTest.getValue()) { AsciiPrinter(Stderr).printPolynomialSet(g); assert(0); } } } else fprintf(Stderr,"Cone has no positive interior point\n"); } fprintf(Stdout,isGroebnerBasis?"true\n":"false\n"); return 0; } }; static IsGroebnerBasisApplication theApplication; gfan0.6.2/src/app_saturation.cpp0000644000175000017500000000242113122232611016203 0ustar andersanders#include "parser.h" #include "printer.h" #include "saturation.h" #include "tropical.h" #include "gfanapplication.h" class SaturationApplication : public GFanApplication { SimpleOption optionIsHomogeneous; SimpleOption optionNoIdeal; public: const char *helpText() { return "This program computes the saturation of the input ideal with the product of the variables x_1,...,x_n. The ideal does not have to be homogeneous.\n"; } SaturationApplication(): optionIsHomogeneous("-h","Tell the program that the input is a homogeneous ideal (with homogeneous generators).\n"), optionNoIdeal("--noideal","Do not treat input as an ideal but just factor out common monomial factors of the input polynomials.") { registerOptions(); } const char *name() { return "_saturation"; } int main() { FileParser P(Stdin); PolynomialSet a=P.parsePolynomialSetWithRing(); AsciiPrinter(Stdout).printPolynomialRing(a.getRing()); AsciiPrinter(Stdout).printNewLine(); if(optionNoIdeal.getValue()) { a.saturate(); pout< #include #define OLD 1 #if OLD #include "gmp.h" namespace gfan{ class Rational; class Integer { friend class Rational; mpz_t value; public: static bool isField() { return false; } Integer() { mpz_init(value); } Integer(signed long int value_) { mpz_init(value); mpz_set_si(value,value_); } Integer(Integer const & value_) { mpz_init_set(value,value_.value); } Integer(mpz_t const value_) { mpz_init_set(value,value_); } ~Integer() { mpz_clear(value); } Integer& operator=(const Integer& a) { const Integer *A=(const Integer*)&a; if (this != A) { mpz_clear(value); mpz_init_set(value, a.value); } return *this; } bool isZero()const{ return mpz_sgn(value)==0; } friend std::ostream &operator<<(std::ostream &f, Integer const &a) { void (*freefunc)(void *, size_t); mp_get_memory_functions(0,0,&freefunc); char *str=mpz_get_str(0,10,a.value); f<setGmp(v); bool ret=(mpz_fits_sint_p(v)!=0); mpz_clear(v); return ret; } int toInt()const { mpz_t v; mpz_init(v); this->setGmp(v); int ret=0; if(mpz_fits_sint_p(v)) ret=mpz_get_si(v); // else // ok=false; mpz_clear(v); return ret; } }; } #else namespace gfan{ typedef signed long int word;//processor type for integers typedef int64_t LimbWord;//memory word. Assumed to be at least as big as word typedef uint64_t uLimbWord;//memory word. Assumed to be at least as big as word const int limbSizeInBytes=8; #include struct spec64malloc{ int64_t data; bool hasLimbs() { return data&1; } word fitsMask() { return 0xc000000000000000; } void assign(word value)//assuming data fits { data=value<<1; } void alloc(int nlimbs)//one limb is added since that will tell the number of remaining limbs { int64_t temp=(int64_t)malloc((nlimbs+1)*limbSizeInBytes); assert(temp); data=temp+1; } LimbWord *limbs()//assuming that limbs exist { return (LimbWord*)(data-1); } word nlimbs()//assuming limbs exist { return (word)*limbs(); } void copy(spec64malloc b) { if(hasLimbs()) { word n2=b.nlimbs()+1; int64_t temp=(int64_t)malloc((n2)*limbSizeInBytes); assert(temp); data=temp+1; memcpy((LimbWord*)temp,limbs(),n2*limbSizeInBytes); } else { data=b.data; } } void doFree()//assuming that limbs exist { free((void*)(data-1)); } word valueToWord()//assume no limbs and that word is big enough to contain int64_t { return data>>1; } }; template struct IntegerTemplate : public spec { private: bool fits(word v) { return !((value_&fitsMask())^((value_<<1)&fitsMask)); } public: static bool isField() { return false; } IntegerTemplate() { spec.data=0; } void assignWordNoFree() { if(fits(value_)) { assign(value); } else { alloc(1); limbs()[0]=1; limbs()[1]=value_; } } IntegerTemplate(word value_) { assignWordNoFree(value_); } IntegerTemplate(IntegerTemplate const & value_) { if(value_.hasLimbs()) { copy(value_); } else data=value.data; } /* Integer(mpz_t value_) { mpz_init_set(value,value_); }*/ ~IntegerTemplate() { if(hasLimbs())doFree(); } IntegerTemplate& operator=(const IntegerTemplate& a) { if(this!=&a) { if(hasLimps())doFree(); copy(a); } return *this; } bool isZero()const{ return data==0; } friend std::ostream &operator<<(std::ostream &f, IntegerTemplate const &a) { if(hasLimps()) { LimpWord *p=limbs(); int l=*p++; for(int i=0;i Integer; }; #endif #endif /* LIB_Z_H_ */ gfan0.6.2/src/singular.h0000644000175000017500000000027013122232611014443 0ustar andersanders#ifndef SINGULAR_H_INCLUDED #define SINGULAR_H_INCLUDED #include "polynomial.h" #include "termorder.h" void singularBuchberger(PolynomialSet *g, TermOrder const &termOrder); #endif gfan0.6.2/src/gfanlib_matrix.h0000644000175000017500000005470113122232611015615 0ustar andersanders/* * lib_zmatrix.h * * Created on: Sep 28, 2010 * Author: anders */ #ifndef LIB_ZMATRIX_H_ #define LIB_ZMATRIX_H_ #include #include #include "gfanlib_vector.h" namespace gfan{ template class Matrix{ int width,height; // std::vector > rows; std::vector data; public: // rowIterator; // std::vector >::iterator rowsBegin(){return rows.begin();} // std::vector >::iterator rowsEnd(){return rows.end();} inline int getHeight()const{return height;}; inline int getWidth()const{return width;}; Matrix(const Matrix &a):width(a.getWidth()),height(a.getHeight()),data(a.data){ } Matrix(int height_, int width_):width(width_),height(height_),data(width_*height_){ assert(height>=0); assert(width>=0); }; ~Matrix(){ }; Matrix():width(0),height(0){ }; static Matrix rowVectorMatrix(Vector const &v) { Matrix ret(1,v.size()); for(int i=0;i column(int i)const { assert(i>=0); assert(i ret(getHeight()); for(int j=0;j const &v) { assert(v.size()==width); data.resize((height+1)*width); height++; for(int j=0;j0); data.resize((height-1)*width); height--; } /*IntegerVector vectormultiply(IntegerVector const &v)const { assert(v.size()==width); IntegerVector ret(height); for(int i=0;i Matrix(const Matrix& c):v(c.size()){ for(int i=0;i=0); assert(startColumn>=0); assert(endRow>=startRow); assert(endColumn>=startColumn); assert(endRow<=height); assert(endColumn<=width); Matrix ret(endRow-startRow,endColumn-startColumn); for(int i=startRow;i=0); assert(j toVector()const { Vector ret(matrix.width); for(int j=0;j()const { return toVector(); } bool operator==(Vector const &b)const { return toVector()==b; } /* typ dot(Vector const &b)const { return dot(toVector(),b); }*/ Vector operator-()const { return -toVector(); } }; class RowRef{ int rowNumM; Matrix &matrix; public: inline RowRef(Matrix &matrix_, int rowNum_): rowNumM(rowNum_*matrix_.width), matrix(matrix_) { } inline typ &operator[](int j) __attribute__((always_inline)) { assert(j>=0); assert(j const &v) { assert(v.size()==matrix.width); for(int j=0;j const &v) { assert(v.size()==matrix.width); for(int j=0;j toVector()const { Vector ret(matrix.width); for(int j=0;j()const { return toVector(); } /* typ dot(Vector const &b)const { return dot(toVector(),b); }*/ bool isZero()const { for(int j=0;j=0); assert(i=0); assert(i=0); assert(i=0); assert(j=0); assert(i=0); assert(j=0 && i=0 && j=height)return false; while(++j pivotColumns()const { std::vector ret; int pivotI=-1; int pivotJ=-1; while(nextPivot(pivotI,pivotJ))ret.push_back(pivotJ); return ret; } /** Returns the indices of the columns not containing a pivot. The returned list is sorted. The matrix must be in row echelon form. */ std::vector nonPivotColumns()const { std::vector ret; int pivotI=-1; int pivotJ=-1; int firstPossiblePivot=0; while(nextPivot(pivotI,pivotJ)) { for(int j=firstPossiblePivot;j=0)retSwaps++; typ inverse=typ(1)/(*this)[currentRow][i]; // if(!rows[currentRow][i].isOne()) { for(int k=0;kzHomomorphism(-(((int)(d+10000.5))-10000)); s.madd(multiplier,u); t.madd(multiplier,v); }*/ for(int k=0;k canonicalize(Vector v)const { assert(typ::isField()); assert((int)v.size()==getWidth()); int pivotI=-1; int pivotJ=-1; while(nextPivot(pivotI,pivotJ)) if(!v[pivotJ].isZero()) { typ s=-v[pivotJ]/(*this)[pivotI][pivotJ]; for(int k=0;k reduceAndComputeVectorInKernel() { assert(typ::isField()); // TODO: (optimization) if the field is ordered, then it is better to just keep track of signs rather than // multiplying by sign*diagonalProduct*lastEntry at the end. int nswaps=this->reduce(); typ sign=typ(1-2*(nswaps&1)); int rank=reduceAndComputeRank(); assert(rank+1==width); REformToRREform(); Vector ret(width); typ diagonalProduct(1); { int pivot2I=-1; int pivot2J=-1; while(nextPivot(pivot2I,pivot2J)) { diagonalProduct*=(*this)[pivot2I][pivot2J]; } } { int j=nonPivotColumns().front(); int pivot2I=-1; int pivot2J=-1; ret[j]=typ(-1); // Pretend that we are appending ret to the matrix, and reducing this // new row by the previous ones. The last entry of the resulting matrix // is lastEntry. typ lastEntry=ret[j]; while(nextPivot(pivot2I,pivot2J)) { ret[pivot2J]=(*this)[pivot2I][j]/(*this)[pivot2I][pivot2J]; lastEntry-=ret[pivot2J]*ret[pivot2J]; } ret=(sign*(diagonalProduct*lastEntry))*ret; } return ret; } /** Calls reduce() and returns the rank of the matrix. */ int reduceAndComputeRank() { reduce(false,!typ::isField(),false); int ret=0; int pivotI=-1; int pivotJ=-1; while(nextPivot(pivotI,pivotJ))ret++; return ret; } /** * Sort the rows of the matrix. */ struct rowComparer{ bool operator()(std::pair i, std::pair j) {return ((*i.first)[i.second].toVector()<(*j.first)[j.second].toVector());} } theRowComparer; void sortRows() { std::vector > v; for(int i=0;i(this,i)); std::sort(v.begin(),v.end(),theRowComparer); Matrix result(height,width); for(int i=0;i ZMatrix; typedef Matrix QMatrix; typedef Matrix IntMatrix; inline QMatrix ZToQMatrix(ZMatrix const &m) { QMatrix ret(m.getHeight(),m.getWidth()); for(int i=0;ib>c...$ (assuming that the ring is Q[a,b,c,...]).\n"; } BuchbergerApplication(): optionReadWeightVector("-w","Compute a Groebner basis with respect to a degree lexicographic order with $a>b>c...$ instead. The degrees are given by a weight vector which is read from the input after the generating set has been read.\n"), optionReverse("-r","Use the reverse lexicographic order (or the reverse lexicographic order as a tie breaker if -w is used). The input must be homogeneous if the pure reverse lexicographic order is chosen. Ignored if -W is used.\n"), optionWalk("-W","Do a Groebner walk. The input must be a minimal Groebner basis. If -W is used -w is ignored.\n"), optionGenericWalk("-g","Do a generic Groebner walk. The input must be homogeneous and must be a minimal Groebner basis with respect to the reverse lexicographic term order. The target term order is always lexicographic. The -W option must be used.\n"), optionParameters("--parameters","With this option you can specify how many variables to treat as parameters instead of variables. This makes it possible to do computations where the coefficient field is the field of rational functions in the parameters.",0) { registerOptions(); } const char *name() { return "_buchberger"; } int main() { TermOrder *myOrder; PolynomialSet g=FileParser(Stdin).parsePolynomialSetWithRing(); if(optionParameters.getValue())g=makeVariablesParameters(makeVariablesParameters(g.getRing(),optionParameters.getValue()),g); if(optionReadWeightVector.getValue()) { IntegerVector w=FileParser(Stdin).parseIntegerVector(); if(optionReverse.getValue()) myOrder = new WeightReverseLexicographicTermOrder(w); else myOrder = new WeightTermOrder(w); } else if(optionReverse.getValue()) myOrder = new ReverseLexicographicTermOrder; else myOrder = new LexicographicTermOrder; if(optionWalk.getValue()) { g.scaleMarkedCoefficientsToOne(); log1 fprintf(Stderr,"Auto-reducing input...\n"); autoReduce(&g,LexicographicTermOrder()); log1 fprintf(Stderr,"Walking...\n"); if(optionGenericWalk.getValue()) { g=genericWalk(g, ReverseLexicographicTermOrder(), LexicographicTermOrder()); } else { g=ReverseSearch(LexicographicTermOrder()).findRoot(g); } } else { //fprintf(Stderr,"TESTING Singular interface\n"); //singularBuchberger(&g,*myOrder); buchberger(&g,*myOrder); // AsciiPrinter(Stderr).printPolynomialSet(g); // fprintf(Stderr,"\n\n\n"); g.scaleMarkedCoefficientsToOne();// buchberger(&g,*myOrder); autoReduce(&g,LexicographicTermOrder()); } AsciiPrinter(Stdout).printPolynomialRing(g.getRing()); printf("\n"); AsciiPrinter(Stdout).printPolynomialSet(g); log1 Timer::printList(); return 0; } }; static BuchbergerApplication theApplication; gfan0.6.2/src/log.cpp0000644000175000017500000000011313122232611013727 0ustar andersanders#include "log.h" int logLevel; void setLogLevel(int l) { logLevel=l; } gfan0.6.2/src/app_smalessixth.cpp0000644000175000017500000005076313122232611016372 0ustar andersanders#include #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "lp.h" #include "gfanapplication.h" #include "polyhedralcone.h" #include "tropical2.h" #include "nbody.h" #include "polymakefile.h" #include "determinant.h" #include "subspace.h" #include "triangulation.h" #include "groebnerengine.h" class SmalesSixthApplication : public GFanApplication { StringOption inputOption; SimpleOption singleOption; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program solves ........\n"; } SmalesSixthApplication(): // inputOption("-i","Specify the name of the input file.","examples/5body10sym.out"/*"examples/5bodyNEW.out2"*/) // inputOption("-i","Specify the name of the input file.","examples/4bodyMoreEquations.out"/*"examples/5bodyNEW.out2"*/) // inputOption("-i","Specify the name of the input file.","examples/nbody/5bodyACAC.out") // inputOption("-i","Specify the name of the input file.","examples/nbody/5bodyACACDZ.out") // inputOption("-i","Specify the name of the input file.","examples/nbody/5bodyACACDZDE.out"), inputOption("-i","Specify the name of the input file.","examples/nbody/5bodyACACDZDEMA.out"), singleOption("-s","Chekc just a single initial system.") { registerOptions(); } const char *name() { return "_smalessixth"; } void printIntList(list const &v) { FILE *f=Stderr; fprintf(f,"{"); for(list::const_iterator i=v.begin();i!=v.end();i++) { if(i!=v.begin())fprintf(f," "); fprintf(f,"%i",*i); } fprintf(f,"}\n"); } void printIntListList(list > const &l) { for(list >::const_iterator i=l.begin();i!=l.end();i++) printIntList(*i); } /* PolynomialSet DziobekEquations(PolynomialRing const &r) { StringParser P("{r243*r353 - r233*r243*r353 - r233*r453 + r233*r243*r453 +r233*r353*r453 - r243*r353*r453," " r253*r343 - r233*r253*r343 - r233*r453 + r233*r253*r453 + r233*r343*r453 - r253*r343*r453," " -r253*r343 + r243*r253*r343 + r243*r353 - r243*r253*r353 - r243*r343*r353 + r253*r343*r353," " r143*r353 - r133*r143*r353 - r133*r453 + r133*r143*r453 + r133*r353*r453 - r143*r353*r453," " r153*r343 - r133*r153*r343 - r133*r453 + r133*r153*r453 + r133*r343*r453 - r153*r343*r453," " -r153*r343 + r143*r153*r343 + r143*r353 - r143*r153*r353 - r143*r343*r353 + r153*r343*r353," " r143*r253 - r123*r143*r253 - r123*r453 + r123*r143*r453 + r123*r253*r453 - r143*r253*r453," " r153*r243 - r123*r153*r243 - r123*r453 + r123*r153*r453 + r123*r243*r453 - r153*r243*r453," " -r153*r243 + r143*r153*r243 + r143*r253 - r143*r153*r253 - r143*r243*r253 + r153*r243*r253," " r133*r253 - r123*r133*r253 - r123*r353 + r123*r133*r353 + r123*r253*r353 - r133*r253*r353," " r153*r233 - r123*r153*r233 - r123*r353 + r123*r153*r353 + r123*r233*r353 - r153*r233*r353," " -r153*r233 + r133*r153*r233 + r133*r253 - r133*r153*r253 - r133*r233*r253 + r153*r233*r253," " r133*r243 - r123*r133*r243 - r123*r343 + r123*r133*r343 + r123*r243*r343 - r133*r243*r343," " r143*r233 - r123*r143*r233 - r123*r343 + r123*r143*r343 + r123*r233*r343 - r143*r233*r343," " -r143*r233 + r133*r143*r233 + r133*r243 - r133*r143*r243 - r133*r233*r243 + r143*r233*r243}"); return P.parsePolynomialSet(r); }*/ PolynomialSet saturationHomog(PolynomialSet const &g, int i) { WeightReverseLexicographicTermOrder T(-1*IntegerVector::standardVector(g.getRing().getNumberOfVariables(),i)); PolynomialSet g2=GE_groebnerBasis(g,T,false,true); // g2.saturate(i); g2.saturate(); return g2; } PolynomialSet removePositiveFactors(PolynomialSet const &g) { PolynomialSet ret(g.getRing()); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { Polynomial p=*i; if(p.numberOfTerms()==2) { FieldElement c1=p.terms.begin()->second; FieldElement c2=p.terms.rbegin()->second; IntegerVector e1=p.terms.begin()->first.exponent; IntegerVector e2=p.terms.rbegin()->first.exponent; if((c1+c2).isZero()) { int d=gcdOfVector(concatenation(e1,e2)); if(d&1) p=Polynomial(Term(c1,Monomial(g.getRing(),e1/d)))+Polynomial(Term(c2,Monomial(g.getRing(),e2/d))); else p=Polynomial(Term(c1,Monomial(g.getRing(),2*e1/d)))+Polynomial(Term(c2,Monomial(g.getRing(),2*e2/d))); } } ret.push_back(p); } return ret; } PolynomialSet withVariablesEqual(PolynomialSet const &g, Polynomial const &b) { PolynomialSet ret(g.getRing()); PolynomialSet B(g.getRing()); B.push_back(b); LexicographicTermOrder T; B.markAndScale(T); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { ret.push_back(division(*i,B,T)); } // ret.push_back(); return ret; } PolynomialSet binomialReduce(PolynomialSet g) { PolynomialSet binomials(g.getRing()); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) if(i->numberOfTerms()==2)binomials.push_back(*i); for(PolynomialSet::const_iterator i=binomials.begin();i!=binomials.end();i++) { g=withVariablesEqual(g,*i); g.saturate(); } for(PolynomialSet::const_iterator i=binomials.begin();i!=binomials.end();i++) { g.push_back(*i); } return g; } void processSingle(PolynomialSet g, int N) { /* Om facstd() i Singular: Hvis to trinomiumsfaktorer afsluttes beregningen efter 6min med 97 baser Hvis foerste er binomium og andet trinomium afsluttes beregningen efter 5 min med 46 baser Hvis foerste er trionomium og andet binomium afsluttes efter 12 sek med 34 baser. Hvis begger er binomier afsluttes efter 1 sek med 29 baser. */ //g.push_back(StringParser("r35^1-r25^1").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r35^2+r35*r25+r25^2").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //g.push_back(StringParser("r45^1-r15^1").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r45^2+r45*r15+r15^2").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r34^1-r24^1").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r342+r24r34+r242").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r35^1-r25^1").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r352+r25r35+r252").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*g.push_back(StringParser("r452+r45r35+r352").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! g.push_back(StringParser("r342+r34r23+r232").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! g.push_back(StringParser("r352+r25r35+r252").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ /* PolynomialSet additional=StringParser( "{r25^3*r34^3-r25^3*r34^3*r35^3-r24^3*r35^3+r24^3*r34^3*r35^3+r24^3*r25^3*r35^3-r24^3*r25^3*r34^3," "-r13^3*r15^3*r34^3*r45^3+r13^3*r15^3*r34^3*r35^3*r45^3+r13^3*r14^3*r35^3*r45^3-r13^3*r14^3*r34^3*r35^3*r45^3-r13^3*r14^3*r15^3*r35^3*r45^3+r13^3*r14^3*r15^3*r34^3*r45^3," "-r12^3*r15^3*r24^3*r45^3+r12^3*r15^3*r24^3*r25^3*r45^3+r12^3*r14^3*r25^3*r45^3-r12^3*r14^3*r24^3*r25^3*r45^3-r12^3*r14^3*r15^3*r25^3*r45^3+r12^3*r14^3*r15^3*r24^3*r45^3," "-r12^3*r15^3*r23^3*r35^3+r12^3*r15^3*r23^3*r25^3*r35^3+r12^3*r13^3*r25^3*r35^3-r12^3*r13^3*r23^3*r25^3*r35^3-r12^3*r13^3*r15^3*r25^3*r35^3+r12^3*r13^3*r15^3*r23^3*r35^3," "-r12^3*r14^3*r23^3*r34^3+r12^3*r14^3*r23^3*r24^3*r34^3+r12^3*r13^3*r24^3*r34^3-r12^3*r13^3*r23^3*r24^3*r34^3-r12^3*r13^3*r14^3*r24^3*r34^3+r12^3*r13^3*r14^3*r23^3*r34^3}").parsePolynomialSet(g.getRing()); for(PolynomialSet::const_iterator i=additional.begin();i!=additional.end();i++) g.push_back(*i); */ //"-r14^3+r14^3*r34^3+r13^3-r13^3*r34^3" // g.push_back(StringParser("r14^3-r13^3").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r343-1").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //g.push_back(StringParser("r143-1").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // g.push_back(StringParser("r34-1").parsePolynomial(g.getRing()));//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /*{//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PolynomialSet g2(g.getRing()); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) if(i->totalDegree()<20 && i->numberOfTerms()!=6 && i->numberOfTerms()<10 )g2.push_back(*i); g=g2; }*/ AsciiPrinter P(Stderr); g.saturate(); P<numberOfTerms()!=0)G2.push_back(*i); P<<"Intersection"<=0;i--) { cerr << i << endl; g2=saturationHomog(g2,i); { PolynomialSet G=g2.polynomialRingIntersection(r3); PolynomialSet G2(G.getRing()); for(PolynomialSet::const_iterator i=G.begin();i!=G.end();i++)if(i->numberOfTerms()!=0)G2.push_back(*i); P<<"Intersection"< > cones=inFile.readMatrixIncidenceProperty("CONES_COMPRESSED"); IntegerVectorList r; for(int i=0;i::const_iterator j=cones[i].begin();j!=cones[i].end();j++) { int sign=rays[*j].toVector().sum(); if(sign<0)hasNeg=true; if(sign>0)hasPos=true; v+=rays[*j]; } //r.push_front(v); if(hasPos ||((!hasPos)&&(!hasNeg))) { r.push_back(v); P.printInteger(r.size()-1); P<embeddedInto(ac.getRing())); if(dziobek) { PolynomialSet dziobek=DziobekEquations(ac.getRing(),N,true); for(PolynomialSet::const_iterator i=dziobek.begin();i!=dziobek.end();i++)all.push_back(*i); } PolynomialSet d=nbodyDeterminants(ac.getRing(),N,true,5); for(PolynomialSet::const_iterator i=d.begin();i!=d.end();i++)all.push_back(*i); if(massEquations)all.push_back(massEquation(ac.getRing(),N,true)); P<<"ALL\n"< void autoReduceRestricted(PolynomialSet *g, PolynomialSet const &initialIdeal) { /* AsciiPrinter P(Stderr); P.printPolynomialSet(*g); P.printPolynomialSet(initialIdeal); */ assert(g->size()==initialIdeal.size()); PolyhedralCone V=homogeneitySpace(initialIdeal); PolyhedralCone C=groebnerCone(*g,false);//no algebraic test - we hope that polyhedral methods are better PolyhedralCone C2=intersection(C,V); IntegerVector omega=C2.getRelativeInteriorPoint(); while(1) { PolyhedralCone C=intersection(groebnerCone(*g,false),V); C.findFacets(); IntegerVectorList normals=C.getHalfSpaces(); bool allAreTrueFacets=true; for(IntegerVectorList::const_iterator i=normals.begin();i!=normals.end();i++) { IntegerVectorList equations=C.getEquations(); equations.push_back(*i); PolyhedralCone C2(C.getHalfSpaces(),equations,C.ambientDimension()); IntegerVector omega2=C2.getRelativeInteriorPoint(); // C2.print(&P); bool isTrueFacet=false; for(PolynomialSet::iterator j=g->begin();j!=g->end();j++) { Polynomial p=initialForm(*j,omega2)-initialForm(*j,omega); if(!p.isZero()) { /* cerr << "poly1:"; P.printPolynomial(*j); cerr << endl << "in_omega"; P.printPolynomial(initialForm(*j,omega)); cerr << endl << "in_omega2"; P.printPolynomial(initialForm(*j,omega2)); */ Polynomial q=divisionLift(p,initialIdeal,*g,LexicographicTermOrder(),true); *j-=q; /*cerr << endl << "q"; P.printPolynomial(q); cerr << endl << "r"; P.printPolynomial(division(p,initialIdeal,LexicographicTermOrder())); cerr << endl << "poly2:"; P.printPolynomial(*j); cerr << endl; */ if(!division(p,initialIdeal,LexicographicTermOrder()).isZero())isTrueFacet=true; } } if(!isTrueFacet)allAreTrueFacets=false; } if(allAreTrueFacets)break; } } gfan0.6.2/src/tropicaldeterminant.h0000644000175000017500000000034113122232611016666 0ustar andersanders#ifndef TROPICALDETERMINANT_H_INCLUDED #define TROPICALDETERMINANT_H_INCLUDED #include "matrix.h" #define td_minusInfinity 0x80000000 int tropicalDeterminant(IntegerMatrix const &m); void tropicalDeterminantTest(); #endif gfan0.6.2/src/traverser_stableintersection.cpp0000644000175000017500000000627613122232611021164 0ustar andersanders#include "traverser_stableintersection.h" #include #include "halfopencone.h" #include "tropical.h" #include "division.h" #include "wallideal.h" #include "groebnerengine.h" #include "tropical2.h" #include "multiplicity.h" #include "mixedvolume.h" #include "log.h" StableIntersectionTraverser::StableIntersectionTraverser(PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &idealGroebnerBasis_): ConeTraverser(coneGroebnerBasis_.getRing().getNumberOfVariables()), coneGroebnerBasis(coneGroebnerBasis_), idealGroebnerBasis(idealGroebnerBasis_), theCone(coneGroebnerBasis_.getRing().getNumberOfVariables()) { n=coneGroebnerBasis_.getRing().getNumberOfVariables(); updatePolyhedralCone(mixedVolume(coneGroebnerBasis)); PolyhedralCone homogeneitySpac=homogeneitySpace(coneGroebnerBasis); d=homogeneitySpac.dimensionOfLinealitySpace(); } void StableIntersectionTraverser::updatePolyhedralCone(int multiplicity) { theCone=PolyhedralCone(fastNormals(wallInequalities(idealGroebnerBasis)),wallInequalities(coneGroebnerBasis),n); theCone.canonicalize(); theCone.setMultiplicity(multiplicity); } static void checkSameLeadingTerms(PolynomialSet const &a, PolynomialSet const &b) { assert(a.size()==b.size()); PolynomialSet::const_iterator A=a.begin(); for(PolynomialSet::const_iterator B=b.begin();B!=b.end();B++,A++) assert(A->getMarked().m.exponent==B->getMarked().m.exponent); } void StableIntersectionTraverser::changeCone(IntegerVector const &ridgeVector, IntegerVector const &rayVector) { IntegerVectorList m; m.push_back(ridgeVector); m.push_back(rayVector); MatrixTermOrder T(m); idealGroebnerBasis.markAndScale(T); coneGroebnerBasis=initialFormsAssumeMarked(initialFormsAssumeMarked(idealGroebnerBasis,ridgeVector),rayVector); updatePolyhedralCone(mixedVolume(coneGroebnerBasis)); checkSameLeadingTerms(idealGroebnerBasis,coneGroebnerBasis); } IntegerVectorList StableIntersectionTraverser::link(IntegerVector const &ridgeVector) { assert(idealGroebnerBasis.containsInClosedGroebnerCone(ridgeVector)); PolynomialSet tempIdeal=initialFormsAssumeMarked(idealGroebnerBasis,ridgeVector); tempIdeal.simplestPolynomialsFirst(); PolyhedralFan theLink=tropicalHyperSurfaceIntersectionClosed(n,tempIdeal); IntegerVectorList rays1=theLink.getRaysInPrintingOrder(0); log2 { cerr<<"Ray candidates:"< static Polynomial wallPolynomial(Polynomial const &p, Subspace const &subspace) // This routine should be deleted since it is inefficient // hmm... does this actually work? { Polynomial r(p.getRing()); IntegerVector markedExponent=p.getMarked().m.exponent; for(TermMap::const_iterator i=p.terms.begin();i!=p.terms.end();i++) { IntegerVector dif=markedExponent-i->first.exponent; if(subspace.contains(dif)) r+=Polynomial(Term(i->second,i->first)); } r.mark(Monomial(p.getRing(),markedExponent)); return r; } static PolynomialSet wallIdeal(PolynomialSet const &groebnerBasis, Subspace const &subspace) { // fprintf(Stderr,"wallIdeal %i",perp.size()); PolynomialSet ret(groebnerBasis.getRing()); for(PolynomialSet::const_iterator i=groebnerBasis.begin();i!=groebnerBasis.end();i++) ret.push_back(wallPolynomial(*i,subspace)); // fprintf(Stderr,"done\n"); return ret; } BergmanFan bergmanRayIntersection(PolynomialSet const &idealGroebnerBasis, int d) // Input ideal is assumed to be homogeneous with respect to a positive vector // Input ideal is assumed not to contain a monomial // Call the Krull dimensionn of the ring/ideal d // The ideal is homogenous with respect to a vector space of dimension d-1 // All d dimensional cones in the Gro\"obner fan with no monomials are computed { BergmanFan bfan; int n=idealGroebnerBasis.numberOfVariablesInRing(); // log0 AsciiPrinter(Stderr).printPolynomialSet(idealGroebnerBasis); if(d==-1)d=krullDimension(idealGroebnerBasis); PolyhedralFan bergmanFan(n); PolynomialSet tropBasis=tropicalBasisOfCurve(n,idealGroebnerBasis,&bergmanFan,d-1); // PolyhedralFan bergmanFan=tropicalPrincipalIntersection(n,tropBasis,d-1); IntegerVectorList rays=bergmanFan.getRays(d); int maximalConeLabel=0; // fprintf(Stderr,"---------------------------------------------------------\n"); // AsciiPrinter(Stderr).printVectorList(rays); // fprintf(Stderr,"---------------------------------------------------------\n"); log2 cerr<<"BBLABL"; for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) { log2 cerr<<"1"; PolynomialSet g=idealGroebnerBasis; g=GE_groebnerBasis(g,WeightReverseLexicographicTermOrder(*i),true,false);//Set to true? // buchberger(&g,WeightReverseLexicographicTermOrder(*i)); PolynomialSet cg=initialFormsAssumeMarked(g,*i); log2 cerr<<"2"; bool inList=false; for(BergmanFan::MaximalConeList::const_iterator j=bfan.cones.begin();j!=bfan.cones.end();j++) { if(areIdealsEqual(j->coneGroebnerBasis,cg)) { inList=true; break; } } log2 cerr<<"3"; if(!inList) { bfan.cones.push_back(BergmanFan::MaximalCone(cg,g,true,maximalConeLabel++)); } log2 cerr<<"4"; } log2 cerr<<"BBLAB END"; // AsciiPrinter temp(Stderr); // bfan.print(temp); return bfan; } BergmanFan bergmanRay(PolynomialSet const &idealGroebnerBasis) // Input ideal is assumed to be homogeneous with respect to a positive vector // Input ideal is assumed not to contain a monomial // Call the Krull dimensionn of the ring/ideal d // The ideal is homogenous with respect to a vector space of dimension d-1 // All d dimensional cones in the Gro\"obner fan with no monomials are computed { BergmanFan bfan; EnumerationTargetCollector gfan; LexicographicTermOrder myTermOrder; ReverseSearch rs(myTermOrder); rs.setEnumerationTarget(&gfan); rs.enumerate(idealGroebnerBasis); int n=idealGroebnerBasis.numberOfVariablesInRing(); fprintf(Stderr,"rankOfMatrix(wallin.idealGroebnerBasis=%i\n",rankOfMatrix(wallInequalities(idealGroebnerBasis))); AsciiPrinter(Stderr).printVectorList(wallInequalities(idealGroebnerBasis)); int d=n-rankOfMatrix(wallInequalities(idealGroebnerBasis))+1; int krull=krullDimension(idealGroebnerBasis); //AsciiPrinter(Stderr).printVectorList(wallInequalities(idealGroebnerBasis)); assert(rankOfMatrix(wallInequalities(idealGroebnerBasis))==Subspace(wallInequalities(idealGroebnerBasis)).dimension()); // fprintf(Stderr,"d: %i krull: %i\n",d,krull); // assert(d==krull); int maximalConeLabel=0; for(PolynomialSetList::const_iterator g=gfan.theList.begin();g!=gfan.theList.end();g++) { PolynomialSetList s; //fprintf(Stderr,"current gbasis:\n"); //AsciiPrinter(Stderr).printPolynomialSet(*g); if(0) { s=fullColoredIdeals(*g,false); fprintf(Stderr,"Full colored ideals computed, #=%i\n",(int)s.size()); } else { IntegerVectorList inequalities=wallInequalities(*g); inequalities=wallFlipableNormals(*g,true); int isize=inequalities.size(); // fprintf(Stderr,"cdd facets to rays "); // AsciiPrinter(Stderr).printVectorList(inequalities); IntegerVectorList rays=extremeRaysInequalityIndices(inequalities); //fprintf(Stderr,"done\n"); //AsciiPrinter(Stderr).printVectorList(rays); // AsciiPrinter(Stderr).printVectorList(rays); for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) if(i->size()!=isize) { IntegerVectorList perp; int j=0; int K=0; for(IntegerVectorList::const_iterator k=inequalities.begin();k!=inequalities.end()&&jsize();k++,K++) if((*i)[j]==K) { perp.push_back(*k); j++; } s.push_back(wallIdeal(*g,Subspace(perp))); } } //fprintf(Stderr,"Number of face ideals to check:%i\n",s.size()); for(PolynomialSetList::const_iterator i=s.begin();i!=s.end();i++) { //fprintf(Stderr,"d:%i\n",d); //fprintf(Stderr,"krull:%i\n",krull); //fprintf(Stderr,"n:%i\n",n); //fprintf(Stderr,"rank: %i\n",rankOfMatrix(wallInequalities(*i))); assert(i->isMarked()); // fprintf(Stderr,"d: %i, rank %i",d,n-rankOfMatrix(wallInequalities(*i))); if(d==n-rankOfMatrix(wallInequalities(*i)))//dimension check { // fprintf(Stderr,"Checking monomial containment"); if(!containsMonomial(*i)) { // fprintf(Stderr,"Done - no\n"); PolynomialSet cg=*i; //buchberger(&cg,StandardGradedLexicographicTermOrder()); The cg is already a Groebner basis bool inList=false; for(BergmanFan::MaximalConeList::const_iterator j=bfan.cones.begin();j!=bfan.cones.end();j++) { if(areIdealsEqual(j->coneGroebnerBasis,cg)) { inList=true; break; } } if(!inList) { bfan.cones.push_back(BergmanFan::MaximalCone(cg,*g,true,maximalConeLabel++)); } } // else // fprintf(Stderr,"Done - yes\n"); } else fprintf(Stderr,"dimension check fails\n"); } } //fprintf(Stderr,"No duplicates:\n"); /* for(PolynomialSetList::const_iterator i=tropical.begin();i!=tropical.end();i++) { AsciiPrinter(Stdout).printPolynomialList(i->coneGroebnerBasis); int coDim=rankOfMatrix(wallInequalities(*i)); int d=i->numberOfVariablesInRing()-coDim; fprintf(Stderr,"%i\n",d); } */ return bfan; } /*static bool staticInOrbit(PolynomialSet const &groebnerBasis1, PolynomialSet const &groebnerBasis2, SymmetryGroup const &s) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(areIdealsEqual(SymmetryGroup::permutePolynomialSet(groebnerBasis2,*j),groebnerBasis1))return true; return false; }*/ /*static bool staticPermutationFixesCone(PolynomialSet const &groebnerBasis, IntegerVector const &v) { // Cone is fixed iff the cone ideal is fixed. PolynomialSet q(groebnerBasis.getRing()); for(PolynomialSet::const_iterator i=groebnerBasis.begin();i!=groebnerBasis.end();i++) { q.push_back(SymmetryGroup::permutePolynomial(*i,v)); } return areIdealsEqual(q,groebnerBasis); }*/ /*static int staticOrbitSize(PolynomialSet const &groebnerBasis, SymmetryGroup const &s) { int groupSize=s.elements.size(); int numFixed=0; for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(staticPermutationFixesCone(groebnerBasis,*j))numFixed++; // fprintf(Stderr,"groupSize = %i, numFixed = %i\n",groupSize,numFixed); return groupSize/numFixed; } */ /** Objects of this class represent ConeOrbits of facet of a tropical variety. */ class ConeOrbit { public: const SymmetryGroup &s; PolynomialSet coneGroebnerBasis; PolynomialSet idealGroebnerBasis; int label; // PolynomialSetList markedFacets; PolyhedralCone theCone; // IntegerVectorList markedFacets; //marked facets of dim d cone. The facet of a facet is a ridge of the tropical variety. IntegerVector stableRay; //stable relative interior point IntegerVectorList unMarkedFacetNormals; ConeOrbit(const SymmetryGroup &s_, PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &idealGroebnerBasis_, int label_): coneGroebnerBasis(coneGroebnerBasis_), idealGroebnerBasis(idealGroebnerBasis_), label(label_), s(s_), theCone(fastNormals(wallInequalities(idealGroebnerBasis_)),//wallFlipableNormals(idealGroebnerBasis_,false), wallInequalities(coneGroebnerBasis_), idealGroebnerBasis_.getRing().getNumberOfVariables()) { /* log0 AsciiPrinter(Stderr).printPolynomialSet(coneGroebnerBasis_); log0 AsciiPrinter(Stderr).printPolynomialSet(idealGroebnerBasis_); log0 fprintf(Stderr,"inequalities:\n"); log0 AsciiPrinter(Stderr).printVectorList(wallInequalities(coneGroebnerBasis_)); log0 fprintf(Stderr,"equalities:\n"); log0 AsciiPrinter(Stderr).printVectorList(wallFlipableNormals(idealGroebnerBasis_,false)); AsciiPrinter P(Stderr); log0 theCone.print(&P); */ theCone.findFacets(); // theCone.canonicalize();//REMOVE ME JAN 2009 stableRay=PolyhedralFan::stableRay(theCone,&s); unMarkedFacetNormals=theCone.getHalfSpaces(); } IntegerVector getStableRay()const { return stableRay; } bool doesPermutationFixCone(IntegerVector const &v)const { // Cone is fixed iff stableRay is fixed. return (SymmetryGroup::compose(v,stableRay)==stableRay); } int orbitSize()const { int groupSize=s.elements.size(); int numFixed=0; for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(doesPermutationFixCone(*j))numFixed++; // fprintf(Stderr,"groupSize = %i, numFixed = %i\n",groupSize,numFixed); return groupSize/numFixed; } void markFacet(IntegerVector const &relIntRidgeVector) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(doesPermutationFixCone(*j)) { IntegerVector relIntRidgeVector2=SymmetryGroup::compose(*j,relIntRidgeVector); { for(IntegerVectorList::iterator i=unMarkedFacetNormals.begin();i!=unMarkedFacetNormals.end();) if(dotLong(*i,relIntRidgeVector2)==0) { IntegerVectorList::iterator temp=i; temp++; unMarkedFacetNormals.erase(i); i=temp; } else i++; } } } /* bool containsAndMark(PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &facetIdeal, IntegerVector *labelPermutation) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(areIdealsEqual(coneGroebnerBasis,SymmetryGroup::permutePolynomialSet(coneGroebnerBasis_,*j))) { PolynomialSet facetIdeal2=SymmetryGroup::permutePolynomialSet(facetIdeal,*j); bool found=false; for(PolynomialSetList::const_iterator i=markedFacets.begin();i!=markedFacets.end();i++) if(areIdealsEqual(*i,facetIdeal2)) { found=true; break; } // assert(!found); //this is not a mistake is it? markedFacets.push_back(facetIdeal2); if(labelPermutation)*labelPermutation=*j; return true; } return false; }*/ /* Alternative using only geometric information. */ bool containsAndMark(IntegerVector const &relIntFacetVector, IntegerVector const &relIntRidgeVector, IntegerVector *labelPermutation) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(theCone.contains(SymmetryGroup::compose(*j,relIntFacetVector))) { markFacet(SymmetryGroup::compose(*j,relIntRidgeVector)); if(labelPermutation)*labelPermutation=*j; return true; } return false; } bool hasUnmarkedFacet()const { return(!unMarkedFacetNormals.empty()); } IntegerVector getUnmarkedFacet()const { assert(!unMarkedFacetNormals.empty()); return *unMarkedFacetNormals.begin(); } /* bool isMarkedFacet(PolynomialSet const &f) { for(SymmetryGroup::ElementContainer::const_iterator j=s.elements.begin();j!=s.elements.end();j++) if(staticPermutationFixesCone(coneGroebnerBasis,*j)) for(PolynomialSetList::const_iterator i=markedFacets.begin();i!=markedFacets.end();i++) if(areIdealsEqual(SymmetryGroup::permutePolynomialSet(f,*j),*i))return true; return false; }*/ void print(AsciiPrinter &p)const { p.printString("ConeOrbit{\n"); p.printInteger(label); p.printNewLine(); IntegerVector v=getStableRay(); /* if(v.size()==25) { p.printVector(v.subvector(0,5));p.printNewLine(); p.printVector(v.subvector(5,10));p.printNewLine(); p.printVector(v.subvector(10,15));p.printNewLine(); p.printVector(v.subvector(15,20));p.printNewLine(); p.printVector(v.subvector(20,25));p.printNewLine(); }*/ p.printVector(v); p.printNewLine(); p.printString("Orbit size:"); p.printInteger(orbitSize()); p.printString("\nConeIdeal:\n"); p.printPolynomialSet(coneGroebnerBasis); p.printString("\nFullIdeal:\n"); p.printPolynomialSet(idealGroebnerBasis); // p.printString("Unmarked facet normals:\n"); // p.printVectorList(unMarkedFacetNormals); theCone.print(&p); p.printString("}ConeOrbit\n"); } IntegerVectorList getEquations()const { return theCone.getEquations(); } IntegerVectorList getInequalities()const { return theCone.getHalfSpaces(); } }; class ConeOrbitContainer { typedef list ConeOrbitList; ConeOrbitList l; public: void push_back(const ConeOrbit &orbit) { l.push_back(orbit); } bool empty() { return l.empty(); } ConeOrbit &front() { return *l.begin(); } int size() { return l.size(); } void pop_front() { l.pop_front(); } void print(AsciiPrinter &p) { p.printString("OrbitList{\n"); for(ConeOrbitList::const_iterator i=l.begin();i!=l.end();i++) { i->print(p); // p.printPolynomialSet(i->coneGroebnerBasis); //p.printNewLine(); } p.printString("}OrbitList\n"); } bool containsAndMark(IntegerVector const &relIntFacetVector, IntegerVector const &relIntRidgeVector, int *label, IntegerVector *labelPermutation) // bool containsAndMark(PolynomialSet const &coneGroebnerBasis, PolynomialSet const &facetIdeal, int *label, IntegerVector *labelPermutation) { // fprintf(Stderr,"listlength:%i",l.size()); // int I=0; // for(ConeOrbitList::const_iterator i=l.begin();i!=l.end();i++) // { // fprintf(Stderr,"%i",I++); // } for(ConeOrbitList::iterator i=l.begin();i!=l.end();i++) { /* fprintf(Stderr,"Comparing:\n"); AsciiPrinter(Stderr).printPolynomialSet(coneGroebnerBasis); AsciiPrinter(Stderr).printPolynomialSet(i->coneGroebnerBasis); */ // if(i->containsAndMark(coneGroebnerBasis,facetIdeal,labelPermutation)) if(i->containsAndMark(relIntFacetVector,relIntRidgeVector,labelPermutation)) // if(areIdealsEqual(coneGroebnerBasis,i->coneGroebnerBasis))// this could be slow! { *label=i->label; return true; } // if(i->coneGroebnerBasis==coneGroebnerBasis)return true; } /* fprintf(Stderr,"________________NOT IN LIST:\n"); AsciiPrinter(Stderr).printPolynomialSet(coneGroebnerBasis); */ return false; } }; static int staticOrbitSize(PolynomialSet const &coneGroebnerBasis, PolynomialSet const &idealGroebnerBasis, SymmetryGroup const &s) { return ConeOrbit(s, coneGroebnerBasis, idealGroebnerBasis, -1).orbitSize(); } BergmanFan bergman(PolynomialSet const &coneGroebnerBasis1, PolynomialSet const &idealGroebnerBasis1, SymmetryGroup const *symmetryGroup) { PolynomialRing theRing=coneGroebnerBasis1.getRing(); bool useFanIntersection=true; bool isSimplicial=true; assert(coneGroebnerBasis1.numberOfVariablesInRing()==idealGroebnerBasis1.numberOfVariablesInRing()); int n=coneGroebnerBasis1.numberOfVariablesInRing(); SymmetryGroup localSymmetryGroup(n); if(!symmetryGroup)symmetryGroup=&localSymmetryGroup; BergmanFan ret; ret.setSymmetryGroup(*symmetryGroup); ConeOrbitContainer active; int maximalConeLabel=0; { ConeOrbit newConeOrbit(*symmetryGroup,coneGroebnerBasis1,idealGroebnerBasis1,maximalConeLabel++); log1 fprintf(Stderr,"Adding orbit of size: %i\n",newConeOrbit.orbitSize()); active.push_back(newConeOrbit); } while(!active.empty()) { log1 fprintf(Stderr,"\n-------------------------------------\n"); log1 fprintf(Stderr,"Size of active set: %i, Completed: %i\n",(int)active.size(),(int)ret.cones.size()); log1 fprintf(Stderr,"-------------------------------------\n"); AsciiPrinter p(Stderr); ConeOrbit ¤t=active.front(); /* AsciiPrinter p2(stdout);//REMOVE THESE THREE LINES current.print(p2); fflush(stdout); */ // IntegerVectorList equalities=wallInequalities(current.coneGroebnerBasis); // IntegerVectorList normals=wallFlipableNormals(current.idealGroebnerBasis,false); /* { PolyhedralCone p(normals,equalities); p.findFacets(); isSimplicial&=p.isSimplicial(); }HUSK AT INDSÆTTE DETTE IGEN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ // removeRedundantRows(&normals,&equalities,true);//IS THIS RIGHT? IntegerVectorList facePerp=current.getEquations();//equalities; /* int numberOfNormals=normals.size(); int numberOfEqualities=equalities.size(); IntegerVectorList inequalities=equalities; inequalities.splice(inequalities.begin(),normals,normals.begin(),normals.end()); IntegerVector equalitySet(inequalities.size()); for(int i=0;iidealGroebnerBasis.isMarked()); log2 cerr<<"8"; PolynomialSet g2(theRing); WeightTermOrder termOrder(termorderWeight(initialIdeal)); for(PolynomialSet::const_iterator j=i->idealGroebnerBasis.begin();j!=i->idealGroebnerBasis.end();j++) g2.push_back(divisionLift(*j, initialIdeal, current.idealGroebnerBasis, termOrder)); assert(g2.isMarked()); log2 cerr<<"9"; if(1) { log2 cerr << "AUTOREDUCTION"; autoReduce(&g2,LexicographicTermOrder()); log2 cerr << "AUTOREDUCTION END"<idealGroebnerBasis); log0 cerr << "RESTRICTED AUTOREDUCTION END"<coneGroebnerBasis,g2,-1); log2 cerr<<"0"; IntegerVector relIntFacetVector=tempConeOrbit.getStableRay(); log2 cerr<<"A"; int label=-1; IntegerVector labelPermutation; if(!active.containsAndMark(relIntFacetVector,relIntRidgeVector,&label,&labelPermutation)) // if(!active.containsAndMark(i->coneGroebnerBasis,initialIdeal,&label,&labelPermutation)) { log2 cerr<<"B"; if(!ret.contains(i->coneGroebnerBasis)) { label=maximalConeLabel++; labelPermutation=SymmetryGroup::identity(n); ConeOrbit newConeOrbit(*symmetryGroup,i->coneGroebnerBasis,g2,label); log1 fprintf(Stderr,"Adding orbit of size: %i\n",newConeOrbit.orbitSize()); //newConeOrbit.markFacet(initialIdeal); newConeOrbit.markFacet(relIntRidgeVector); active.push_back(newConeOrbit); } else { assert(0);//Can this ever happen? REMOVE JAN 2009 } log2 cerr<<"C"; } log2 cerr<<"D"; ret.codimensionOneCones.back().incidenceList.push_back(label); log2 cerr<<"E"; ret.codimensionOneCones.back().incidencePermutationList.push_back(labelPermutation); log2 cerr<<"F"; } } // else // numberOfAlreadyMarkedFacets++; } else { assert(0); } } // equalitySet[I]=0; // i++; //assert(0);//for timing purposes } log1 fprintf(Stderr,"Done processing this orbit - Number of valid facets: %i Number of already marked facets: %i\n",numberOfValidFacets,numberOfAlreadyMarkedFacets); ret.cones.push_back(BergmanFan::MaximalCone(current.coneGroebnerBasis,current.idealGroebnerBasis,false,current.label,numberOfValidFacets)); active.pop_front(); } ret.setSimplicial(isSimplicial); return ret; } //-------------------------------------- // BergmanFan //-------------------------------------- BergmanFan::MaximalCone::MaximalCone(PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &idealGroebnerBasis_, bool storeIdealBasis, int label_, int numberOfFacets_): idealBasisStored(storeIdealBasis), coneGroebnerBasis(coneGroebnerBasis_), idealGroebnerBasis(idealGroebnerBasis_), label(label_), numberOfFacets(numberOfFacets_), multiplicity(-1), theCone(fastNormals(wallInequalities(idealGroebnerBasis_)), wallInequalities(coneGroebnerBasis_), idealGroebnerBasis_.getRing().getNumberOfVariables()) { if(!storeIdealBasis)idealGroebnerBasis=PolynomialSet(coneGroebnerBasis_.getRing()); theCone.canonicalize(); } int BergmanFan::numberOfMaximalCones()const { int ret=0;; for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) { IntegerVector stableRay=PolyhedralFan::stableRay(i->theCone,&symmetryGroup); //ConeOrbit C(symmetryGroup, i->coneGroebnerBasis, i->idealGroebnerBasis, -1); ret+=symmetryGroup.orbitSize(stableRay);//C.orbitSize(); // ret+=staticOrbitSize(i->coneGroebnerBasis, symmetryGroup); } return ret; } void BergmanFan::print(Printer &p) { int numberOfMaximalCones=0; p.printString("Printing tropical variety modulo symmetry\n"); p.printString("-----------------"); p.printNewLine(); p.printString("1. Maximal cones:\n"); p.printString("-----------------"); p.printNewLine(); for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) { p.printString("Orbit index: "); p.printInteger(i->label); p.printString("\n"); p.printString("Initial ideal:\n"); p.printPolynomialSet(i->coneGroebnerBasis); //p.printPolynomialSet(i->idealGroebnerBasis); int orbitSize=(symmetryGroup.sizeOfBaseSet())?staticOrbitSize(i->coneGroebnerBasis,i->coneGroebnerBasis,symmetryGroup):1; p.printString("OrbitSize:"); p.printInteger(orbitSize); p.printString("\n"); p.printString("NumberOfFacets:"); p.printInteger(i->numberOfFacets); p.printString("\n\n"); numberOfMaximalCones+=orbitSize; /* { IntegerVectorList normals=wallInequalities(i->idealGroebnerBasis); IntegerVectorList equations=wallInequalities(i->coneGroebnerBasis); PolyhedralCone c(normals,equations); c.canonicalize(); c.print(&p); } */ if(symmetryGroup.sizeOfBaseSet()) { list indices; int index=0; /* //This needs to be changed so that torus permutations are considered too. for(MaximalConeList::const_iterator j=cones.begin();j!=cones.end();j++,index++) if(staticInOrbit(j->coneGroebnerBasis,i->coneGroebnerBasis,symmetryGroup))indices.push_back(index); */ if(indices.size()>1) { fprintf(Stderr,"Conflicting orbits!!!!:"); for(list::const_iterator j=indices.begin();j!=indices.end();j++) fprintf(Stderr," %i ",*j); fprintf(Stderr,"\n"); } } } p.printString("-----------------------"); p.printNewLine(); p.printString("2. Codimension 1 cones:\n"); p.printString("-----------------------"); p.printNewLine(); for(CodimensionOneConeList::const_iterator i=codimensionOneCones.begin();i!=codimensionOneCones.end();i++) { //p.printString("----------------------"); // p.printNewLine(); p.printString("Groebner basis of initial ideal:\n"); p.printPolynomialSet(i->idealGroebnerBasis); // p.printNewLine(); p.printString("Adjacent maximal cones (orbit index, permutation):\n"); p.printString("("); IntegerVectorList::const_iterator J=i->incidencePermutationList.begin(); for(list::const_iterator j=i->incidenceList.begin();j!=i->incidenceList.end() && J!=i->incidencePermutationList.end();j++,J++) { if(j!=i->incidenceList.begin())p.printString(",\n"); p.printString("("); p.printInteger(*j); p.printString(", "); p.printVector(*J); p.printString(")"); } p.printString(")\n"); { int index=*(i->incidenceList.begin()); MaximalConeList::const_iterator j=cones.begin(); while(index>0){index--;j++;} // IntegerVectorList normals=wallInequalities(SymmetryGroup::permutePolynomialSet(j->idealGroebnerBasis,*(i->incidencePermutationList.begin()))); /* IntegerVectorList normals=wallInequalities(SymmetryGroup::permutePolynomialSet(j->idealGroebnerBasis,SymmetryGroup::inverse(*(i->incidencePermutationList.begin())))); IntegerVectorList equations=wallInequalities(i->idealGroebnerBasis); PolyhedralCone c(normals,equations); c.canonicalize(); c.print(&p); */ /* p.printString("-----------"); p.printNewLine(); PolyhedralFan F=PolyhedralFan::facetsOfCone(c); F.print(&p); p.printString("-----------"); p.printNewLine(); */ //p.printString("----------------------"); p.printNewLine(); } } p.printString("Done printing tropical variety - #maxcones="); p.printInteger(numberOfMaximalCones); p.printString(" ("); p.printInteger(cones.size()); p.printString(") #codim1cones= ? ("); p.printInteger(codimensionOneCones.size()); p.printString(")"); p.printNewLine(); } bool BergmanFan::contains(PolynomialSet const &g) { for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) { if(areIdealsEqual(g,i->coneGroebnerBasis)) { return true; } } return false; } void BergmanFan::setSymmetryGroup(SymmetryGroup const &s) { symmetryGroup=s; } PolyhedralFan BergmanFan::toPolyhedralFan()const { assert(!cones.empty()); int n=cones.begin()->idealGroebnerBasis.numberOfVariablesInRing(); PolyhedralFan ret(n); for(MaximalConeList::const_iterator i=cones.begin();i!=cones.end();i++) { //PolyhedralCone c1(wallInequalities(i->idealGroebnerBasis),wallInequalities(i->coneGroebnerBasis)); // PolyhedralCone c1(wallFlipableNormals(i->idealGroebnerBasis,false),wallInequalities(i->coneGroebnerBasis),n); PolyhedralCone c1=i->theCone; log2 fprintf(Stderr,"Cononicalising...\n"); c1.canonicalize(); log2 fprintf(Stderr,"... done canonicalising...\n"); // fprintf(Stderr,"a\n"); // for(SymmetryGroup::ElementContainer::const_iterator j=symmetryGroup.elements.begin();j!=symmetryGroup.elements.end();j++) // { /* IntegerVectorList normals=wallInequalities(SymmetryGroup::permutePolynomialSet(i->idealGroebnerBasis,*j)); IntegerVectorList equations=wallInequalities(SymmetryGroup::permutePolynomialSet(i->coneGroebnerBasis,*j)); PolyhedralCone c(normals,equations); */ // PolyhedralCone c=c1.permuted(*j); // c.canonicalize(); c1.setMultiplicity(i->multiplicity); ret.insert(c1); // } } return ret; } void BergmanFan::setSimplicial(bool b) { simplicial=b; } bool BergmanFan::isSimplicial()const { return simplicial; } void BergmanFan::computeMultiplicities() { for(MaximalConeList::iterator i=cones.begin();i!=cones.end();i++) i->multiplicity=multiplicity(i->coneGroebnerBasis); //MULTIPLICITY TEST // AsciiPrinter(Stderr).printPolynomialSet(current.coneGroebnerBasis); // fprintf(Stderr,"MULTIPLICITY :%i\n",multiplicity(current.coneGroebnerBasis)); } gfan0.6.2/src/log.h0000644000175000017500000000111713122232611013401 0ustar andersanders#ifndef LOG_H_INCLUDED #define LOG_H_INCLUDED /* The main purpose of this file is to define notation for identifying the parts of the Gfan code that prints out debug information. Later this notation will probably change. A second purpose is to be able to disable logging.*/ extern int logLevel; void setLogLevel(int l); /* Use log0 for temporary output while debugging. This makes it easy to remove debugging commands after the bug has been fixed. */ #define log0 if(logLevel>=0) #define log1 if(logLevel>=1) #define log2 if(logLevel>=2) #define log3 if(logLevel>=3) #endif gfan0.6.2/src/app_smalessixth2.cpp0000644000175000017500000002147113122232611016446 0ustar andersanders#include #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "lp.h" #include "gfanapplication.h" #include "polyhedralcone.h" #include "tropical2.h" #include "nbody.h" #include "polymakefile.h" #include "determinant.h" #include "subspace.h" #include "triangulation.h" #include "groebnerengine.h" class SmalesSixth2Application : public GFanApplication { StringOption inputOption; SimpleOption singleOption; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program solves ........\n"; } SmalesSixth2Application(): inputOption("-i","Specify the name of the input file.","examples/nbody/5ACAC.out"), singleOption("-s","Chekc just a single initial system.") { registerOptions(); } const char *name() { return "_smalessixth2"; } void printIntList(list const &v) { FILE *f=Stderr; fprintf(f,"{"); for(list::const_iterator i=v.begin();i!=v.end();i++) { if(i!=v.begin())fprintf(f," "); fprintf(f,"%i",*i); } fprintf(f,"}\n"); } void printIntListList(list > const &l) { for(list >::const_iterator i=l.begin();i!=l.end();i++) printIntList(*i); } PolynomialSet saturationHomog(PolynomialSet const &g, int i) { WeightReverseLexicographicTermOrder T(-1*IntegerVector::standardVector(g.getRing().getNumberOfVariables(),i)); PolynomialSet g2=GE_groebnerBasis(g,T,false,true); // g2.saturate(i); g2.saturate(); return g2; } PolynomialSet removePositiveFactors(PolynomialSet const &g) { PolynomialSet ret(g.getRing()); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { Polynomial p=*i; if(p.numberOfTerms()==2) { FieldElement c1=p.terms.begin()->second; FieldElement c2=p.terms.rbegin()->second; IntegerVector e1=p.terms.begin()->first.exponent; IntegerVector e2=p.terms.rbegin()->first.exponent; if((c1+c2).isZero()) { int d=gcdOfVector(concatenation(e1,e2)); if(d&1) p=Polynomial(Term(c1,Monomial(g.getRing(),e1/d)))+Polynomial(Term(c2,Monomial(g.getRing(),e2/d))); else p=Polynomial(Term(c1,Monomial(g.getRing(),2*e1/d)))+Polynomial(Term(c2,Monomial(g.getRing(),2*e2/d))); } } ret.push_back(p); } return ret; } PolynomialSet withVariablesEqual(PolynomialSet const &g, Polynomial const &b) { PolynomialSet ret(g.getRing()); PolynomialSet B(g.getRing()); B.push_back(b); LexicographicTermOrder T; B.markAndScale(T); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) { ret.push_back(division(*i,B,T)); } // ret.push_back(); return ret; } PolynomialSet binomialReduce(PolynomialSet g) { PolynomialSet binomials(g.getRing()); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) if(i->numberOfTerms()==2)binomials.push_back(*i); for(PolynomialSet::const_iterator i=binomials.begin();i!=binomials.end();i++) { g=withVariablesEqual(g,*i); g.saturate(); } for(PolynomialSet::const_iterator i=binomials.begin();i!=binomials.end();i++) { g.push_back(*i); } return g; } void processSingle(PolynomialSet g, int N) { {//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PolynomialSet g2(g.getRing()); for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++) if(i->totalDegree()<20 && i->numberOfTerms()!=6 && i->numberOfTerms()<10 )g2.push_back(*i); g=g2; } AsciiPrinter P(Stderr); g.saturate(); P<numberOfTerms()!=0)G2.push_back(*i); P<<"Intersection"<=0;i--) { cerr << i << endl; g2=saturationHomog(g2,i); { PolynomialSet G=g2.polynomialRingIntersection(r3); PolynomialSet G2(G.getRing()); for(PolynomialSet::const_iterator i=G.begin();i!=G.end();i++)if(i->numberOfTerms()!=0)G2.push_back(*i); P<<"Intersection"<429)return true; if(I==41 || I==48 || I==180 || I==223 || I==235 || I==236 || I==264 || I==418 || I==419 || I==420 || I==421)return true; if(I==41 || I==48 || I==110 || I==143 || I==175 || I==180 || I==189 || I==192 || I==193 || I==198 || I==228 || I==232 || I==235 || I==236 || I==254 || I==264 || I==270 || I==298 || I==342 || I==399 || I==400 || I==418 || I==419 || I==420 || I==421 || (I==423) || (I==424) || (I==425) || (I==426) || I==427 || I==428 || I==428 || I==429)return true; if(I==22 || I==23 || I==30 || I==36 || I==54 || I==61 || I==64 || I==108 || I==149 || I==161 || I==162 || I==172 || I==173 || I==174 || I==177 || I==178 || (I==187) || I==190 || I==191 || I==194 || I==195 || I==204 || I==206 || I==207 || I==209 || I==211 || I==212 || I==213 || I==214 || I==217 || I==219 || I==222 || I==224 || (I==225) || I==230 || (I==233) || I==234 || I==241 || (I==244) || I==246 || I==249 || I==255 || I==257 || I==263 || I==271 || I==283 || I==338 || I==339 || I==345 || I==360 || I==396 || I==397 || I==398 || I==401 || I==404 || I==409 || I==410 || I==415)return true; return false; } int main() { int N=5; LpSolver::printList(Stderr); lpSetSolver("cddgmp"); if(singleOption.getValue()) { PolynomialSet g=FileParser(Stdin).parsePolynomialSetWithRing(); processSingle(g,N); return 0; } AsciiPrinter P(Stderr); // cerr<< "Simplified"< > cones=inFile.readMatrixIncidenceProperty("CONES_COMPRESSED"); // P<embeddedInto(ac.getRing())); P<<"ALL\n"< skipped; int I=cones.size()-1; for(int i=0;i::const_iterator j=cones[i].begin();j!=cones[i].end();j++) { v+=rays[*j]; if(dotLong(IntegerVector::allOnes(n),rays[*j])>=0)hasNegativeSum=true; raySubset.push_back(rays[*j]); } AsciiPrinter(Stderr)<b.getMarked().m.exponent.sum())return false; return LexicographicTermOrder()(a.getMarked().m.exponent,b.getMarked().m.exponent); } }; public: const char *helpText() { return "This program computes the union of a list of polynomial sets given as input. The polynomials must all belong to the same ring. The ring is specified on the input. After this follows the list of polynomial sets.\n"; } PolynomialSetUnionApplication(): optionSpecialMode("-s","Sort output by degree.\n") { registerOptions(); } const char *name() { return "_polynomialsetunion"; } int main() { FileParser P(Stdin); PolynomialRing r=P.parsePolynomialRing(); int c=P.nextNonBlank(); bool first=true; assert(P.isLeftBracket(c)); PolynomialSet s=P.parsePolynomialSet(r); c=P.nextNonBlank(); while(','==c || first) { PolynomialSet temp=P.parsePolynomialSet(r); // if(optionSpecialMode.getValue())temp.markAndScale(LexicographicTermOrder()); s.unionSet(temp); c=P.nextNonBlank(); first=false; } assert(P.isRightBracket(c)); if(optionSpecialMode.getValue())s.sort(PolynomialCmp()); AsciiPrinter(Stdout).printPolynomialRing(r); AsciiPrinter(Stdout).printNewLine(); AsciiPrinter(Stdout).printPolynomialSet(s); return 0; } }; static PolynomialSetUnionApplication theApplication; gfan0.6.2/src/app_supportindices.cpp0000644000175000017500000000126113122232611017066 0ustar andersanders#include "vektor.h" #include "printer.h" #include "parser.h" #include "gfanapplication.h" class SupportIndicesApplication : public GFanApplication { public: bool includeInDefaultInstallation() { return false; } SupportIndicesApplication() { registerOptions(); } const char *name() { return "_supportindices"; } int main() { FileParser P(Stdin); IntegerVector v=P.parseIntegerVector(); for(int i=0;i #include #include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "polyhedralcone.h" #include "gfanapplication.h" #include "saturation.h" #include "field_rationals.h" #include "field_zmodpz.h" #include "field_rationalfunctions.h" #include "symmetry.h" #include "linalg.h" #include "fieldlp.h" #include "integer.h" #include "polynomialgcd.h" #include "packedmonomial.h" #include "gfanlib_zcone.h" #include "gfanlib_tableau.h" #include "gfanlib_circuittableint.h" #include "lll.h" using namespace gfan; template class gfan::Vector; template class gfan::Vector; template class gfan::Matrix; template class gfan::Matrix; class TestApplication : public GFanApplication { StringOption testSuiteFolderOption; StringOption executableOption; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This runs the test suite and checks against the stored result. If no result exists, it is generated.\n"; } TestApplication(): testSuiteFolderOption("--suite","Specify the folder which contains the test suite.","testsuite"), executableOption("--gfan","Specify name of gfan executable to test.","./gfan") { registerOptions(); } const char *name() { return "_test"; } int testGCD() { PolynomialRing r=StringParser("Q[p126,p125,p124,p123,p027,p026,p025,p024,p023,p017,p016,p015,p014,p013,p012]").parsePolynomialRing(); // Crashes (when linked with Singular) // Polynomial p=StringParser("-p126*p027*p026*p015^2+p125*p026*p025*p017*p016-p125*p026^2*p017*p015-p125*p027*p025*p016^2+p125*p027*p026*p016*p015-p126*p025^2*p017*p016+p126*p026*p025*p017*p015+p126*p027*p025*p016*p015").parsePolynomial(r); // Polynomial q=StringParser("p126*p027*p026*p025*p016*p015*p014-p124*p026*p025^2*p017*p016^2+2*p124*p026^2*p025*p017*p016*p015-p124*p026^3*p017*p015^2+p124*p027*p025^2*p016^3-2*p124*p027*p026*p025*p016^2*p015+p124*p027*p026^2*p016*p015^2+p125*p026*p025*p024*p017*p016^2-p125*p026^2*p024*p017*p016*p015-p125*p026^2*p025*p017*p016*p014+p125*p026^3*p017*p015*p014-p125*p027*p025*p024*p016^3+p125*p027*p026*p024*p016^2*p015+p125*p027*p026*p025*p016^2*p014-p125*p027*p026^2*p016*p015*p014-p126*p026*p025*p024*p017*p016*p015+p126*p026*p025^2*p017*p016*p014+p126*p026^2*p024*p017*p015^2-p126*p026^2*p025*p017*p015*p014+p126*p027*p025*p024*p016^2*p015-p126*p027*p025^2*p016^2*p014-p126*p027*p026*p024*p016*p015^2").parsePolynomial(r); // Crashes (even when not linked to Singular) Polynomial p=StringParser("-p126*p027*p026*p015^2*p014+p124*p025^2*p017*p016^2-2*p124*p026*p025*p017*p016*p015+p124*p026^2*p017*p015^2+p125*p026*p025*p017*p016*p014-p125*p026^2*p017*p015*p014-p125*p027*p025*p016^2*p014+p125*p027*p026*p016*p015*p014-p126*p025^2*p017*p016*p014+p126*p026*p025*p017*p015*p014+p126*p027*p025*p016*p015*p014").parsePolynomial(r); Polynomial q=StringParser("p126*p027*p026*p025*p016*p015*p014-p124*p026*p025^2*p017*p016^2+2*p124*p026^2*p025*p017*p016*p015-p124*p026^3*p017*p015^2+p124*p027*p025^2*p016^3-2*p124*p027*p026*p025*p016^2*p015+p124*p027*p026^2*p016*p015^2+p125*p026*p025*p024*p017*p016^2-p125*p026^2*p024*p017*p016*p015-p125*p026^2*p025*p017*p016*p014+p125*p026^3*p017*p015*p014-p125*p027*p025*p024*p016^3+p125*p027*p026*p024*p016^2*p015+p125*p027*p026*p025*p016^2*p014-p125*p027*p026^2*p016*p015*p014-p126*p026*p025*p024*p017*p016*p015+p126*p026*p025^2*p017*p016*p014+p126*p026^2*p024*p017*p015^2-p126*p026^2*p025*p017*p015*p014+p126*p027*p025*p024*p016^2*p015-p126*p027*p025^2*p016^2*p014-p126*p027*p026*p024*p016*p015^2").parsePolynomial(r); // Finds factor // Polynomial p=StringParser("-p027*p026*p016*p015-p026*p025*p017*p016+p026^2*p017*p015+p027*p025*p016^2").parsePolynomial(r); // Polynomial q=StringParser("p126*p027*p025*p016*p014+p124*p026*p025*p017*p016-p124*p026^2*p017*p015-p124*p027*p025*p016^2+p124*p027*p026*p016*p015-p125*p026*p024*p017*p016+p125*p026^2*p017*p014+p125*p027*p024*p016^2-p125*p027*p026*p016*p014+p126*p026*p024*p017*p015-p126*p026*p025*p017*p014-p126*p027*p024*p016*p015").parsePolynomial(r); // Finds only 1 as factor // Polynomial p=StringParser("-p026*p015+p025*p016").parsePolynomial(r); // Polynomial q=StringParser("p126*p027*p025*p016*p014+p124*p026*p025*p017*p016-p124*p026^2*p017*p015-p124*p027*p025*p016^2+p124*p027*p026*p016*p015-p125*p026*p024*p017*p016+p125*p026^2*p017*p014+p125*p027*p024*p016^2-p125*p027*p026*p016*p014+p126*p026*p024*p017*p015-p126*p026*p025*p017*p014-p126*p027*p024*p016*p015").parsePolynomial(r); Polynomial g=polynomialGCD(p,q); debug< M(3,5); M[0][0]=0;M[0][1]=0;M[0][2]=2;M[0][3]=2;M[0][4]=1; M[1][0]=1;M[1][1]=0;M[1][2]=3;M[1][3]=2;M[1][4]=1; M[2][0]=2;M[2][1]=0;M[2][2]=2;M[2][3]=0;M[2][4]=0; gfan::TableauSolver M2(M,true); M2.coneInfo(); return 0; } { gfan::Matrix M(2,2); M[0][0]=2; M[1][0]=1; M[1][1]=2; M[0][1]=2; gfan::Tableau M2(M,true); debug< M(3,6); M[0][0]=1; M[1][0]=0; M[2][0]=1; M[0][1]=0; M[1][1]=1; M[2][1]=1; M[0][2]=2; M[1][2]=2; M[2][2]=1; M[0][3]=5; M[1][3]=1; M[2][3]=1; M[0][4]=4; M[1][4]=0; M[2][4]=1; M[0][5]=3; M[1][5]=3; M[2][5]=3; gfan::TableauSolver M2(M,true); debug<"+outputName; cerr<<"Running command:\""< subFolderNames() { #define tempName "GfAnTeMpTeStS" char command[256]; int err=system("rm " tempName); err=0;//Having err!=0 above is probably not at mistake. Rather the file did not exist. sprintf(command,"ls %s>" tempName ,testSuiteFolderOption.getValue()); err|=system(command); assert(err==0); list ret; FILE *f=fopen(tempName,"r"); assert(f); char name[256]; while(fgets(name,255,f)) { for(int i=0;i<255 && name[i];i++)if(name[i]=='\n'){name[i]=0;} if(name[0]>='0' && name[0]<='9')ret.push_back(string(testSuiteFolderOption.getValue())+"/"+string(name)); } fclose(f); return ret; } int main() { // lpRationalFunctionTest(); // testRationalFunctionField(); // packedTest();return 0; // return testIntegers(); // return testGCD(); // return testGfanLib(); // return testPolynomialGCD(); // return testLLL(); list testFolders=subFolderNames(); list testList; for(list::const_iterator i=testFolders.begin();i!=testFolders.end();i++) { testList.push_back(TestCase(*i)); } cout<<"Number of tests to perform "< failed; int good=0; int bad=0; for(list::iterator i=testList.begin();i!=testList.end();i++) if(i->perform(executableOption.getValue())) good++; else { bad++; failed.push_back(i->folder); } cout<<"\n"; if(!failed.empty()) { cout<<"Failed tests:\n-------------\n"; for(list::iterator i=failed.begin();i!=failed.end();i++) { cout<<*i<<" FAILED!\n"; } } cout<<"Number of succesful tests "< > convertTuple(std::vector const &tuple) { vector > ret; ret.reserve(tuple.size()); for(int i=0;i a(tuple[i].getHeight(),tuple[i].getWidth()); for(int j=0;j const &tuple, int nthreads, int steps) { //Zero-dimensional volumes are obtained by taking determinants of 0x0 matrices. Such determinants are 1. Hence the volume polynomial is constant 1. The coefficient of the product of the variables is 1. //Alternative explanation. A generic polynomial system with zero variables has exactly 1 solution. if(tuple.size()==0){return Integer(1);} // For now, let's make in an error to pass the wrong number of polytopes. Of course we could define the // mixed volume to be 0 in that case, but the code calling will almost certainly be wrong. It is safer to throw. // for(const auto &x:tuple) // Range based for is not supported until gcc 4.6/ for(auto x=tuple.begin();x!=tuple.end();x++) if(x->getHeight()!=tuple.size()) {throw MVAmbientDimensionMismatch;} std::vector > tuple2=convertTuple(tuple); // assert(tuple2.size()); typedef SpecializedRTraverser MySpecializedRTraverser; vector T1; int N=nthreads; if(N==0)N=1;// Even if we do not parallelize, we still need one traverser. T1.reserve(N); vector I; for(int i=0;iaborting; if(aborted) { throw MVExceptionRethrow; } mvtyp::Double total; int totalSteps=0; for(int i=0;imixedVolume.toString()<<"Steps:"<<((MySpecializedRTraverser*)(I[i]))->numberOfExpensiveSteps<<"\n"; //debug<<((SpecializedMTraverser*)(I[i]))->T.counter; total.addWithOverflowCheck(((MySpecializedRTraverser*)(I[i]))->mixedVolume); totalSteps+=((MySpecializedRTraverser*)(I[i]))->numberOfExpensiveSteps; } // debug<<"Total:"<<(int)total.v<<"\n"; // debug<<"Totalsteps:"< cyclic(int n) { vector ret; for(int i=1;i noon(int n) { vector ret; for(int i=0;i chandra(int n) { vector ret; for(int i=0;i katsura(int n) { n++; vector ret; for(int i=0;i0 ? (n-1-y-i) : -(n-1-y-i)][y]+=1; } m[i][m.getWidth()-1]=1; ret.push_back(m); } ret.push_back(combineLeftRight(IntMatrix::identity(n),IntMatrix(n,1))); return ret; } vector gaukwa(int n) { vector ret; for(int i=0;i<2*n;i++) ret.push_back(combineLeftRight(combineOnTop(IntMatrix::identity(n),i*IntMatrix::identity(n)),IntMatrix(2*n,1))); return ret; } vector eco(int n) { vector ret; for(int i=0;iprint(); fprintf(Stderr,"}\n"); } XFig::Polygon XFig::intersect(const Polygon &polygon, const Point &normal) { // fprintf(Stderr,"intersect input:\n"); // printPolygon(polygon); Polygon ret; Polygon temp; Polygon::const_iterator i=polygon.begin(); while(i!=polygon.end()) { if(normal.isInside(*i))break; i++; } if(i==polygon.end())return ret; for(Polygon::const_iterator j=i;j!=polygon.end();j++) temp.push_back(*j); for(Polygon::const_iterator j=polygon.begin();j!=i;j++) temp.push_back(*j); temp.push_back(*i); // fprintf(Stderr,"intersect temp:\n"); // printPolygon(temp); Polygon::const_iterator j=temp.begin(); while(j!=temp.end()) { Point last(0,0,0); while(j!=temp.end()&&normal.isInside(*j)) { //fprintf(Stderr,"inside:"); //j->print(); last=*j; ret.push_back(*j); j++; } if(j==temp.end())break; Point leaving=normal.intersect(last,*j); while(!normal.isInside(*j)) { //fprintf(Stderr,"outside:"); //j->print(); last=*j; j++; } Point entering=normal.intersect(last,*j); ret.push_back(leaving); ret.push_back(entering); ret.push_back(*j); j++; } ret.pop_back(); // fprintf(Stderr,"intersect ret:\n"); // printPolygon(ret); return ret; } void XFig::kickPoint(const Point &p, int mode) { // fprintf(file," %i %i",(int)(p.x*10000),(int)(p.y*10000)); switch(mode) { case 0: { float invSqrt2=0.707106781; float invSqrt6=0.40824829; fprintf(f," %i %i",(int)((invSqrt2+invSqrt2*p.x-invSqrt2*p.y)*10000+offsetX),(int)((2*invSqrt6+invSqrt6*p.x+invSqrt6*p.y-2*invSqrt6*p.z)*10000+offsetY)); } break; case 1: { fprintf(f," %i %i",(int)((p.x)*10000+offsetX),(int)((p.y)*10000+offsetY)); } } } void XFig::drawPolygon(const Polygon &vertices, int mode) { if(vertices.size()) { fprintf(f,"2 3 0 1 0 %i 50 0 25 0.000 0 0 -1 0 0 %i\n ",7,(int)vertices.size()+1); for(Polygon::const_iterator i=vertices.begin();i!=vertices.end();i++) kickPoint(*i,mode); kickPoint(*vertices.begin(),mode); fprintf(f,"\n"); } fflush(f); } gfan0.6.2/src/determinantpoly.cpp0000644000175000017500000002575013122232611016402 0ustar andersanders#include "determinantpoly.h" #include #include "printer.h" #include "buchberger.h" #include "wallideal.h" #include "termorder.h" #include "tropical2.h" #include "tropicaldeterminant.h" #include "log.h" using namespace std; static list interval(int n, bool sqrt) { list ret; for(int i=0;((sqrt)?i*i:i) forms; PolyMatrixEntry(Polynomial const &p_, IntegerVector const &w): p(p_), isZero(p_.isZero()) { if(p.isZero()) { maxDegree=td_minusInfinity; mminDegree=td_minusInfinity; return; } maxDegree=p_.degree(w); mminDegree=p_.degree(-w); // debug<first.exponent,w)+mminDegree]+=Term(i->second,i->first); } } }; list::iterator indexOfSparsestRow(list &rows, list const &columns, int &chosenRowIteratorIndex) { list::iterator ret=rows.end(); int bestNumberOfZeros=-1; int I=0; for(list::iterator i=rows.begin();i!=rows.end();i++,I++) { int numberOfZeros=0; for(list::const_iterator j=columns.begin();j!=columns.end();j++)numberOfZeros+=data[*i][*j].isZero; if(numberOfZeros>bestNumberOfZeros) { bestNumberOfZeros=numberOfZeros; ret=i; chosenRowIteratorIndex=I; } } // cerr<<":"< > data; PolynomialRing theRing; //constructor for Jacobi matrix PolyMatrix(PolynomialSet const &generators, IntegerVector const &w, bool takeDerivatives, int numberOfDVariables=-1): theRing(generators.getRing()) { if(takeDerivatives) { int n=generators.size(); if(numberOfDVariables==-1)numberOfDVariables=n; PolynomialSet::const_iterator I=generators.begin(); for(int i=0;i row; for(int j=0;jderivative(j),w)); data.push_back(row); I++; } } else { int n=generators.size(); for(int i=0;i=n){n=i;break;}assert(n*n==generators.size()); PolynomialSet::const_iterator I=generators.begin(); for(int i=0;i row; for(int j=0;j l) { cerr<<"{"; for(list::const_iterator i=l.begin();i!=l.end();i++) cerr<<*i<<","; cerr<<"}\n"; } IntegerMatrix subTropicalMatrix(bool max, list const &rows, list const &columns) { IntegerMatrix ret(rows.size(),columns.size()); list::const_iterator I=rows.begin(); for(int i=0;i::const_iterator J=columns.begin(); for(int j=0;j rows, list columns, int degree, int level) { Polynomial ret(theRing); IntegerMatrix matMax=subTropicalMatrix(true,rows,columns); IntegerMatrix matMMin=subTropicalMatrix(false,rows,columns); /* if(level==0) { debug<maxDet)return Polynomial(theRing); if(-degree>mminDet)return Polynomial(theRing); if(rows.size()==1) { if(data[rows.front()][columns.front()].isZero)return Polynomial(theRing); // cerr<::iterator chosenRowIterator=indexOfSparsestRow(rows, columns, chosenRowIteratorIndex);//rows.begin(); int chosenrow=*chosenRowIterator; { list::iterator temp=chosenRowIterator;temp++; rows.erase(chosenRowIterator); //no need to update rows afterwards since it is stored on the stack } /* if(level==0)cerr<<"-"<::iterator i=columns.begin();i!=columns.end();i++) { int chosencol=*i; if(!data[chosenrow][chosencol].isZero) { list::iterator temp=i;temp++; columns.erase(i); i=temp; // int D=degree+1; // if(data[chosenrow][chosencol].forms.size() rows=interval(data.size(),0); list columns=interval(data.size(),0); IntegerMatrix matMax=subTropicalMatrix(true,rows,columns); IntegerMatrix matMMin=subTropicalMatrix(false,rows,columns); int maxDet=tropicalDeterminant(matMax); int mminDet=tropicalDeterminant(matMMin); cerr<<"Max"<=-mminDet;d--) { log1 debug<<"Computing degree "< toIndexed(list const &l) { list ret; int a=0; for(list::const_iterator i=l.begin();i!=l.end();i++,a++)if(*i)ret.push_back(a); return ret; } PolynomialSet jacobiMinors(PolynomialSet const &g, int codim) { IntegerVector w(g.getRing().getNumberOfVariables()); PolyMatrix m(g,w,true,w.size()); //log1 m.print(); PolynomialSet ret(g.getRing()); if(codim<=g.size())if(codim<=w.size()) { list rows; for(int i=0;i cols; for(int i=0;i #include using namespace std; class Graph{ int n; bool isDirected; class Edge{ public: int a,b; Edge(int a_, int b_): a(a_), b(b_) { } bool operator<(const Edge &e)const { return (a edges; public: Graph(int numberOfVertices, bool isDirected_=false): n(numberOfVertices), isDirected(isDirected_) { } void addEdge(int a, int b) { edges.insert(Edge(a,b)); } int diameter(int *timesAttained=0)const; string toString()const; }; #endif gfan0.6.2/src/app_volume.cpp0000644000175000017500000000235513122232611015327 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "lp.h" #include "gfanapplication.h" #include "polyhedralcone.h" #include "polymakefile.h" #include "determinant.h" #include "subspace.h" #include "triangulation.h" #include "polyhedralfan.h" #include "symmetry.h" class VolumeApplication : public GFanApplication { StringOption inputOption; public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program computes the volume of a polyhedral fan intersected with the standard cube with edge length 2 centered at the origin. This is done for each dimension\n"; } VolumeApplication(): inputOption("-i","Specify the name of the input file.","polymake.out") { registerOptions(); } const char *name() { return "_volume"; } int main() { PolyhedralFan F=PolyhedralFan::readFan(inputOption.getValue(),true,0,0,0,false/*true*/); IntegerVectorList generators=FileParser(Stdin).parseIntegerVectorList(); SymmetryGroup s(F.getAmbientDimension()); s.computeClosure(generators); int d=F.getMaxDimension(); cout << F.volume(d,&s).toString(); return 0; } }; static VolumeApplication theApplication; gfan0.6.2/src/term.h0000644000175000017500000000076513122232611013577 0ustar andersanders#ifndef TERM_H_INCLUDED #define TERM_H_INCLUDED #include "field.h" #include "monomial.h" #include "polynomialring.h" class Term { PolynomialRing theRing; public: Monomial m; FieldElement c; Term(PolynomialRing const &r):theRing(r),m(r),c(r.getField()){}; Term(FieldElement const &c_, Monomial const &m_); void operator*=(const Term &t); PolynomialRing const &getRing()const{return theRing;} Term operator/(const Term &b)const; Term operator/(const Monomial &b)const; }; #endif gfan0.6.2/src/tropicalmap.cpp0000644000175000017500000000575013122232611015475 0ustar andersanders#include "tropicalmap.h" #include using namespace std; #include "log.h" static IntegerVectorList vectorImages(PolynomialSet const &polynomialMap, IntegerVectorList const &l) { int d=polynomialMap.size(); IntegerVectorList ret; for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) { IntegerVector v(d); int j=0; for(PolynomialSet::const_iterator J=polynomialMap.begin();J!=polynomialMap.end();J++,j++) v[j]=J->degree(*i); ret.push_back(v); } return ret; } PolyhedralCone imageOfConeUnderTropicalMap(PolynomialSet const &polynomialMap, PolyhedralCone const &cone) { int d=polynomialMap.size(); IntegerVectorList linealitySpace=cone.linealitySpace().dualCone().getEquations(); IntegerVectorList rays=cone.extremeRays(); PolyhedralCone C=PolyhedralCone::givenByRays(vectorImages(polynomialMap,rays),vectorImages(polynomialMap,linealitySpace),d); C.canonicalize(); return C; } PolyhedralFan imageOfTropicalMap(PolynomialSet const &polynomialMap, PolyhedralFan domain) { for(PolynomialSet::const_iterator i=polynomialMap.begin();i!=polynomialMap.end();i++) { domain=refinement(domain,PolyhedralFan::normalFanOfNewtonPolytope(*i)); } return imageOfTropicalMapGivenLinearityCones(polynomialMap,domain); } PolyhedralFan imageOfTropicalMapGivenLinearityCones(PolynomialSet const &polynomialMap, PolyhedralFan linearityCones) { int d=polynomialMap.size(); PolyhedralFan ret(d); /* We first put the images of the cones of the domain into the imageCones set. This automatically removes duplicates. */ set imageCones; for(PolyhedralFan::coneIterator i=linearityCones.conesBegin();i!=linearityCones.conesEnd();i++) imageCones.insert(imageOfConeUnderTropicalMap(polynomialMap,*i)); log0 cerr << "Number of image cones "<::iterator i=imageCones.begin();i!=imageCones.end();) { bool isContainedInOther=false; IntegerVectorList linealitySpace=i->linealitySpace().dualCone().getEquations(); IntegerVectorList rays=i->extremeRays(); for(set::iterator j=imageCones.begin();j!=imageCones.end();j++) { if(j!=i) if(j->contains(rays) && j->contains(linealitySpace)) { isContainedInOther=true;break; } } if(isContainedInOther) { set::iterator k=i; i++; imageCones.erase(k); } else i++; } log0 cerr << "Number of image cones "<::const_iterator i=imageCones.begin();i!=imageCones.end();i++,I++) { // if(I<31)continue; // if(I==32)break; // AsciiPrinter P(Stderr); // P< using namespace std; class Triangulation{ public: /** This class represents an oriented simplex. The simplex is stored as the list of indices of the vertices it contains together with an orientation flag which is either +1 or -1. The ordering of the indices is important. The list of indices can be sorted by calling coneSort(). This will change the orientation flag appropriately. */ class Cone : public list { public: int changeSign; Cone(): changeSign(1) { } }; /** The class Cone2 is just a short name for a list of integers. */ typedef list Cone2; // private: static int coneDim(Cone2 const &c, IntegerMatrix const &rays); static IntegerVectorList coneToVectorList(Cone2 const &c, IntegerMatrix const &rays); static void coneSort(Cone &c); static Cone firstSimplex(Cone const &c, IntegerMatrix const &rays); static IntegerVectorList coneComplement(Cone c, IntegerMatrix const &rays);//returns generators of orth. complement. static int signVisible(int v, Cone const &c, IntegerVectorList const &complement, IntegerMatrix const &rays); static list triangulateRek(int d, Cone2 const &c, IntegerMatrix const &rays, bool revlex=false, bool ignoreContainedRays=false); public: /** Computes a triangulation of the rows of the matrix rays indexed by c. The tringulation is lexicographic unless revlex is set in which case a reverse lexicographic triangulation is computed. Notice that a reverselex triangulation does not always exist. CHOOSING REVLEX DOES NOT WORK YET. */ static list triangulate(Cone2 c, IntegerMatrix const &rays, bool revlex=false); //computes a lexicographic triangulation static list triangulate(IntegerMatrix const &rays, bool revlex=false); //computes a lexicographic triangulation static list boundary(list cones); static IntegerVectorList normals(IntegerMatrix &rays); /** Takes a Cone list and turns it into a vector of lists of integers, thereby remove the orientation flag stored in the Cones. */ static vector > removeOrientation(list const &triangulation); /** Takes a Cone vector and turns it into a vector of lists of integers, thereby remove the orientation flag stored in the Cones. */ static vector > removeOrientation(vector const &triangulation); }; #endif gfan0.6.2/src/traverser_bsptree.cpp0000644000175000017500000000610213122232611016713 0ustar andersanders/* * traverser_bsptree.cpp * * Created on: Aug 23, 2011 * Author: anders */ #include "traverser_bsptree.h" #include "parser.h" BSPTreeTraverser::BSPTreeTraverser(int n_, BSPTree const & tree_): ConeTraverser(n_), tree(tree_) { IntegerVectorList omega=IntegerMatrix::identity(n).getRows(); theCone=tree.region(omega); theCone.canonicalize(); } void BSPTreeTraverser::changeCone(IntegerVector const &ridgeVector, IntegerVector const &rayVector) { IntegerVectorList omega; omega.push_back(ridgeVector); omega.push_back(rayVector); //debug<<"OMEGA"<>old; D(theCone); debug>>theCone; assert(0); }*/ IntegerVector lastFacetVector=ridgeVector; IntegerVectorList temp=old.faceContaining(ridgeVector).getEquations(); assert(temp.size()==1); IntegerVector lastFlipDirection=temp.front(); if(dotLong(lastFlipDirection,rayVector)<0)lastFlipDirection=-lastFlipDirection; // debug<n?n:d; for(int r=1;r<=min;r++) { PolynomialRing R(Q,matrixVariableNames("m",d,n)); PolynomialSet p=minors(R,r,d,n,false,false); if(optionKapranov.getValue()) { WeightReverseLexicographicTermOrder T(w); buchberger(&p,T); } PolynomialSet q=initialForms(p,w); bool containsMonomial=false; for(PolynomialSet::const_iterator i=q.begin();i!=q.end();i++) if(i->isMonomial()) { containsMonomial=true; break; } fprintf(Stderr,"%ix%i picks monomial: %s %i\n",r,r,containsMonomial?"true, meaning that rank is >":"false, meaning that rank is <=",r-1); if(!containsMonomial) { theRank=r-1; break; } } if(theRank==-1) theRank=min; AsciiPrinter(Stdout).printInteger(theRank); AsciiPrinter(Stdout).printNewLine(); return 0; } }; static TropicalRankApplication theApplication; gfan0.6.2/src/graph.cpp0000644000175000017500000000233613122232611014260 0ustar andersanders#include "graph.h" #include #include "matrix.h" int Graph::diameter(int *timesAttained)const { IntegerMatrix A(n,n); for(int i=0;i::const_iterator i=edges.begin();i!=edges.end();i++) { A[i->a][i->b]=1; if(!isDirected)A[i->b][i->a]=1; } for(int i=0;iret) { ret=A[i][j]; timesAttained2=0; } if(A[i][j]==ret) timesAttained2++; } if(timesAttained)*timesAttained=timesAttained2; return ret; } string Graph::toString()const { stringstream ret; ret<<"("<::const_iterator i=edges.begin();i!=edges.end();i++) { if(i!=edges.begin())ret<<","<a<<","<b<<")"< data; public: /** Adds a facet orbit. The list of vectors is the canonoical symmetry (w.r.t. symmetries of the ridge) invariant interior points of its ridges. Futhermore, these should be unique orbit representatives rather than just vectors. */ void insertFacetOrbit(IntegerVectorList const &ridges); /* BE CAREFUL WHEN MAKING CONCLUSIONS - THIS ROUINE DOES NOT SUPPORT SYMMETRY. */ bool isConnected()const; }; gfan0.6.2/src/polyhedralcone.cpp0000644000175000017500000011742313122232611016173 0ustar andersanders#include "polyhedralcone.h" #include "lp.h" #include "subspace.h" #include "symmetry.h" #include "polymakefile.h" #include "wallideal.h" #include #include "triangulation.h" #include "triangulation2.h" #include "linalg.h" #include "linalgfloat.h" #include "continuedfractions.h" #include "polyhedralfan.h" #include "log.h" static bool hasFullRowRank(IntegerVectorList const &l)//The tests where this is used can actually be improved by also using the known equations { int s=l.size(); if(s==0)return true; if(s>l.front().size())return false; return ::rank(rowsToIntegerMatrix(l))==s; } //-------------------------------- // PolyhedralCone //-------------------------------- static bool compareIntegerLists(IntegerVectorList const &a, IntegerVectorList const &b) { assert(a.size()==b.size()); IntegerVectorList::const_iterator B=b.begin(); for(IntegerVectorList::const_iterator A=a.begin();A!=a.end();A++) { if(LexicographicTermOrder()(*A,*B))return true; if(LexicographicTermOrder()(*B,*A))return false; B++; } return false; } bool operator<(PolyhedralCone const &a, PolyhedralCone const &b) { assert(a.state>=3); assert(b.state>=3); if(a.dimension()>b.dimension())return true;//INVERTED if(a.dimension()b.equations.size())return false; if(a.nb.n)return false; if(a.inequalities.size()b.inequalities.size())return false; if(compareIntegerLists(a.equations,b.equations))return true; if(compareIntegerLists(b.equations,a.equations))return false; if(compareIntegerLists(a.inequalities,b.inequalities))return true; if(compareIntegerLists(b.inequalities,a.inequalities))return false; return false; } bool operator!=(PolyhedralCone const &a, PolyhedralCone const &b) { return (a1)//there can be no implied equation unless we have at least two inequalities if(!hasFullRowRank(inequalities))//the inequalities have been moved to an appropriate subspace above, so now we can easily check if the dual cone is simplicial removeRedundantRows(&inequalities,&equations,false); //log0 cerr<<"Number of inequalities: "<=2) && !(preassumptions&PCP_facetsKnown)) { // halfSpaces.sort(); // AsciiPrinter(Stderr).printVectorList(halfSpaces); if(inequalities.size()>25) // if(0) { IntegerVectorList h1; IntegerVectorList h2; bool a=false; for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { if(a) h1.push_back(*i); else h2.push_back(*i); a=!a; } PolyhedralCone c1(h1,equations); PolyhedralCone c2(h2,equations); c1.ensureStateAsMinimum(2); c2.ensureStateAsMinimum(2); inequalities=c1.inequalities; for(IntegerVectorList::const_iterator i=c2.inequalities.begin();i!=c2.inequalities.end();i++) inequalities.push_back(*i); } // fprintf(Stderr,"Number half spaces: %i, number of equations: %i\n",halfSpaces.size(),equations.size()); if(equations.size()) { FieldMatrix equationSpace=integerMatrixToFieldMatrix(rowsToIntegerMatrix(equations,n),Q); equationSpace.reduce(); IntegerVectorList halfSpaces2; for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { halfSpaces2.push_back(equationSpace.canonicalize(integerVectorToFieldVector(*i,Q)).primitive()); } if(hasFullRowRank(halfSpaces2))goto noFallBack;//the inequalities have been moved to an appropriate subspace above, so now we can easily check if the dual cone is simplicial for(IntegerVectorList::const_iterator i=halfSpaces2.begin();i!=halfSpaces2.end();i++) if((i->max()>1000) || (i->min()<-1000))goto fallBack;//more overflows caught in lp_cdd. inequalities=fastNormals(halfSpaces2); goto noFallBack; fallBack: removeRedundantRows(&inequalities,&equations,true); noFallBack:; } else inequalities=fastNormals(inequalities); // fprintf(Stderr,"done\n"); } if((state<3) && (s>=3)) { // fprintf(Stderr,"Number half spaces: %i, number of equations: %i\n",halfSpaces.size(),equations.size()); // log1 fprintf(Stderr,"Computing subspace...\n"); Subspace v(equations,n); equations=v.getRepresentation(); // log1 fprintf(Stderr,"...done computing subspace.\n"); for(IntegerVectorList::iterator i=inequalities.begin();i!=inequalities.end();i++) { *i=v.canonicalizeVector(*i); } inequalities.sort(); //fprintf(Stderr,"done\n"); } state=s; } void PolyhedralCone::canonicalize() { ensureStateAsMinimum(3); } void PolyhedralCone::findFacets() { ensureStateAsMinimum(2); } void PolyhedralCone::findImpliedEquations() { ensureStateAsMinimum(1); } /*PolyhedralCone::PolyhedralCone(IntegerVectorList const &halfSpaces_, IntegerVectorList const &equations_, int ambientDimension, int state): inequalities(halfSpaces_), equations(equations_), state(0), multiplicity(1), n(ambientDimension) { this->state=state; } */ PolyhedralCone::PolyhedralCone(int ambientDimension): n(ambientDimension), state(1), preassumptions(PCP_impliedEquationsKnown|PCP_facetsKnown), multiplicity(1), haveExtremeRaysBeenCached(false), haveGeneratorsOfLinealitySpaceBeenCached(false) { } PolyhedralCone::PolyhedralCone(IntegerVectorList const &halfSpaces_, IntegerVectorList const &equations_, int ambientDimension, int preassumptions_): //PolyhedralCone::PolyhedralCone(IntegerVectorList const &halfSpaces_, IntegerVectorList const &equations_, int ambientDimension): inequalities(halfSpaces_), equations(equations_), // equations(subsetBasis(equations_)), state(0), preassumptions(preassumptions_), multiplicity(1), haveExtremeRaysBeenCached(false), haveGeneratorsOfLinealitySpaceBeenCached(false) { n=ambientDimension; if(n==-1) { if(!halfSpaces_.empty()) n=halfSpaces_.begin()->size(); else if(!equations_.empty()) n=equations_.begin()->size(); else { assert(0); } } for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { assert(i->size()==n); } for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++) { /*AsciiPrinter P(Stderr); P.printString("FJDSKFJA\n"); P.printVector(*i); */ assert(i->size()==n); } ensureStateAsMinimum(1); // computeAndReduceLinearitySpace(); } IntegerVector PolyhedralCone::getRelativeInteriorPoint()const { // ensureStateAsMinimum(1); assert(state>=1); IntegerVector ret; IntegerVectorList g=equations; int numberOfEqualities=g.size(); g.insert(g.end(),inequalities.begin(),inequalities.end()); IntegerVector equalitySet(g.size()); for(int i=0;i0)) { fprintf(Stderr,"PolyhedralCone::relativeInteriorPoint() : halfSpaces not reduced or mistake in cdd interface!!!\n"); } } return ret; } IntegerVectorList const &PolyhedralCone::getHalfSpaces()const { return inequalities; } const IntegerVectorList &PolyhedralCone::getEquations()const { assert(state>=1); return equations; } const IntegerVectorList &PolyhedralCone::getImpliedEquations()const { const_cast(this)->findImpliedEquations(); return equations; } IntegerVectorList PolyhedralCone::generatorsOfSpan()const { assert(isInStateMinimum(1)); IntegerVectorList empty; PolyhedralCone temp(empty,getEquations(),n); return temp.dualCone().getEquations(); } IntegerVectorList PolyhedralCone::generatorsOfLinealitySpace()const { if(haveGeneratorsOfLinealitySpaceBeenCached)return cachedGeneratorsOfLinealitySpace; IntegerVectorList l=equations; l.insert(l.end(),inequalities.begin(),inequalities.end()); FieldMatrix L=integerMatrixToFieldMatrix(rowsToIntegerMatrix(l,ambientDimension()),Q); cachedGeneratorsOfLinealitySpace=fieldMatrixToIntegerMatrixPrimitive(L.reduceAndComputeKernel()).getRows(); // return linealitySpace().generatorsOfSpan(); haveGeneratorsOfLinealitySpaceBeenCached=true; return cachedGeneratorsOfLinealitySpace; } int PolyhedralCone::ambientDimension()const { return n; } int PolyhedralCone::codimension()const { return ambientDimension()-dimension(); // return getEquations().size(); } int PolyhedralCone::dimension()const { assert(state>=1); // ensureStateAsMinimum(1); return ambientDimension()-equations.size(); } bool PolyhedralCone::isZero()const { return dimension()==0; } bool PolyhedralCone::isFullSpace()const { for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) if(!i->isZero())return false; for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++) if(!i->isZero())return false; return true; } PolyhedralCone intersection(const PolyhedralCone &a, const PolyhedralCone &b) { if(a.ambientDimension()!=b.ambientDimension()) { debug<=s; } int PolyhedralCone::getState()const { return state; } void PolyhedralCone::print(class Printer *p, bool xml)const { if(0) { p->printString("Printing PolyhedralCone"); p->printNewLine(); p->printString("Ambient dimension: "); p->printInteger(n); p->printNewLine(); if(isInStateMinimum(1)) { p->printString("Dimension: "); p->printInteger(dimension()); p->printNewLine(); } p->printString("Linearity space:"); // p->printNewLine(); p->printVectorList(equations); p->printString("Inequalities:"); p->printVectorList(inequalities); p->printString("Relative interior point:\n"); p->printVector(getRelativeInteriorPoint()); p->printNewLine(); p->printString("Done printing PolyhedralCone."); p->printNewLine(); } else { PolymakeFile polymakeFile; polymakeFile.create("NONAME","PolyhedralCone","PolyhedralCone",xml); polymakeFile.writeCardinalProperty("AMBIENT_DIM",n); if(isInStateMinimum(1)) { polymakeFile.writeCardinalProperty("DIM",dimension()); //need to check that the following is done correctly // polymakeFile.writeCardinalProperty("LINEALITY_DIM",dimensionOfLinealitySpace()); polymakeFile.writeMatrixProperty("IMPLIED_EQUATIONS",rowsToIntegerMatrix(equations,n)); } polymakeFile.writeCardinalProperty("LINEALITY_DIM",dimensionOfLinealitySpace()); polymakeFile.writeMatrixProperty("LINEALITY_SPACE",rowsToIntegerMatrix(linealitySpace().dualCone().getEquations(),n)); if(isInStateMinimum(2)) polymakeFile.writeMatrixProperty("FACETS",rowsToIntegerMatrix(inequalities,n)); else polymakeFile.writeMatrixProperty("INEQUALITIES",rowsToIntegerMatrix(inequalities,n)); polymakeFile.writeCardinalVectorProperty("RELATIVE_INTERIOR_POINT",getRelativeInteriorPoint()); stringstream s; polymakeFile.writeStream(s); string S=s.str(); p->printString(S.c_str()); } } void PolyhedralCone::printAsFan(class Printer *p)const { IntegerVectorList empty; PolyhedralCone C2=*this; C2.canonicalize(); PolyhedralFan F(n);F.insert(C2); F.printWithIndices(p,FPF_default); } static IntegerVector dehomogenize(IntegerVector const &v) { assert(v.size()>0); IntegerVector ret(v.size()-1); for(int i=0;i0); return PolyhedralCone(dehomogenize(inequalities),dehomogenize(equations)); } bool PolyhedralCone::containsPositiveVector()const { PolyhedralCone temp=intersection(*this,PolyhedralCone::positiveOrthant(n)); IntegerVector v=temp.getRelativeInteriorPoint(); return v.isPositive(); } int PolyhedralCone::dimensionOfLinealitySpace()const { if(inequalities.empty())return dimension(); IntegerVectorList a; PolyhedralCone temp(a,inequalities); temp=intersection(temp,*this); return temp.dimension(); } bool PolyhedralCone::contains(IntegerVector const &v)const { for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++) { if(dotLong(*i,v)!=0)return false; } for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { if(dotLong(*i,v)<0)return false; } return true; } bool PolyhedralCone::contains(IntegerVectorList const &l)const { for(IntegerVectorList::const_iterator i=l.begin();i!=l.end();i++) if(!contains(*i))return false; return true; } bool PolyhedralCone::contains(PolyhedralCone const &c)const { PolyhedralCone c2=intersection(*this,c); PolyhedralCone c3=c; c2.canonicalize(); c3.canonicalize(); return !(c2!=c3); } bool PolyhedralCone::containsPerturbed(IntegerVectorList const &l)const { for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++) { for(IntegerVectorList::const_iterator j=l.begin();j!=l.end();j++) if(dotLong(*i,*j)!=0)return false; } for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { for(IntegerVectorList::const_iterator j=l.begin();j!=l.end();j++) if(dotLong(*i,*j)<0)return false; else if(dotLong(*i,*j)>0) break; } return true; } bool PolyhedralCone::containsRelatively(IntegerVector const &v)const { assert(state>=1); for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++) { if(dotLong(*i,v)!=0)return false; } for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { if(dotLong(*i,v)<=0)return false; } return true; } PolyhedralCone PolyhedralCone::permuted(IntegerVector const &v)const { PolyhedralCone ret(SymmetryGroup::permuteIntegerVectorList(inequalities,v),SymmetryGroup::permuteIntegerVectorList(equations,v),n,(areImpliedEquationsKnown()?PCP_impliedEquationsKnown:0)+(areFacetsKnown()?PCP_facetsKnown:0)); if(state>=1)ret.state=1; if(state>=2)ret.state=2; ret.ensureStateAsMinimum(state); ret.setMultiplicity(multiplicity); return ret; } IntegerVector PolyhedralCone::getUniquePoint()const { IntegerVectorList rays=extremeRays(); IntegerVector ret(n); for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) ret+=*i; assert(containsRelatively(ret));//remove this check later return ret; } IntegerVector PolyhedralCone::getUniquePointFromExtremeRays(IntegerVectorList const &extremeRays)const { IntegerVector ret(n); for(IntegerVectorList::const_iterator i=extremeRays.begin();i!=extremeRays.end();i++) if(contains(*i))ret+=*i; return ret; } /** * Returns a primitive vector parallel to the projection of v onto the orthogonal complement of E. */ static IntegerVector primitiveProjection(IntegerVectorList const &E, IntegerVector &v, bool useFloat) { int n=v.size(); if(useFloat) { IntegerMatrix E2=rowsToIntegerMatrix(E,n); linalgfloat::Matrix E3(E.size(),n); for(int i=0;i temp(coefficients.size()); for(int i=0;i tempInt(coefficients.size()); int denominator; doubleVectorToFractions(temp, tempInt, denominator); IntegerVector tempInt2(tempInt.size());for(int i=0;i1000)goto fallback; if(tempInt2.min()<-1000)goto fallback; if(denominator>1000)goto fallback; if(denominator<-1000)goto fallback; IntegerVector ret=denominator*v; int I=0; for(IntegerVectorList::const_iterator i=E.begin();i!=E.end();i++,I++)ret-=coefficients[I]*(*i); if(!E2.inKernel(ret))goto fallback; return normalized(ret); } fallback: debug<<"FLOATCONELINALG FALLBACK\n"; IntegerVectorList inequalities; inequalities.push_back(v); FieldMatrix linealitySpaceOrth=combineOnTop(integerMatrixToFieldMatrix(rowsToIntegerMatrix(E,n),Q),integerMatrixToFieldMatrix(rowsToIntegerMatrix(inequalities,n),Q)); FieldMatrix temp=combineOnTop(linealitySpaceOrth.reduceAndComputeKernel(),integerMatrixToFieldMatrix(rowsToIntegerMatrix(E,n),Q)); FieldMatrix temp2=temp.reduceAndComputeKernel(); assert(temp2.getHeight()==1); return temp2[0].primitive(); } IntegerVectorList PolyhedralCone::extremeRays(IntegerVectorList const *generatorsOfLinealitySpace)const { assert((dimension()==ambientDimension()) || (state>=3)); if(haveExtremeRaysBeenCached)return cachedExtremeRays; //The generators of the lineality space are not known, we may as well compute them. Since we typycally will use them at least once. IntegerVectorList generatorsOfLinealitySpace2; if(!generatorsOfLinealitySpace) { FieldMatrix linealitySpaceOrth=combineOnTop(integerMatrixToFieldMatrix(rowsToIntegerMatrix(this->equations,n),Q),integerMatrixToFieldMatrix(rowsToIntegerMatrix(this->inequalities,n),Q)); generatorsOfLinealitySpace2=fieldMatrixToIntegerMatrixPrimitive(linealitySpaceOrth.reduceAndComputeKernel()).getRows(); generatorsOfLinealitySpace=&generatorsOfLinealitySpace2; } // this->print(&debug); /* This code actually works even for lower dimensional cones if they have been canonicalized. */ // AsciiPrinter(Stderr).printVectorList(halfSpaces); // AsciiPrinter(Stderr).printVectorList(equations); IntegerVectorList ret; // log0 fprintf(Stderr,"calling double description (cddlib)\n"); IntegerVectorList indices=extremeRaysInequalityIndices(inequalities); // log0 fprintf(Stderr,"returning\n"); // log0 fprintf(Stderr,"computing relative interior points\n"); // debug<<"INDICES"<size();j++)asVector[(*i)[j]]=1; // log0 AsciiPrinter(Stderr)<equations; IntegerVectorList inequalities; IntegerVector theInequality; // log0 AsciiPrinter(Stderr)<inequalities.begin(); for(int j=0;jequations; for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++)equations2.push_back(*i); debug<equations,n),Q),integerMatrixToFieldMatrix(rowsToIntegerMatrix(this->inequalities,n),Q)); FieldMatrix temp=combineOnTop(linealitySpaceOrth.reduceAndComputeKernel(),integerMatrixToFieldMatrix(rowsToIntegerMatrix(equations,n),Q)); FieldMatrix temp2=temp.reduceAndComputeKernel(); assert(temp2.getHeight()==1); thePrimitiveVector=temp2[0].primitive(); // debug<size();j++) { IntegerVectorList::const_iterator a=halfSpaces.begin(); for(int k=0;k<(*i)[j];k++) { assert(a!=halfSpaces.end()); a++; } assert(a!=halfSpaces.end()); equations.push_back(*a); }*/ IntegerVector asVector(inequalities.size()); for(int j=0;jsize();j++)asVector[(*i)[j]]=1; IntegerVectorList equations=this->equations; IntegerVectorList inequalities; IntegerVectorList::const_iterator a=inequalities.begin(); for(int j=0;j=2); // ensureStateAsMinimum(2); // AsciiPrinter P(Stderr); // print(&P); return codimension()+getHalfSpaces().size()+dimensionOfLinealitySpace()==n; } bool PolyhedralCone::checkDual(PolyhedralCone const &c)const { assert(dimensionOfLinealitySpace()+c.dimension()==ambientDimension()); for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { assert(c.contains(*i)); } for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++) { assert(c.contains(*i)); } return true; } PolyhedralCone PolyhedralCone::dualCone()const { assert(state>=1); IntegerVectorList dualInequalities,dualEquations; dual(ambientDimension(),inequalities,equations,&dualInequalities,&dualEquations); PolyhedralCone ret(dualInequalities,dualEquations); ret.ensureStateAsMinimum(state); // ret.canonicalize(); assert(checkDual(ret)); assert(ret.checkDual(*this)); return ret; } PolyhedralCone PolyhedralCone::negated()const { IntegerVectorList inequalities2; for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++)inequalities2.push_back(-*i); // PolyhedralCone ret(inequalities2,equations,n); PolyhedralCone ret(inequalities2,equations,n,(areFacetsKnown()?PCP_facetsKnown:0)|(areImpliedEquationsKnown()?PCP_impliedEquationsKnown:0)); ret.ensureStateAsMinimum(state); return ret; } PolyhedralCone PolyhedralCone::linealitySpace()const { IntegerVectorList l1=getEquations(); IntegerVectorList l2=getHalfSpaces(); l1.splice(l1.begin(),l2); IntegerVectorList temp; PolyhedralCone ret(temp,l1,n); ret.ensureStateAsMinimum(state); return ret; } PolyhedralCone PolyhedralCone::span()const { return PolyhedralCone(IntegerVectorList(),getImpliedEquations(),n); } int PolyhedralCone::getMultiplicity()const { return multiplicity; } void PolyhedralCone::setMultiplicity(int m) { multiplicity=m; } IntegerVectorList PolyhedralCone::quotientLatticeBasis()const { assert(isInStateMinimum(1));// Implied equations must have been computed in order to know the span of the cone return basisOfQuotientLattice(equations,inequalities,n); } IntegerVector PolyhedralCone::semiGroupGeneratorOfRay()const { IntegerVectorList temp=quotientLatticeBasis(); assert(temp.size()==1); for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) if(dotLong(temp.front(),*i)<0) { temp.front()=-temp.front(); break; } return temp.front(); } IntegerVector const &PolyhedralCone::getLinearForm()const { return linearForm; } void PolyhedralCone::setLinearForm(IntegerVector const &linearForm_) { linearForm=linearForm_; } PolyhedralCone PolyhedralCone::link(IntegerVector const &w)const { /* * Observe that the inequalities giving rise to facets * also give facets in the link, if they are kept as * inequalities. This means that the state cannot decrease when taking links. * */ // assert(state>=3); IntegerVectorList inequalities2; for(IntegerVectorList::const_iterator j=inequalities.begin();j!=inequalities.end();j++) if(dotLong(w,*j)==0)inequalities2.push_back(*j); // PolyhedralCone C(inequalities2,getEquations(),n); // C.canonicalize(); // PolyhedralCone C(inequalities2,getEquations(),n,state);//STATE----------------------------------------------------- PolyhedralCone C(inequalities2,getEquations(),n,(areImpliedEquationsKnown()?PCP_impliedEquationsKnown:0)|(areFacetsKnown()?PCP_facetsKnown:0)); C.ensureStateAsMinimum(state); C.setLinearForm(getLinearForm()); C.setMultiplicity(getMultiplicity()); return C; } PolyhedralCone PolyhedralCone::givenByRays(IntegerVectorList const &generators, IntegerVectorList const &linealitySpace, int n) { //rewrite modulo lineality space IntegerVectorList newGenerators=generators; { Subspace l(linealitySpace,n); for(IntegerVectorList::const_iterator i=generators.begin();i!=generators.end();i++) newGenerators.push_back(l.canonicalizeVector(*i)); } PolyhedralCone dual(newGenerators,linealitySpace,n); dual.findFacets(); dual.canonicalize(); IntegerVectorList inequalities=dual.extremeRays(); IntegerVectorList span=generators; for(IntegerVectorList::const_iterator i=linealitySpace.begin();i!=linealitySpace.end();i++)span.push_back(*i); FieldMatrix m2Q=integerMatrixToFieldMatrix(rowsToIntegerMatrix(span,n),Q); IntegerVectorList equations=fieldMatrixToIntegerMatrixPrimitive(m2Q.reduceAndComputeKernel()).getRows(); return PolyhedralCone(inequalities,equations,n); } FieldElement PolyhedralCone::volume()const { AsciiPrinter P(Stderr); PolyhedralCone Ctemp=intersection(*this,this->linealitySpace().dualCone()); Ctemp.canonicalize(); cerr<<"testestests"; IntegerVectorList eq2=rowsToIntegerMatrix(Ctemp.equations,n).transposed().getRows(); eq2.push_front(IntegerVector(Ctemp.equations.size())); eq2=rowsToIntegerMatrix(eq2).transposed().getRows(); cerr<<"testestests2"; IntegerVectorList in2=rowsToIntegerMatrix(Ctemp.inequalities,n).transposed().getRows(); in2.push_front(IntegerVector(Ctemp.inequalities.size())); in2=rowsToIntegerMatrix(in2).transposed().getRows(); for(int i=0;i T=Triangulation::triangulate(A.transposed(),true);//revlex P<<"Done triangulating\n"; P<<(int)T.size(); FieldElement ret(Q); for(list::const_iterator i=T.begin();i!=T.end();i++) { FieldMatrix S=A2.submatrixRows(*i); debug<<"M"<linealitySpace().dualCone().getEquations(); IntegerVectorList rays=extremeRays(); for(IntegerVectorList::const_iterator i=linealitySpace.begin();i!=linealitySpace.end();i++) if(!f.contains(*i))return false; IntegerVectorList strict; for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++) if(!f.contains(*i)) strict.push_back(*i); IntegerVectorList linealitySpace2=f.linealitySpace().dualCone().getEquations(); IntegerVectorList rays2=f.extremeRays(); for(IntegerVectorList::const_iterator i=rays2.begin();i!=rays2.end();i++) { linealitySpace2.push_back(*i); } IntegerVectorList empty; HalfOpenCone C(n,linealitySpace2, empty, strict); return !C.isEmpty(); } PolyhedralCone PolyhedralCone::faceContaining(IntegerVector const &v)const { assert(n==v.size()); if(!contains(v)) { debug<<"Not contained in cone:\n"<=1)?PCP_impliedEquationsKnown:0); ret.ensureStateAsMinimum(state); return ret; } PolyhedralCone PolyhedralCone::faceContainingPerturbed(IntegerVectorList const &l)const { IntegerVectorList newEquations=equations; IntegerVectorList newInequalities; for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++) { bool onFacet=true; for(IntegerVectorList::const_iterator j=l.begin();j!=l.end();j++) if(dotLong(*i,*j)){onFacet=false;break;} if(!onFacet) newInequalities.push_back(*i); else newEquations.push_back(*i); } PolyhedralCone ret(newInequalities,newEquations,n,(state>=1)?PCP_impliedEquationsKnown:0); ret.ensureStateAsMinimum(state); return ret; } PolyhedralCone PolyhedralCone::projection(int newn)const { assert(newn<=n); assert(newn>=0); IntegerVectorList rays=extremeRays(); IntegerVectorList lines=linealitySpace().generatorsOfSpan(); rays=rowsToIntegerMatrix(rays,n).submatrix(0,0,rays.size(),newn).getRows(); lines=rowsToIntegerMatrix(lines,n).submatrix(0,0,lines.size(),newn).getRows(); return givenByRays(rays,lines,newn); } PolyhedralCone sum(PolyhedralCone const &A, PolyhedralCone const &B) { IntegerVectorList raysA=A.extremeRays(); IntegerVectorList raysB=B.extremeRays(); for(IntegerVectorList::const_iterator i=raysB.begin();i!=raysB.end();i++)raysA.push_back(*i); IntegerVectorList gensA=A.generatorsOfLinealitySpace(); IntegerVectorList gensB=B.generatorsOfLinealitySpace(); for(IntegerVectorList::const_iterator i=gensB.begin();i!=gensB.end();i++)gensA.push_back(*i); return PolyhedralCone::givenByRays(raysA,gensA,A.ambientDimension()); } IntegerVectorList inducedLink(PolyhedralCone const &c, PolyhedralCone const &l) { PolyhedralCone A=sum(c,l); A.canonicalize(); IntegerVectorList ret; if(A.dimension()==l.dimension())return ret; assert(l.dimension()+1==A.dimension()); int nineq=A.getHalfSpaces().size(); assert(nineq<=1); if(nineq==1) { ret.push_back(A.getUniquePoint()); } else { PolyhedralCone ADual=A.dualCone(); IntegerVectorList L=l.getEquations(); for(IntegerVectorList::const_iterator i=L.begin();i!=L.end();i++) if(!ADual.contains(*i)) { IntegerVectorList temp;temp.push_back(*i); PolyhedralCone ray(temp,A.getImpliedEquations()); ray.canonicalize(); IntegerVector v=ray.getUniquePoint(); ret.push_back(v); ret.push_back(-v); break; } assert(!ret.empty()); } return ret; } bool PolyhedralCone::doesSatisfyInequalityExpensive(IntegerVector const &ineq)const { if(!haveExtremeRaysBeenCached)this->extremeRays(); if(!haveGeneratorsOfLinealitySpaceBeenCached)this->generatorsOfLinealitySpace(); assert(haveGeneratorsOfLinealitySpaceBeenCached); assert(haveExtremeRaysBeenCached); for(IntegerVectorList::const_iterator i=cachedGeneratorsOfLinealitySpace.begin();i!=cachedGeneratorsOfLinealitySpace.end();i++) if(dotLong(*i,ineq)!=0)return false; for(IntegerVectorList::const_iterator i=cachedExtremeRays.begin();i!=cachedExtremeRays.end();i++) if(dotLong(*i,ineq)<0)return false; return true; } list PolyhedralCone::triangulation()const { IntegerVectorList rays=this->extremeRays(); rays.sort(); IntegerVectorList lines=this->generatorsOfLinealitySpace(); IntegerMatrix M=rowsToIntegerMatrix(rays,n); IntegerMatrix M2=M.transposed(); Triangulation2 T(M2); T.triangulate(); T.changeToTriangulationInducedBy(LexicographicTermOrder()); list ret; for(set::const_iterator i=T.bases.begin();i!=T.bases.end();i++) { IntegerVectorList gens; for(int j=0;jsize();j++)gens.push_back(M[(*i)[j]]); ret.push_back(PolyhedralCone::givenByRays(gens,lines,n)); } return ret; } gfan0.6.2/src/myassert.h0000644000175000017500000000067313122232611014475 0ustar andersanders/* * myassert.h * * Created on: Jul 10, 2011 * Author: anders */ #ifndef MYASSERT_H_ #define MYASSERT_H_ /* * This header does not have to be included, unless an explicit dumpStackTrace call is needed. * Compiling (using gcc) with -DSTACKDUMP_ENABLED -D__assert_fail=__assert_fail2 (and linking the * .o file) will make the assertions fail with a stack dump automatically. */ void dumpStackTrace(); #endif /* MYASSERT_H_ */ gfan0.6.2/src/app_scarfcomplex.cpp0000644000175000017500000000336613122232611016511 0ustar andersanders#include "parser.h" #include "printer.h" #include "polynomial.h" #include "division.h" #include "buchberger.h" #include "wallideal.h" #include "lp.h" #include "reversesearch.h" #include "termorder.h" #include "ep_standard.h" #include "ep_xfig.h" #include "gfanapplication.h" #include "matrix.h" #include "latticeideal.h" #include "subspace.h" #include "scarf.h" class ScarfComplexApplication : public GFanApplication { public: bool includeInDefaultInstallation() { return false; } const char *helpText() { return "This program .\n"; } ScarfComplexApplication() { registerOptions(); } const char *name() { return "_scarf_complex"; } int main() { LpSolver::printList(Stdout); lpSetSolver("cddgmp"); FileParser P(Stdin); IntegerVectorList ivl=P.parseIntegerVectorList(); IntegerMatrix A=rowsToIntegerMatrix(ivl); bool s1=satisfiesA1(A); fprintf(Stdout,"A1 satisfied:%i\n",s1); if(s1) { IntegerVectorList N=neighbours(A); AsciiPrinter Q(Stdout); Q.printVectorList(N); fprintf(Stdout,"A2 satisfied:%i\n",satisfiesA2(A)); fprintf(Stdout,"A3 satisfied:%i\n",satisfiesA3(A,&N)); N=orientedNeighbours(N,-A[0].toVector()); IntegerMatrix N2(1,A.getWidth()); N2.append(rowsToIntegerMatrix(N)); N2.append((-1)*rowsToIntegerMatrix(N)); Q.printVectorList(N2.getRows()); /* simplex=StringParser("(0,5,6)").parseIntegerVector(); Q.printVector(simplex); simplex=kFlip(A,N2,simplex,0); Q.printVector(simplex); */ IntegerVector simplex=computeMaximalScarfSimplex(A,N2); traverseScarfComplex(A,N2,simplex); } else fprintf(Stdout,"Neighbours for this matrix cannot be computed with the implemented method.\n"); return 0; } }; static ScarfComplexApplication theApplication; gfan0.6.2/src/gfanapplication.cpp0000644000175000017500000001605013122232611016314 0ustar andersanders#include "gfanapplication.h" #include #include #include "field.h" #include "field_rationals.h" #include "field_zmodpz.h" #include "division.h" #include "printer.h" #include "symmetry.h" #include "log.h" #include "linalg.h" #include "polymakefile.h" GFanApplication::FieldOption::FieldOption(): IntegerOption("--mod","Set the field to Z / pZ. The value must be a prime number p between 2 and 32749.\n") { } void GFanApplication::FieldOption::onOptionsParsed() { if(getValue()) { fprintf(Stderr,"CANNOT CHANGE FIELD\n"); assert(0); // Field::setField(new FieldZModPZ(getValue())); // Field::setField(Field::find("Zmod2Z")); } } GFanApplication::LogLevelOption::LogLevelOption(): IntegerOption("--log","Set the logging level.\n") { hide(); } GFanApplication::XmlOption::XmlOption(): SimpleOption("--xml","Switch to XML polyhedral data format output.\n") { hide(); } GFanApplication::StdinFileOption::StdinFileOption(): StringOption("--stdin","Set a file to be read as stdin.\n","") { hide(); } void GFanApplication::StdinFileOption::onOptionsParsed() { if(strlen(getValue())>0) { FILE *err=freopen(getValue(),"r",stdin); assert(err); } } GFanApplication::StdoutFileOption::StdoutFileOption(): StringOption("--stdout","Set a file to be read as stdin.\n","") { hide(); } void GFanApplication::StdoutFileOption::onOptionsParsed() { if(strlen(getValue())>0) { FILE *err=freopen(getValue(),"w",stdout); assert(err); } } void GFanApplication::LogLevelOption::onOptionsParsed() { if(getValue()==9) { Printer::setAssertOnPrinting(true); } else if(getValue()) { setLogLevel(getValue()); } } void GFanApplication::XmlOption::onOptionsParsed() { if(getValue())PolymakeFile::forceXml(); } void GFanApplication::assertSymmetriesMatch(IntegerVectorList const &g, class PolynomialSet &markedGroebnerBasis, FieldMatrix const *torusActions, bool asPolynomials) { PolynomialSet markedGroebnerBasis2=markedGroebnerBasis; markedGroebnerBasis2.sort_(); int n=markedGroebnerBasis2.numberOfVariablesInRing(); int I=0; for(IntegerVectorList::const_iterator i=g.begin();i!=g.end();i++) { if(i->size()!=n) { fprintf(Stderr,"PERMUTATION "); AsciiPrinter(Stderr).printVector(*i); fprintf(Stderr," HAS WRONG LENGTH.\n"); assert(0); } if(!SymmetryGroup::isPermutation(*i)) { fprintf(Stderr,"VECTOR "); AsciiPrinter(Stderr).printVector(*i); fprintf(Stderr," DOES NOT REPRESENT A PERMUTATION.\n"); assert(0); } //log0 AsciiPrinter(Stderr).printPolynomialSet(markedGroebnerBasis); PolynomialSet b2=SymmetryGroup::permutePolynomialSet(markedGroebnerBasis2,*i); //log0 AsciiPrinter(Stderr).printPolynomialSet(b2); if(torusActions)b2=b2.torusAct((*torusActions)[I]); //log0 AsciiPrinter(Stderr).printPolynomialSet(b2); if(!asPolynomials) { if(!areIdealsEqual(markedGroebnerBasis2,b2)) { fprintf(Stderr,"PERMUTATION "); AsciiPrinter(Stderr).printVector(*i); fprintf(Stderr," DOES NOT KEEP THE IDEAL FIXED.\n"); log1 fprintf(Stderr,"Original ideal:\n"); log1 AsciiPrinter(Stderr).printPolynomialSet(markedGroebnerBasis2); log1 fprintf(Stderr,"Permuted ideal:\n"); log1 AsciiPrinter(Stderr).printPolynomialSet(b2); log1 { for(PolynomialSet::const_iterator i=b2.begin();i!=b2.end();i++) { Polynomial remainder=division(*i,markedGroebnerBasis2,LexicographicTermOrder()); log1 AsciiPrinter(Stderr).printString("Remainder: "); log1 AsciiPrinter(Stderr).printPolynomial(remainder); log1 AsciiPrinter(Stderr).printNewLine(); if(!remainder.isZero()) { log1 AsciiPrinter(Stderr).printString("Polynomial not in ideal: "); log1 AsciiPrinter(Stderr).printPolynomial(*i); log1 AsciiPrinter(Stderr).printNewLine(); break; } } } assert(0); } } else { b2.markAndScale(LexicographicTermOrder()); markedGroebnerBasis2.markAndScale(LexicographicTermOrder()); b2.sort_(); if(!(markedGroebnerBasis2==b2)) { fprintf(Stderr,"PERMUTATION "); AsciiPrinter(Stderr).printVector(*i); fprintf(Stderr," DOES NOT KEEP POLYNOMIAL SET FIXED.\n"); log1 { AsciiPrinter(Stderr).printPolynomialSet(markedGroebnerBasis2); AsciiPrinter(Stderr).printPolynomialSet(b2); PolynomialSet::const_iterator j=markedGroebnerBasis2.begin(); for(PolynomialSet::const_iterator i=b2.begin();i!=b2.end();i++) { if(!(*j-*i).isZero()) { fprintf(Stderr,"Polynomials are different:\n"); AsciiPrinter(Stderr).printPolynomial(*i); fprintf(Stderr,"\n"); AsciiPrinter(Stderr).printPolynomial(*j); fprintf(Stderr,"\nDifference:\n"); AsciiPrinter(Stderr).printPolynomial(*i-*j); fprintf(Stderr,"\n"); break; } j++; } } assert(0); } } I++; } } void GFanApplication::onExit() { log1 { fprintf(Stderr,"Number of living FieldImplementation objects:%i\n",FieldImplementation::getNumberOfLivingFieldImplementations()); fprintf(Stderr,"Number of living FieldElementImplementation objects:%i\n",FieldElementImplementation::getNumberOfLivingFieldElementImplementations()); } } #include "gmp.h" #include "versioninfo.h" #include "lp.h" #include "groebnerengine.h" class VersionApplication : public Application { bool includeInDefaultInstallation() { return true; } const char *helpText() { return "This program writes out version information of the Gfan installation.\n"; } const char *name() { return "_version"; } int main() { cout<<"Gfan version:\n"<