/* * gfanlib_mixedvolume.cpp * * Created on: Apr 10, 2016 * Author: anders */ #include #include "gfanlib_mixedvolume.h" #include "gfanlib_circuittableint.h" #include "gfanlib_tropicalhomotopy.h" #include "gfanlib_z.h" using namespace std; typedef gfan::CircuitTableInt32 mvtyp; namespace gfan{ static Integer stringToInteger(char const *s) { Integer ret; while(*s)ret=Integer(10)*ret+((*(s++))-'0'); return ret; } class MVExceptionRethrow: public exception { virtual const char* what() const throw() { return "Exception: Rethrown after detecting aborting flag in tropical homotopy."; } }MVExceptionRethrow; class MVAmbientDimensionMismatch: public std::exception { virtual const char* what() const throw() { return "Exception: The number of polytopes passed to the mixed volume computation does not match the ambient dimension."; } }MVAmbientDimensionMismatch; static std::vector > 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;i