示例#1
0
bool testRandom(const Ring& R,
		const SmithForm& SF,
		LinBox::VectorStream<Vector>& stream1)
{

    std::ostringstream str;

	str << "Testing Smith Form binary(EGV++):";

        commentator().start (str.str ().c_str (), "testSmithform");//, stream1.m ());

        bool ret = true;
        bool iter_passed = true;

        LinBox::VectorDomain<Ring> VD (R);

	Vector d, x;

	VectorWrapper::ensureDim (d, stream1.n ());

	VectorWrapper::ensureDim (x, stream1.n ());


	int n = (int)d. size();

	 while (stream1) {

                commentator().startIteration ((unsigned)stream1.j ());

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

                iter_passed = true;

                stream1.next (d);

		report << "Input vector:  ";
		VD.write (report, d);
                report << endl;

		BlasMatrix<Ring> D(R, n, n), L(R, n, n), U(R, n, n), A(R,n,n);

		int i, j;

		for(i = 0; i < n; ++i) {
			R. assign (D[i][i], d[i]);
			R. init (L[i][i], 1);
			R. init (U[i][i], 1);}

		for (i = 0; i < n; ++ i)

			for (j = 0; j < i; ++ j) {

				R.init(L[i][j], rand() % 10);

				R.init(U[j][i], rand() % 10);
			}


		std::vector<typename Ring::Element> tmp1(n), tmp2(n), e(n);

		typename BlasMatrix<Ring>::ColIterator col_p;

		i = 0;
		for (col_p = A.colBegin();
		     col_p != A.colEnd(); ++ col_p, ++ i) {

			R.init(e[i],1);
			U.apply(tmp1, e);
			D.apply(tmp2, tmp1);
			L.apply(*col_p, tmp2);
			R.init(e[i],0);
		}



		SF.smithFormBinary (x, A);


		report << "Computed Smith form: \n";

		VD. write (report, x);

		report << '\n';


		typename std::vector<typename Ring::Element>::iterator p1, p2;
		typename Ring::Element g;


		for (p1 = d.begin(); p1 != d.end(); ++ p1) {

			for ( p2 = p1 + 1; p2 != d.end(); ++ p2) {

				if (R. isUnit(*p1))  break;

				else if (R. isZero (*p2)) continue;

				else if (R. isZero (*p1)) {
                                                std::swap (*p1, *p2);
				}

				else {
					R. gcd (g, *p1, *p2);

					R. divin (*p2, g);

					R. mulin (*p2, *p1);

					R. assign (*p1, g);
				}
			}
		}


		report << "Expected smith form:\n";

		VD.write (report, d);

		report << '\n';

		if (!VD.areEqual (d, x))

			ret = iter_passed = false;

                if (!iter_passed)

                        commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: Computed Smith form is incorrect" << endl;



                commentator().stop ("done");

                commentator().progress ();

	 }

	 //stream1.reset ();

	  commentator().stop (MSG_STATUS (ret), (const char *) 0, "testSmithform");

	  return ret;

}
bool testRandomSolve (const Ring& R,
		      const Field& f,
		      LinBox::VectorStream<Vector>& stream1,
		      LinBox::VectorStream<Vector>& stream2)
{


	std::ostringstream str;



	commentator().start ("Testing Nonsingular Random Diagonal solve ", "testNonsingularRandomDiagonalSolve");

	bool ret = true;

        bool iter_passed = true;

	VectorDomain<Ring> VD (R);

	Vector d, b, x, y;

	VectorWrapper::ensureDim (d, stream1.n ());
        VectorWrapper::ensureDim (b, stream1.n ());
        VectorWrapper::ensureDim (x, stream1.n ());
        VectorWrapper::ensureDim (y, stream1.n ());

	int n = (int)d. size();

	while (stream1 && stream2) {

		commentator().startIteration ((unsigned)stream1.j ());

                //ActivityState state = commentator().saveActivityState ();

                iter_passed = true;

		bool zeroEntry;
		do {
		  stream1.next (d);
		  zeroEntry = false;
		  for (size_t i=0; i<stream1.n(); i++)
		    zeroEntry |= R.isZero(d[i]);
		} while (zeroEntry);

                stream2.next (b);

                std::ostream &report = commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION);
                report << "Diagonal entries: ";
                VD.write (report, d);
                report << endl;

                report << "Right-hand side:  ";
                VD.write (report, b);
                report << endl;

                //Diagonal<Ring> D(R, d);

		BlasMatrix<Ring> D(R, n, n);

		for(int i = 0; i < n; ++i) R.init (D[i][i],  d[i]);

		typedef RationalSolverAdaptive RSolver;
		RSolver rsolver;

		//std::vector<std::pair<typename Ring::Element, typename Ring::Element> > answer(n);
		std::vector<typename Ring::Element> num(n);
		typename Ring::Element den;

		SolverReturnStatus solveResult = rsolver.solveNonsingular(num, den, D, b); //often 5 primes are not enough

#if 0
		typename Ring::Element lden;

		R. init (lden, 1);

		typename std::vector<std::pair<typename Ring::Element, typename Ring::Element> >::iterator p;

		for (p = answer.begin(); p != answer.end(); ++ p)
			R. lcm (lden, lden, p->second);
		typename Vector::iterator p_x;
		//typename Vector::iterator p_y;
#endif

		if (solveResult == SS_OK) {
#if 0
		  for (p = answer.begin(), p_x = x. begin();
		       p != answer.end();
		       ++ p, ++ p_x) {

		    R. mul (*p_x, p->first, lden);

		    R. divin (*p_x, p->second);

		  }

		  D. apply (y, x);
#endif
		  D. apply (y, num);

		  VD. mulin(b, den);

		  if (!VD.areEqual (y, b)) {
		    ret = iter_passed = false;
		    commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
		      << "ERROR: Computed solution is incorrect" << endl;
		  }
		}
		else {
		    ret = iter_passed = false;
		    commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
		      << "ERROR: Did not return OK solving status" << endl;
		}

		commentator().stop ("done");
                commentator().progress ();

	}


	stream1.reset ();
        stream2.reset ();

        commentator().stop (MSG_STATUS (ret), (const char *) 0, "testNonsingularRandomDiagonalSolve");

	return ret;
}
示例#3
0
bool testRandom(const Ring& R,
		LinBox::VectorStream<Vector>& stream1)
{

	std::ostringstream str;

	str << "Testing the smithForm function in solutions directory:\n";

        commentator().start (str.str ().c_str (), "testRandom");//, stream1.m ());

        bool ret = true;

        LinBox::VectorDomain<Ring> VD (R);

	Vector d(R), x(R);

	LinBox::VectorWrapper::ensureDim (d, stream1.n ());

	LinBox::VectorWrapper::ensureDim (x, stream1.n ());


	int n = (int)d. size();

	 while (stream1) {

                commentator().startIteration ((unsigned)stream1.j ());

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

                bool iter_passed = true;

                stream1.next (d);

		report << "Input vector:  ";
		VD.write (report, d);
                report << endl;

		BlasMatrix<Ring> D(R, (size_t)n, (size_t)n), L(R, (size_t)n, (size_t)n), U(R, (size_t)n, (size_t)n), A(R,(size_t)n,(size_t)n);

		int i, j;

		for(i = 0; i < n; ++i) {
			R. assign (D[(size_t)i][(size_t)i], d[(size_t)i]);
			R. assign(L[(size_t)i][(size_t)i], R.one);
			R. assign(U[(size_t)i][(size_t)i], R.one);}

		for (i = 0; i < n; ++ i)

			for (j = 0; j < i; ++ j) {

				R.init(L[(size_t)i][(size_t)j], rand() % 10);

				R.init(U[(size_t)j][(size_t)i], rand() % 10);
			}


		BlasVector<Ring> tmp1(R,(size_t)n), tmp2(R,(size_t)n), e(R,(size_t)n);

		typename BlasMatrix<Ring>::ColIterator col_p;

		i = 0;
		for (col_p = A.colBegin();
		     col_p != A.colEnd(); ++ col_p, ++ i) {

			R.assign(e[(size_t)i],R.one);
			U.apply(tmp1, e);
			D.apply(tmp2, tmp1);
			// LinBox::BlasSubvector<BlasVector<Ring> > col_p_v (R, *col_p);
			// L.apply(col_p_v, tmp2);
			L.apply(*col_p, tmp2); //! @internal @bug  should use Triangular apply ? We are doing this many times, factor somewhere in test-utils.h ? why not some ftrtr routine for that ?
			R.assign(e[(size_t)i],R.zero);
		}

		typename Vector::iterator x_p;
		Givaro::ZRing<Integer> Z;
		BlasVector<Givaro::ZRing<Integer> > xi(Z,A. rowdim());
		BlasVector<Givaro::ZRing<Integer> >::iterator xi_p;
		std::list<std::pair<Integer, size_t> > cpt;
		smithForm (cpt, A);
		std::list<std::pair<Integer, size_t> >::iterator cpt_p;

		xi_p = xi. begin();
		for (cpt_p = cpt.begin(); cpt_p != cpt.end(); ++ cpt_p) {
			for (size_t ii = 0; ii < cpt_p -> second; ++ ii, ++ xi_p)
				*xi_p = cpt_p -> first;
		}

		for (x_p = x. begin(), xi_p = xi. begin(); x_p != x. end(); ++ x_p, ++ xi_p)
			A. field (). init (*x_p, *xi_p);

		report << "Computed Smith form: \n";
		VD. write (report, x);

		report << '\n';

		typename BlasVector<Ring>::iterator p1, p2;
		typename Ring::Element g;

		for (p1 = d.begin(); p1 != d.end(); ++ p1) {
			for ( p2 = p1 + 1; p2 != d.end(); ++ p2) {
				if (R. isUnit(*p1))  break;
				else if (R. isZero (*p2)) continue;
				else if (R. isZero (*p1)) std::swap (*p1, *p2);
				else { // (*p1, *p2) <-- (g, *p1 * *p2 / g), where g = gcd(*p1, *p2)
					R. gcd (g, *p1, *p2);
					R. divin (*p2, g);
					R. mulin (*p2, *p1);
					R. assign (*p1, g);
				}
			}
		}

		report << "Expected smith form:\n";
		VD.write (report, d) << endl;

		if (!VD.areEqual (d, x))
			ret = iter_passed = false;

		if (!iter_passed)
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: Computed Smith form is incorrect" << endl;

		commentator().stop ("done");
		commentator().progress ();
	 }

	//stream1.reset ();

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testRandom");

	return ret;
}