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; }
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; }