Beispiel #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;
}
bool testEchelonize (const Ring &F, const char *text, Matrix &A)
{
	std::ostringstream str;
	str << "Testing Elimination::echelonize for " << text << " matrices" << std::ends;
	commentator.start (str.str ().c_str (), __FUNCTION__);

	std::ostream &report = commentator.report (Commentator::LEVEL_NORMAL, INTERNAL_DESCRIPTION);
	std::ostream &error = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR);

	bool pass = true;

	Context<Ring> ctx (F);

	Elimination<Ring> elim (ctx);

	typename Matrix::ContainerType PA (A.rowdim (), A.coldim ()), LPA (A.rowdim (), A.coldim ());

	BLAS3::copy (ctx, A, PA);

	typename Elimination<Ring>::Permutation P;

	size_t rank;
	typename Ring::Element det;

	report << "A = " << std::endl;
	BLAS3::write (ctx, report, A, FORMAT_PRETTY);

	elim.echelonize (A, P, rank, det, true);

	report << "L, R = " << std::endl;
	BLAS3::write (ctx, report, A, FORMAT_PRETTY);

	report << "P = ";
	BLAS1::write_permutation (report, P.begin (), P.end ()) << std::endl;

	BLAS3::permute_rows (ctx, P.begin (), P.end (), PA);
	report << "PA = " << std::endl;
	BLAS3::write (ctx, report, PA, FORMAT_PRETTY);

	typename Matrix::ContainerType L (A.rowdim (), A.rowdim ());

	typename Matrix::ContainerType::RowIterator i_L;
	StandardBasisStream<Ring, typename Matrix::ContainerType::Row> s (ctx.F, A.rowdim ());

	for (i_L = L.rowBegin (); i_L != L.rowEnd (); ++i_L)
		s >> *i_L;

	elim.move_L (L, A);

	BLAS3::scal (ctx, F.zero (), LPA);
	BLAS3::gemm (ctx, F.one (), L, PA, F.zero (), LPA);
	report << "LPA = " << std::endl;
	BLAS3::write (ctx, report, LPA);

	report << "Computed rank = " << rank << std::endl;
	report << "Computed det = ";
	F.write (report, det);
	report << std::endl;

	if (!BLAS3::equal (ctx, LPA, A)) {
		error << "LPA != R, not okay" << std::endl;
		pass = false;
	}

	commentator.stop (MSG_STATUS (pass));

	return pass;
}