test-ratrecon.C
// Copyright(c)'1994-2009,2010 by The Givaro group
// This file is part of Givaro.
// BB: adapted,enhanced from examples/FiniteFields/ff-arith.C
// Givaro is governed by the CeCILL-B license under French law
// and abiding by the rules of distribution of free software.
// see the COPYRIGHT file for more details.
#include <iostream>
#include <givaro/givpoly1.h>
#include <givaro/givfractiondomain.h>
#include <givaro/modular-integral.h>
#ifdef GIVARO_DEBUG
long long TTcount = 0;
#endif
using namespace Givaro;
#define TEST_EQ( F, a, b ) \
if (!F.areEqual((a),(b))) {\
F.write( F.write(std::cout,a) << "!=",b) << " failed (at line " << __LINE__ << ')' << std::endl; \
return(-1); \
}
template<class PDomain>
int TestRR(PDomain& PolDom, GivRandom& generator, const Degree d) {
// std::cout << "Start: " << d << std::endl;
typename PDomain::Element P,Q,R,S,M,A,B, G;
PolDom.random(generator, M, (d << 1) + 2);
Degree dG;
do {
PolDom.random(generator, Q, d);
PolDom.getdomain().assign(Q[Q.size()-1], PolDom.getdomain().one);
PolDom.gcd(G, M, Q);
PolDom.degree(dG, G);
} while( dG > 0);
do {
PolDom.random(generator, P, d-1);
PolDom.gcd(G, P, Q);
PolDom.degree(dG, G);
} while( dG > 0);
PolDom.invmod(R,Q,M);
// PolDom.write(std::cout << "R1:= ", R) << ';' << std::endl;
PolDom.mulin(R, P);
// PolDom.write(std::cout << "R2:= ", R) << ';' << std::endl;
PolDom.modin(R, M);
// PolDom.write(std::cout << "R3:= ", R) << ';' << std::endl;
PolDom.ratrecon(A,B,R,M,d);
typename PDomain::Type_t lc;
PolDom.leadcoef(lc, B);
PolDom.divin(A, lc);
PolDom.divin(B, lc);
PolDom.invmod(S,B,M);
// PolDom.write(std::cout << "S1:= ", S) << ';' << std::endl;
PolDom.mulin(S, A);
// PolDom.write(std::cout << "S2:= ", S) << ';' << std::endl;
PolDom.modin(S, M);
// PolDom.write(std::cout << "S3:= ", S) << ';' << std::endl;
// PolDom.write(std::cout << "M:= ", M) << ';' << std::endl;
// PolDom.write(std::cout << "P:= ", P) << ';' << std::endl;
// PolDom.write(std::cout << "Q:= ", Q) << ';' << std::endl;
// PolDom.write(std::cout << "R:= ", R) << ';' << std::endl;
// PolDom.write(std::cout << "A:= ", A) << ';' << std::endl;
// PolDom.write(std::cout << "B:= ", B) << ';' << std::endl;
// PolDom.write( PolDom.write(std::cout << "P/Q: ", P) << "/", Q) << std::endl;
// PolDom.write( PolDom.write(std::cout << "A/B: ", A) << "/", B) << std::endl;
// TEST_EQ(PolDom, A, P);
// TEST_EQ(PolDom, B, Q);
TEST_EQ(PolDom, S, R);
#ifdef GIVARO_DEBUG
++TTcount;
#endif
return 0;
}
int main(int argc, char ** argv)
{
int seed = int(argc>1?atoi(argv[1]):BaseTimer::seed());
#ifdef GIVARO_DEBUG
std::cerr << "seed: " << seed << std::endl;
#endif
Integer::seeding((unsigned long)seed);
GivRandom generator((unsigned long)seed);
typedef Modular<int64_t> Field;
typedef Poly1Dom< Field, Dense > PolyZpz;
typedef FracDom<PolyZpz> FracZpz;
typedef Poly1Dom< FracZpz, Dense > PolyFracZpz;
Field F101(101);
Field F2(2);
Field F65521(65521);
bool success = true;
{
PolyZpz PZ(F101,"X");
for(size_t j=0; j<4; ++j)
for(Degree i=1; i<Degree(30); ++i)
success &= (! TestRR(PZ, generator, i) );
PolyFracZpz PFZ(PZ,"Y");
for(size_t j=0; j<2; ++j)
for(Degree i=2; i<Degree(5); ++i)
success &= (! TestRR(PFZ, generator, i) );
}
{
PolyZpz PZ(F2,"X");
for(size_t j=0; j<4; ++j)
for(Degree i=5; i<Degree(50); ++i)
success &= (! TestRR(PZ, generator, i) );
PolyFracZpz PFZ(PZ,"Y");
for(size_t j=0; j<3; ++j)
for(Degree i=7; i<Degree(15); ++i)
success &= (! TestRR(PFZ, generator, i) );
}
{
PolyZpz PZ(F65521,"X");
for(size_t j=0; j<5; ++j)
for(Degree i=1; i<Degree(30); ++i)
success &= (! TestRR(PZ, generator, i) );
PolyFracZpz PFZ(PZ,"Y");
for(size_t j=0; j<2; ++j)
for(Degree i=2; i<Degree(5); ++i)
success &= (! TestRR(PFZ, generator, i) );
}
#ifdef GIVARO_DEBUG
if (! success) {
std::cerr << "Error: " << seed << std::endl;
} else {
std::cerr << "Success:" << TTcount << std::endl;
}
#endif
return (! success);
}
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s