Characteristic polynomial of matrix over Z or Zp.
#include <iostream>
#include <iomanip>
#include "linbox/field/unparametric.h"
#include "linbox/blackbox/sparse.h"
#include "linbox/solutions/charpoly.h"
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 << " + ";
}
return out;
}
template <class Field, class Polynomial>
std::ostream& prettyprintIntegerPolynomial (std::ostream& out, const Field &F, const Polynomial &v)
{
size_t n = v.size()-1;
if (n == 0) {
F.write(out, v[0]);
}
else {
if(v[n] != 0) {
if (v[n] != 1) F.write(out, v[n]) << '*';
out << 'X';
if (n > 1) out << '^' << n;
for (int i = (int)n - 1; i > 0; i--) {
if (v[i] != 0) {
if (v[i] >0) out << " + ";
if (v[i] != 1) F.write (out, v[i]) << '*';
out << 'X';
if (i > 1) out << '^' << i;
}
}
if (v[0] != 0) {
if (v[0] >0) out << " + ";
F.write(out, v[0]);
}
}
}
return out;
}
template <class Field, class Factors, class Exponents>
std::ostream& printFactorization (std::ostream& out, const Field &F, const Factors &f, const Exponents& exp)
{
typename Factors::const_iterator itf = f.begin();
typename Exponents::const_iterator ite = exp.begin();
for ( ; itf != f.end(); ++itf, ++ite) {
prettyprintIntegerPolynomial(out << '(', F, *(*itf)) << ')';
if (*ite > 1) out << '^' << *ite;
out << endl;
}
return out;
}
int main (int argc, char **argv)
{
commentator().
setMaxDetailLevel (2);
commentator().
setMaxDepth (2);
commentator().
setReportStream (std::cerr);
cout<<setprecision(8);
cerr<<setprecision(8);
if (argc < 2 || argc > 3) {
cerr << "Usage: charpoly <matrix-file-in-SMS-format> [<p>]" << endl;
return -1;
}
ifstream input (argv[1]);
if (!input) { cerr << "Error opening matrix file " << argv[1] << endl; return -1; }
if (argc == 2) {
IntPolRing::Element c_A;
Timer tim; tim.clear();tim.start();
tim.stop();
cout << "Characteristic Polynomial is ";
cout << tim << endl;
#ifdef __LINBOX_HAVE_NTL
cout << "Do you want a factorization (y/n) ? ";
char tmp;
cin >> tmp;
if (tmp == 'y' || tmp == 'Y') {
commentator().
start(
"Integer Polynomial factorization by NTL",
"NTLfac");
vector<IntPolRing::Element*> intFactors;
vector<unsigned long> exp;
IntPolRing IPD(ZZ);
tim.start();
IPD.
factor (intFactors, exp, c_A);
tim.stop();
commentator().
stop(
"done", NULL,
"NTLfac");
printFactorization(cout << intFactors.size() << " integer polynomial factors:" << endl, ZZ, intFactors, exp) << endl;
vector<IntPolRing::Element*>::const_iterator itf = intFactors.begin();
for ( ; itf != intFactors.end(); ++itf)
delete *itf;
cout << tim << endl;
}
#endif
}
if (argc == 3) {
double q = atof(argv[2]);
Field F(q);
cout <<
"B is " << B.
rowdim() <<
" by " << B.
coldim() << endl;
GivPolynomialRing<Field, Givaro::Dense>::Element c_B;
Timer tim; tim.clear();tim.start();
charpoly (c_B, B);
tim.stop();
cout << "Characteristic Polynomial is ";
cout << tim << endl;
}
return 0;
}