bool testGaussTransform (const Ring &F, size_t m, size_t n) { commentator.start ("Testing GaussJordan::echelonize", __FUNCTION__); std::ostream &report = commentator.report (Commentator::LEVEL_NORMAL, INTERNAL_DESCRIPTION); std::ostream &error = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR); bool pass = true; DenseMatrix<typename Ring::Element> R (m, n); RandomDenseStream<Ring, typename DenseMatrix<typename Ring::Element>::Row> A_stream (F, n, m); DenseMatrix<typename Ring::Element> A (A_stream), A_copy (m, n); typename GaussJordan<Ring>::Permutation P; Context<Ring> ctx (F); Elimination<Ring> elim (ctx); GaussJordan<Ring> GJ (ctx); size_t rank; typename Ring::Element det; BLAS3::copy (ctx, A, R); BLAS3::copy (ctx, A, A_copy); GJ.echelonize (R, P, rank, det); report << "A = " << std::endl; BLAS3::write (ctx, report, A); report << "P = "; BLAS1::write_permutation (report, P.begin (), P.end ()) << std::endl; report << "R, L = " << std::endl; BLAS3::write (ctx, report, R); BLAS3::permute_rows (ctx, P.begin (), P.end (), A); report << "PA = " << std::endl; BLAS3::write (ctx, report, A); typename DenseMatrix<typename Ring::Element>::SubmatrixType Rp (R, 0, 0, R.rowdim (), R.rowdim ()); BLAS3::trmm (ctx, F.one (), Rp, A, LowerTriangular, true); report << "LPA = " << std::endl; BLAS3::write (ctx, report, A); report << "Computed rank = " << rank << std::endl; report << "Computed det = "; F.write (report, det); report << std::endl; // Trick to eliminate part below diagonal so that equality-check works elim.move_L (R, R); if (!BLAS3::equal (ctx, A, R)) { error << "ERROR: LPA != R" << std::endl; pass = false; } elim.echelonize (A_copy, P, rank, det, false); report << "Result of Elimination::echelonize: " << std::endl; BLAS3::write (ctx, report, A_copy); if (!BLAS3::equal (ctx, A_copy, R)) { error << "ERROR: Results from Elimination and GaussJordan not equal" << std::endl; pass = false; } commentator.stop (MSG_STATUS (pass)); return pass; }
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; }