bool testRandom(const Ring& R, size_t n) { bool pass = true; commentator().start ("Testing Iloipoulos elimination:", "testRandom"); using namespace std; ostream &report = commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION); BlasMatrixDomain<Ring> BMD(R); BlasMatrix<Ring> D(R, n, n), L(R, n, n), U(R, n, n), A(R,n,n); // D is Smith Form const int m = 16; int p[m] = {1,1,1,1,1,1,2, 2, 2, 4, 3, 3, 3, 5, 7, 101}; typename Ring::Element x, y; R.assign(x, R.one); if (n > 0) D.setEntry(0,0,x); for(size_t i = 1; i < n; ++i){ R.init(y, p[rand()%m]); D.setEntry(i,i, R.mulin(x, y)); } if (n > 0) D.setEntry(n-1,n-1, R.zero); // L and U are random unit triangular. for (size_t i = 0; i < n; ++ i) { for (size_t j = 0; j < i; ++ j) { L.setEntry(i,j, R.init(x, rand() % 10)); U.setEntry(j,i, R.init(x, rand() % 10)); } L.setEntry(i,i, R.one); U.setEntry(i,i, R.one); } // A is ULDU BMD.mul(A, U, L); BMD.mulin_left(A, D); BMD.mulin_left(A, U); D.write( report << "Smith form matrix:\n " ) << endl; A.write( report << "input matrix:\n " ) << endl; // SmithFormIliopoulos::smithFormIn (A); // A.write( report << "smith of input matrix direct:\n " ) << endl; report << "Using PIRModular<int32_t>\n"; typename Ring::Element d; R.init(d,16*101);//16*101*5*7*9); for (size_t i = 0; i < n-1; ++i) R.mulin(d, D.getEntry(x, i, i)); R.write(report << "modulus: ", d) << endl; //det(d, D); //PIRModular<int32_t> Rd( (int32_t)(s % LINBOX_MAX_MODULUS)); PIRModular<int32_t> Rp( (int32_t)d); BlasMatrix<PIRModular<int32_t> > Ap(Rp, n, n), Dp(Rp, n, n); MatrixHom::map (Ap, A); SmithFormIliopoulos::smithFormIn (Ap); Ap.write( report << "Computed Smith form: \n") << endl; MatrixHom::map (Dp, D); BlasMatrixDomain<PIRModular<int32_t> > BMDp(Rp); pass = pass and BMDp.areEqual(Dp, Ap); commentator().stop (MSG_STATUS (pass), (const char *) 0, "testRandom"); return pass; }
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; }