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