Undocumented.
#include <givaro/modular.h>
#include <linbox/field/gmp-rational.h>
#include <linbox/solutions/charpoly.h>
#include <linbox/solutions/minpoly.h>
#include <linbox/ring/polynomial-ring.h>
typedef Givaro::ZRing<Integer> Integers;
typedef Integers::Element Integer;
typedef Givaro::Modular<double > Field;
typedef Field::Element Element;
typedef GMPRationalField Rationals;
typedef SparseMatrix<Rationals > RBlackbox;
typedef UserTimer myTimer;
myTimer tRationalModular;
template <class Field, class Polynomial>
std::ostream&
printPolynomial (std::ostream& out,
const Field &F,
const Polynomial &v)
{
for (int i = v.size () - 1; i >= 0; i--) {
F.write (out, v[i]);
if (i > 0)
out << " X^" << i << " + ";
out << "\n";
}
return out;
}
template <class Blackbox, class MyMethod>
struct PrecRationalModularCharpoly {
const Blackbox &A;
const MyMethod &M;
const Integer ≺
PrecRationalModularCharpoly(const Integer& detPrec, const Blackbox& b, const MyMethod& n) :
prec(detPrec), A(b), M(n)
{}
template<typename Polynomial, typename Field>
Polynomial& operator()(Polynomial& P, const Field& F) const
{
typedef typename Blackbox::template rebind<Field>::other FBlackbox;
FBlackbox * Ap;
tRationalModular.clear();
tRationalModular.start();
MatrixHom::map(Ap, A, F);
tRationalModular.stop();
F.characteristic(p);
cout<<"Valence "<<p<<" = P[P.size()-1]" << P[P.size(0)-1] << " R-M time " ;
tRationalModular.print(cout);
cout << "\n" ;
typename Field::Element fprec;
F.init(fprec, prec);
delete Ap;
for (int i=0; i < P.size(); ++i)
F.mulin(P[i],fprec);
return P;
}
};
template <class Blackbox, class MyMethod>
struct PrecRationalModularMinpoly {
const Blackbox &A;
const MyMethod &M;
const DVector ≺
PrecRationalModularMinpoly(const DVector& detPrec, const Blackbox& b, const MyMethod& n) :
prec(detPrec), A(b), M(n)
{}
template<typename Polynomial, typename Field>
{
typedef typename Blackbox::template rebind<Field>::other FBlackbox;
FBlackbox * Ap;
tRationalModular.clear();
tRationalModular.start();
MatrixHom::map(Ap, A, F);
tRationalModular.stop();
F.characteristic(p);
cout<<"Valence "<<p<<" = P[P.size()-1]" << P[P.size()-1] << " R-M time " ;
tRationalModular.print(cout);
cout << "\n" ;
typename Field::Element fprec;
delete Ap;
for (int i=0; i < P.size()-1; ++i) {
F.init(fprec, prec[i]);
F.mulin(P[i],fprec);
}
}
};
void continuedFractionIn(double x,Integer& num, Integer& den, double epsi,const size_t s, Integer den_bound);
template <class RMatrix>
int main (int argc, char** argv)
{
if ((argc < 3) || (argc > 4) ) {
cout << "Usage: qchar n matrix" << endl;
return -1;
}
size_t n = atoi(argv[1]);
cout << "Matrix size " << n<< endl;
string filename;
filename=argv[2];
Integers Z;
Rationals Q;
Integer detPrec = 1;
Integer detNum;
Integer detDen;
Blackbox DM(Z,n,n);
RBlackbox M(Q,n,n);
DVector V(n,1);
cout << "detPrec is " << detPrec << "\n";
IntPolRing::Element c_A;
Integer max = 1,min=0;
for (size_t i=0; i < n; ++i) {
for (size_t j=0; j < n; ++j) {
Integer a;
Q.convert(a,M.getEntry(i,j));
if (max < a)
max = a;
if (min > a)
min = a;
}
}
if (max<-min)
max=-min;
else max = max+1;
double hadamarcp = (double)n/2.0*(log(double(n))+2*log(double(max))+0.21163275)/log(2.0);
cout << "had" << hadamarcp << "\n";
cout << "had2" << (Integer)hadamarcp*detPrec << "\n";
MyMethod Met;
PrecRationalModularMinpoly< RBlackbox ,MyMethod> iteration(V, M, Met);
cra (c_A, iteration, genprime);
return 0 ;
}
void continuedFractionIn(Integer& num, Integer& den, double epsi,const size_t s, Integer den_bound)
{
Integer a=num;
Integer b=den;
Integer t;
Integer f[s];
f[0] = a/b;
int i=1;
while (1)
{
t = a%b;
a = b;
b = t;
f[i] = a/b;
num = 1;
den = f[i];
for (int j=i-1; j > 0; --j) {
Integer tmp = num;
num = den;
den = f[j]*den+tmp;
}
num = den*f[0]+num;
if (den >= den_bound) break;
++i;
if (i >= s) {
break;
}
}
}
{
detPrec=1;
Rationals Q;
for (int i=0; i < den.size();++i) den[i]=1;
for (int i=0; i < n; ++i) {
for (int j=0; j <=i ; ++j) {
Integer q_num =0;
Integer q_den =1;
for (int k=0; k < n; ++k) {
Integer deno_ik, nume_ik, deno_jk, nume_jk, deno, nume;
if (i==k) {
nume_ik = deno_ik-nume_ik;
}
else {
nume_ik = -nume_ik;
}
if (j==k) {
nume_jk = deno_jk-nume_jk;
}
else {
nume_jk = -nume_jk;
}
deno = deno_ik*deno_jk;
nume = nume_ik*nume_jk;
if (deno==q_den) q_num+=nume;
else {
if (nume != 0) {
Integer g = gcd(q_den, deno);
q_num = q_num*deno/g+nume*q_den/g;
q_den = q_den*deno/g;
}
}
}
if (q_num != 0) {
if (i!=j) {
den[i]=lcm(den[i], q_den);
den[j]=lcm(den[j], q_den);
Res.setEntry(i,j,q);
Res.setEntry(j,i,q);
cout << i << " " << j << " " << q_num << "/" << q_den << "\n";
cout << j << " " << i << " " << q_num << "/" << q_den << "\n";
}
else {
den[i]=lcm(den[i], q_den);
Res.setEntry(i,j,q);
cout << i << " " << j << " " << q_num << "/" << q_den << "\n";
}
}
}
}
Integer d = 1;
for (int i=0; i < den.size(); ++i) {
detPrec *=den[i];
d = lcm(d, den[i]);
}
den[den.size()-1]=d;
for (int i=den.size()-2; i >=0; --i) {
den[i]=d*den[i+1];
}
}
template <class RMatrix>
{
int prec=10;
denPrec = 1;
ifstream is(filename.c_str(), std::ios::in);
int m,n;
char c;
is >> m >> n;
do is >> c; while (isspace (c));
cout << m << " " << n << " " ;
cout << "Wrong matrix size\n";
return;
}
cout << "Reading matrix\n";
den.resize(m,1);
while (1) {
#if 0
while (is >> m)
if (m==0) break;
#endif
is >> m;
is >> n;
#if 0
cout << m << n << "\n";
long double x;
is >> x;
#endif
char xstr[500];
char numstr[500];
#if 0
cout << x << " ";
sprintf(xstr, "%100f", x);
cout << xstr << " " ;
is >> c; int i=0;
while (c!= '\n') {
xstr[i]=c;
++i;
is >> c;
if (i>=199) {
xstr[i]=0;
break;
}
}
is >> c;
#endif
is.getline(xstr,500);
Integer ten=1;
if (strchr(xstr, '/') != NULL) {
strcpy(numstr, strtok(xstr, "/"));
char tenstr[500];
strcpy(tenstr, strtok(NULL, "/"));
if (prec < strlen(tenstr)) {
int cut = strlen(tenstr)-prec;
tenstr[prec]=0;
numstr[strlen(numstr)-cut]=0;
}
Integer tmp(tenstr);
ten = tmp;
}
else
{
int i=0;
int j=0;
c=xstr[i]; ++i;
while (isspace (c)) {
if (i >=strlen(xstr)) break;
c=xstr[i];
++i;
}
if (c=='-') {
numstr[j]=c;++j;
if (i < strlen(xstr)) {
c = xstr[i];
++i;
}
}
if (c=='0') {
if (i < strlen(xstr)) {
c = xstr[i];
++i;
}
}
while (strchr("0123456789",c) != NULL) {
numstr[j]=c; ++j;
if (i >=strlen(xstr)) break;
c=xstr[i];
++i;
}
if (c=='.') {
if (i < strlen(xstr)) {
c = xstr[i];
++i;
while (strchr("0123456789",c) != NULL) {
numstr[j]=c;++j;
if (i >=strlen(xstr)) break;
c=xstr[i];
++i;
}
}
else {
cout << "wrong number format at .";
break;
}
}
numstr[j]=0;
size_t dplaces=0;
int exp=0;
j=0;
c = xstr[j]; ++j;
while (c != '.') {
if (j >= strlen(xstr)) break;
c = xstr[j];
++j;
}
if (j < strlen(xstr)) {
c = xstr[j]; ++j;
while (c != 'e') {
++dplaces;
ten *= 10;
if (j >= strlen(xstr)) break;
c = xstr[j];
++j;
}
}
if (j < strlen(xstr)) {
sscanf(xstr+j, "%d", &exp);
j=j-2;c = xstr[j];
while (c=='0') {
ten/=10;
--j;
c = xstr[j];
}
}
dplaces -=exp;
if (exp > 0) {
for (int i=0; i < exp; ++i) ten /=10;
}
else if (exp < 0) {
for (int i=0; i < exp; ++i) ten *=10;
}
}
Integer num (numstr);
Integer g;
#ifdef _LB_CONT_FR
double epsi = 1/(double)ten*10;
size_t s=10;
continuedFractionIn(num, ten, epsi, s, ten);
#endif
g = gcd(num,ten);
if ((m==0)&&(n==0)&&(num==0)) break;
den[m-1] = lcm(den[m-1],ten/g);
}
Integer d = 1;
for (int i=0; i < den.size(); ++i) {
denPrec *=den[i];
d = lcm(d, den[i]);
}
den[den.size()-1]=d;
cout << d << "\n";
for (int i=den.size()-2; i >=0; --i) {
den[i]=d*den[i+1];
cout << den[i] << "\n";
}
}
#undef _LB_CONT_FR