void i_vti_v(RBlackbox& Res, DenseMatrix<Rationals >& M, DVector& den, Integer& detPrec) { detPrec=1; Rationals Q; int n = M.coldim(); //DVector denV(n,1); for (int i=0; i < den.size();++i) den[i]=1; for (int i=0; i < n; ++i) { for (int j=0; j <=i ; ++j) { Integer q_num =0; Integer q_den =1; for (int k=0; k < n; ++k) { Integer deno_ik, nume_ik, deno_jk, nume_jk, deno, nume; Q.get_den (deno_ik, M.getEntry(k,i)); Q.get_num (nume_ik, M.getEntry(k,i)); Q.get_den (deno_jk, M.getEntry(k,j)); Q.get_num (nume_jk, M.getEntry(k,j)); if (i==k) { nume_ik = deno_ik-nume_ik; } else { nume_ik = -nume_ik; } if (j==k) { nume_jk = deno_jk-nume_jk; } else { nume_jk = -nume_jk; } //cout << nume_ik << nume_jk; deno = deno_ik*deno_jk; nume = nume_ik*nume_jk; //cout << q_num << "/" << q_den << " " ; //cout << nume << "/" << deno << " " ; if (deno==q_den) q_num+=nume; else { if (nume != 0) { Integer g = gcd(q_den, deno); q_num = q_num*deno/g+nume*q_den/g; q_den = q_den*deno/g; } } //cout << q_num << "/" << q_den << " " ; } if (q_num != 0) { Quotient q(q_num,q_den); if (i!=j) { den[i]=lcm(den[i], q_den); den[j]=lcm(den[j], q_den); Res.setEntry(i,j,q); Res.setEntry(j,i,q); cout << i << " " << j << " " << q_num << "/" << q_den << "\n"; cout << j << " " << i << " " << q_num << "/" << q_den << "\n"; } else { den[i]=lcm(den[i], q_den); Res.setEntry(i,j,q); cout << i << " " << j << " " << q_num << "/" << q_den << "\n"; } } } } Integer d = 1; for (int i=0; i < den.size(); ++i) { detPrec *=den[i]; d = lcm(d, den[i]); } den[den.size()-1]=d; for (int i=den.size()-2; i >=0; --i) { den[i]=d*den[i+1]; } }
int main (int argc, char **argv) { // Usage if (argc < 2 || argc > 4) { std::cerr << "Usage: solve <matrix-file-in-supported-format> [<dense-vector-file>]" << std::endl; return 0; } // File std::ifstream input (argv[1]); if (!input) { std::cerr << "Error opening matrix file " << argv[1] << std::endl; return -1; } std::ifstream invect; bool createB = false; if (argc == 2) { createB = true; } if (argc == 3) { invect.open (argv[2], std::ifstream::in); if (!invect) { createB = true; } else { createB = false; } } // Read Integral matrix from File Ints ZZ; MatrixStream< Ints > ms( ZZ, input ); DenseMatrix<Ints> A (ms); Ints::Element d; std::cout << "A is " << A.rowdim() << " by " << A.coldim() << std::endl; { // Print Matrix // Matrix Market // std::cout << "A is " << A << std::endl; // Maple A.write(std::cout << "Pretty A is ", Tag::FileFormat::Maple) << std::endl; } // Vectors ZVector X(ZZ, A.coldim()),B(ZZ, A.rowdim()); if (createB) { std::cerr << "Creating a random {-1,1} vector " << std::endl; srand48( BaseTimer::seed() ); for(ZVector::iterator it=B.begin(); it != B.end(); ++it) if (drand48() <0.5) *it = -1; else *it = 1; } else { for(ZVector::iterator it=B.begin(); it != B.end(); ++it) invect >> *it; } { // Print RHS std::cout << "B is ["; for(auto it:B) ZZ.write(std::cout, it) << " "; std::cout << "]" << std::endl; } std::cout << "B is " << B.size() << "x1" << std::endl; Timer chrono; // BlasElimination Method::BlasElimination M; M.singular(Specifier::NONSINGULAR); chrono.start(); solve (X, d, A, B, M); chrono.stop(); std::cout << "CPU time (seconds): " << chrono.usertime() << std::endl; { // Solution size std::cout<<"Reduced solution: \n"; size_t maxbits=0; for (size_t i=0;i<A.coldim();++i){ maxbits=(maxbits > X[i].bitsize() ? maxbits: X[i].bitsize()); } std::cout<<" numerators of size "<<maxbits<<" bits" << std::endl <<" denominators hold over "<<d.bitsize()<<" bits\n"; } { // Check Solution VectorDomain<Ints> VD(ZZ); MatrixDomain<Ints> MD(ZZ); ZVector LHS(ZZ, A.rowdim()), RHS(ZZ, B); // check that Ax = d.b MD.vectorMul(LHS, A, X); VD.mulin(RHS, d); if (VD.areEqual(LHS, RHS)) std::cout << "Ax=b : Yes" << std::endl; else std::cout << "Ax=b : No" << std::endl; } { // Print Solution std::cout << "(BlasElimination) Solution is ["; for(auto it:X) ZZ.write(std::cout, it) << " "; std::cout << "] / "; ZZ.write(std::cout, d)<< std::endl; } return 0; }