示例#1
0
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;
}
示例#2
0
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;
}