Codebase list eclib / 352dcf3
Imported Upstream version 2015-02-28 Julien Puydt 9 years ago
30 changed file(s) with 457 addition(s) and 312 deletion(s). Raw diff Collapse all Expand all
22 # Process this file with autoconf to produce a configure script.
33
44 AC_PREREQ([2.65])
5 AC_INIT([eclib], [20141106], [john.cremona@gmail.com])
5 AC_INIT([eclib], [20150228], [john.cremona@gmail.com])
66 AM_INIT_AUTOMAKE([-Wall])
77 AC_MSG_NOTICE([Configuring eclib...])
88 AC_CONFIG_SRCDIR([libsrc])
99 #AC_CONFIG_HEADERS([config.h])
1010 AC_CONFIG_MACRO_DIR([m4])
11 AM_PROG_AR
1112
1213 # Initialise libtools:
1314 LT_INIT
2021
2122 # Checks for system features and libraries, via macros defined in m4/ directory
2223 AX_CXX_COMPILE_STDCXX_0X
24 # Uncomment this to check for C++-11 compliance (no C++-11 features are used)
2325 #AX_CXX_COMPILE_STDCXX_11([],[optional])
2426 AX_CXX_HEADER_TR1_UNORDERED_MAP
2527 AX_CXX_HEADER_UNORDERED_MAP
7878 }
7979
8080 // The quantity called C_1 in the paper, = Norm(h2-h0) and should be
81 // POSITIVE for a reduced form:
81 // NON-NEGATIVE for a reduced form:
8282
8383 bigint cubic::j_c1() const
8484 {
108108 }
109109
110110 // MINUS the quantity called C_2 in the paper, = -Norm(h0-h1) and should be
111 // NEGATIVE for a reduced form:
111 // NON-POSITIVE for a reduced form:
112112
113113 bigint cubic::j_c2() const
114114 {
143143 // POSITIVE for a reduced form:
144144
145145 bigint cubic::j_c3() const
146 {
146 {
147147 bigint a = coeffs[0], b=coeffs[1], c=coeffs[2], d=coeffs[3];
148148 bigint b2=b*b;
149149 bigint b3=b*b2;
169169 + 27*a2*b2*c2 + 6*b5*c - 648*b2*c*a2*d + 162*a*d*b4 + 1458*a3*d2*b;
170170 }
171171
172 // The quantity C_4 (not in the paper), = Norm(h1)/8 and should be
173 // NON-NEGATIVE for a reduced form with C1=0 (i.e. when h0=h2 we want h1>=0).
174
175 bigint cubic::j_c4() const
176 {
177 bigint a = coeffs[0], b=coeffs[1], c=coeffs[2], d=coeffs[3];
178 bigint b2=b*b;
179 bigint b3=b*b2;
180 bigint b4=b*b3;
181 bigint a2=a*a;
182 bigint c2=c*c;
183 bigint c3=c*c2;
184
185 return 27*d*c3*a2 + (27*d^2*b3 - 54*d*c2*b2 + 9*c^4*b)*a + 9*d*c*b4 - 2*c3*b3;
186 }
187
172188 //#define DEBUG
173189
174190 bigcomplex cubic::hess_root() const
175191 {
176192 bigfloat discr = I2bigfloat(disc());
177 if(!is_positive(disc()))
193 if(!is_positive(disc()))
178194 {
179195 cout<<"Error: hess_root called with negative dicriminant!\n";
180196 return to_bigfloat(0);
183199 bigfloat Q = I2bigfloat(q_semi());
184200 bigfloat delta = sqrt(3*discr);
185201 bigcomplex gamma(-Q,delta); gamma/=(2*P);
186 return gamma;
202 return gamma;
187203 }
188204
189205 void cubic::hess_reduce(unimod& m)
194210 while(s)
195211 {
196212 s=0;
213 // NB roundover(a,b) returns c such that a/b=c+x and -1/2 < x <= 1/2,
214 // so after the shift (when P>0) we have -P <= Q < P.
197215 k = roundover(-q_semi(),2*p_semi());
198216 if(!is_zero(k))
199217 {
209227 cout << "invert: " << (*this) << endl;
210228 #endif
211229 }
230 }
231 // Now we have -P <= Q < P <= R and test for boundary condition
232 if((p_semi()==r_semi()) && (q_semi()<0))
233 {
234 invert(m);
235 #ifdef DEBUG
236 cout << "Final inversion: " << (*this) << endl;
237 #endif
212238 }
213239 if(a()<0) {::negate(coeffs[0]); ::negate(coeffs[2]);}
214240 }
220246 while(s)
221247 {
222248 s=0;
223 if(mat_c1()<0)
249 if(mat_c1()<0)
224250 {
225251 s=1; invert(m);
226252 #ifdef DEBUG
238264 #endif
239265 }
240266 bigint plus1, minus1; plus1=1; minus1=-1;
241 while(mat_c2()>0)
267 while(mat_c2()>0)
242268 {
243269 s=1; x_shift(plus1,m);
244270 #ifdef DEBUG
245271 cout << "Shift by +1: "<<(*this)<<endl;
246272 #endif
247273 }
248 while(mat_c3()<0)
274 while(mat_c3()<0)
249275 {
250276 s=1; x_shift(minus1,m);
251277 #ifdef DEBUG
265291 while(s)
266292 {
267293 s=0;
268 if(j_c1()<0)
294 if(j_c1()<0)
269295 {
270296 s=1; invert(m);
271297 #ifdef DEBUG
272298 cout << "invert: " << (*this) << endl;
273299 #endif
274300 }
275 bigfloat alpha = real_root();
276 bigfloat ra = I2bigfloat(a());
277 bigfloat rb = I2bigfloat(b());
278 bigfloat rc = I2bigfloat(c());
279 bigfloat h0 = (9*ra*ra*alpha + 6*ra*rb)*alpha + 6*ra*rc-rb*rb;
280 bigfloat h1 = 6*(ra*rb*alpha + (rb*rb-ra*rc))*alpha + 2*rb*rc;
281 k = Iround(-h1/(2*h0));
282 if (k!=0)
301 if ((j_c2()>0) || (j_c3()<0))
283302 {
284303 s=1;
285 x_shift(k,m);
286 #ifdef DEBUG
287 cout << "Initial shift by "<<k<<": "<<(*this)<<endl;
288 #endif
304 bigfloat alpha = real_root();
305 bigfloat ra = I2bigfloat(a());
306 bigfloat rb = I2bigfloat(b());
307 bigfloat rc = I2bigfloat(c());
308 bigfloat h0 = (9*ra*ra*alpha + 6*ra*rb)*alpha + 6*ra*rc-rb*rb;
309 bigfloat h1 = 6*(ra*rb*alpha + (rb*rb-ra*rc))*alpha + 2*rb*rc;
310 #ifdef DEBUG
311 cout << "h0 = "<<h0<<endl;
312 cout << "h1 = "<<h1<<endl;
313 cout << "-h1/(2*h0) = "<<(-h1/(2*h0))<<endl;
314 #endif
315 k = Iround(-h1/(2*h0));
316 if (k!=0)
317 {
318 x_shift(k,m);
319 #ifdef DEBUG
320 cout << "Initial shift by "<<k<<": "<<(*this)<<endl;
321 #endif
322 }
323 // Two loops to guard against rounding error in computing k:
324 while(j_c2()>0)
325 {
326 x_shift(minus1,m);
327 #ifdef DEBUG
328 cout << "Shift by -1: "<<(*this)<<endl;
329 #endif
330 }
331 while(j_c3()<0)
332 {
333 x_shift(plus1,m);
334 #ifdef DEBUG
335 cout << "Shift by +1: "<<(*this)<<endl;
336 #endif
337 }
289338 }
290 while(j_c2()>0)
291 {
292 s=1; x_shift(minus1,m);
293 #ifdef DEBUG
294 cout << "Shift by -1: "<<(*this)<<endl;
295 #endif
296 }
297 while(j_c3()<0)
298 {
299 s=1; x_shift(plus1,m);
300 #ifdef DEBUG
301 cout << "Shift by +1: "<<(*this)<<endl;
302 #endif
303 }
304 #ifdef DEBUG
305 cout<<"C1="<<j_c1()<<", C2="<<j_c2()<<", C3="<<j_c3()<<endl;
306 #endif
307 }
308 if(a()<0) {::negate(coeffs[0]); ::negate(coeffs[1]);}
339 if ((j_c1()==0) && (j_c4()<0))
340 {
341 s=1; invert(m);
342 #ifdef DEBUG
343 cout << "invert: " << (*this) << endl;
344 #endif
345 }
346 #ifdef DEBUG
347 cout<<"C1="<<j_c1()<<", C2="<<j_c2()<<", C3="<<j_c3()<<", C4="<<j_c4()<<endl;
348 #endif
349 }
350 if(a()<0) {::negate(coeffs[0]); ::negate(coeffs[2]);}
309351 }
310352
311353 // Just shifts x:
101101 bigint j_c1() const;
102102 bigint j_c2() const;
103103 bigint j_c3() const;
104 bigint j_c4() const;
104105
105106 bigcomplex hess_root() const;
106107 bigfloat real_root() const; // requires disc<0
6868 mat& operator*=(scalar);
6969 mat& operator/=(scalar);
7070 const scalar* get_entries()const{return entries;}
71 long nrows() const {return nro;}
72 long ncols() const {return nco;}
73 long rank() const;
74 long nullity() const;
75 long trace() const;
76 vector<long> charpoly() const;
77 long determinant() const;
7178 void output(ostream&s=cout) const;
7279 void output_pari(ostream&s=cout) const;
7380 void output_pretty(ostream&s=cout) const;
7582 void read_from_file(string filename); // binary input
7683
7784 // non-member (friend) functions and operators
78 friend long nrows(const mat&);
79 friend long ncols(const mat&);
8085 friend void add_row_to_vec(vec& v, const mat& m, long i);
8186 friend void sub_row_to_vec(vec& v, const mat& m, long i);
8287 friend mat operator*(const mat&, const mat&);
135140 mat submat(const mat& m, const vec& iv, const vec& jv);
136141 mat echelon(const mat& m, vec& pcols, vec& npcols,
137142 long& rk, long& ny, scalar& d, int method=0); // default method 0: scalars
138 long rank(const mat&);
139 long nullity(const mat&);
140 long trace(const mat&);
141 vector<long> charpoly(const mat&);
142 long determinant(const mat&);
143143 mat addscalar(const mat&, scalar);
144144 vec apply(const mat&, const vec&);
6363 //the parameter here is a dummy just to distinguish these
6464 mat_i shorten(int) const;
6565 mat_l shorten(long) const;
66 long nrows() const {return nro;}
67 long ncols() const {return nco;}
68 long rank() const;
69 long nullity() const;
70 bigint trace() const;
71 vector<bigint> charpoly() const;
72 bigint determinant() const;
6673
6774 // non-member (friend) functions and operators
68 friend long nrows(const mat_m&);
69 friend long ncols(const mat_m&);
7075 friend mat_m operator*(const mat_m&, const mat_m&);
7176 friend vec_m operator*(const mat_m&, const vec_m&);
7277 friend int operator==(const mat_m&, const mat_m&);
114119 long& rk, long& ny, bigint& d, int method=0);
115120 mat_m echelon(const mat_m& m, vec_l& pcols, vec_l& npcols,
116121 long& rk, long& ny, bigint& d, int method=0);
117 long rank(const mat_m&);
118 long nullity(const mat_m&);
119 bigint trace(const mat_m&);
120 vector<bigint> charpoly(const mat_m&);
121 bigint determinant(const mat_m&);
122122 mat_m addscalar(const mat_m&, const bigint&);
123123 vec_m apply(const mat_m&, const vec_m&);
124124
8080 msubspace peigenspace(const mat_m& mat, const bigint& lambda, const bigint& pr);
8181 msubspace psubeigenspace(const mat_m& mat, const bigint& l, const msubspace& s, const bigint& pr);
8282
83 inline int dim(const msubspace& s) {return ncols(s.basis);} // the dimension
83 inline int dim(const msubspace& s) {return s.basis.ncols();} // the dimension
8484 inline bigint denom(const msubspace& s) {return s.denom;} // the denominator
8585 inline vec_i pivots(const msubspace& s) {return s.pivots;} // the pivot vector
8686 inline mat_m basis(const msubspace& s) {return s.basis;} // the basis matrix
6464 smat select_rows(const vec& rows) const;
6565 void setrow ( int i, const svec& v); // i counts from 1
6666 svec row(int) const; // extract row i as an svec
67
67 int nrows() const {return nro;}
68 int ncols() const {return nco;}
69 long rank(scalar mod=DEFAULT_MODULUS);
70 long nullity(const scalar& lambda, scalar mod=DEFAULT_MODULUS); // nullity of this-lambda*I
71
6872 // non-member (friend) functions and operators
6973
70 friend inline int nrows(const smat& A) {return A.nro;}
71 friend inline int ncols(const smat& A) {return A.nco;}
7274 friend inline vector<int> dim(const smat& A)
7375 {vector<int>d; d.push_back(A.nro);d.push_back(A.nco);return d;}
7476 friend vec operator* (smat& m, const vec& v);
6565 void remove( list& L ); // L must be ordered
6666 ordlist( int m = 10) : list(m) {;}
6767 };
68
68
6969 scalar modulus;
7070 int rank;
71
7172 ordlist* column; // an array of lists, oner per col, of row nos
7273 // which have nonzero entries in that col
73 int *position;
74 int *position;
7475 int *elim_col; // in which row was col eliminated;
7576 int *elim_row; //order of elimination of rows;
7677 void clear_col(int,int,list&, int fr = 0, int fc = 0,int M = 0,int *li =0);
8283 long n_active_entries(); // number of active entries
8384 double active_density(); // density of non-eliminated part
8485 void report(); // report current state (density etc)
85
86
8687 public:
8788 int get_rank( ) { return rank; }
8889 void init( );
117118 return s;
118119 }
119120
120 long rank(smat& sm, scalar mod=DEFAULT_MODULUS);
121
122 inline long nullity(const smat& sm, const scalar& lambda, scalar mod=DEFAULT_MODULUS) // nullity of sm-lambda*I
123 {
124 smat sma(sm); sma-=lambda; return ncols(sm)-rank(sma,mod);
125 }
126
127121 class ssubspace {
128122
129123 public:
143137 inline scalar mod() const {return modulus;} // the (prime) modulus
144138
145139 // non-member (friend) functions and operators
146 friend int dim(const ssubspace& s) {return ncols(s.basis);}
140 friend int dim(const ssubspace& s) {return s.basis.ncols();}
147141 friend vec pivots(const ssubspace& s) {return s.pivots;}
148142 friend smat basis(const ssubspace& s) {return s.basis;}
149143 friend ssubspace combine(const ssubspace& s1, const ssubspace& s2);
7979 subspace psubeigenspace(const mat& m, scalar l, const subspace& s, scalar pr);
8080
8181
82 inline int dim(const subspace& s) {return ncols(s.basis);} // the dimension
82 inline int dim(const subspace& s) {return s.basis.ncols();} // the dimension
8383 inline scalar denom(const subspace& s) {return s.denom;} // the denominator
8484 inline vec pivots(const subspace& s) {return s.pivots;} // the pivot vector
8585 inline mat basis(const subspace& s) {return s.basis;} // the basis matrix
794794 cout<<"In comp_map_image, m="<<m;
795795 cout<<"moduli = "<<moduli<<endl;
796796 #endif
797 int npts=nrows(m), np=ncols(m);
797 int npts=m.nrows(), np=m.ncols();
798798 int i, j, jj;
799799 if(np==0) return ans;
800800 for(j=1; j<=np; j++)
0 // parislave.cc: class for starting up a "slave" background gp process
1 //////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright 1990-2012 John Cremona
4 //
5 // This file is part of the eclib package.
6 //
7 // eclib is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2 of the License, or (at your
10 // option) any later version.
11 //
12 // eclib is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with eclib; if not, write to the Free Software Foundation,
19 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 //
21 //////////////////////////////////////////////////////////////////////////
22
23 #ifdef USE_GP_FACTORING
24
25 #include <unistd.h> // for unlink() (not needed on linux)
26 #include <sstream>
27 #include <eclib/gpslave.h>
28 #include <eclib/marith.h>
29
30 //#define DEBUG_PARI_SLAVE
31
32 parislave the_pari_slave; // The one and only instance
33
34 // test if we have an executable gp to use...
35 int do_we_have_pari(string& gp_path)
36 {
37 string path_to_gp(getenv("PATH_TO_GP"));
38 if (path_to_gp.str().size()==0)
39 gp_path = string("gp");
40 else
41 gp_path = string(path_to_gp)+string("gp");
42 string comm = string("[ -x ") + gp_path + string(" ]");
43 #ifdef DEBUG_PARI_SLAVE
44 cout<<"In do_we_have_pari, command="<<comm<<endl;
45 #endif
46 return !system(comm.c_str());
47 }
48
49 parislave::parislave()
50 {
51 // test if we have an executable gp to use...
52 string gpcommand;
53 dummy = !do_we_have_pari(gpcommand);
54 if(dummy) return;
55
56 strcpy(gpinfilename,"/tmp/gp_in_XXXXXX");
57 mkstemp(gpinfilename);
58 string comm=string("rm ")+gpinfilename; system(comm.c_str());
59 #ifdef DEBUG_PARI_SLAVE
60 cout<<"Using file "<<gpinfilename<<" for gp input"<<endl;
61 #endif
62
63 comm = string("mkfifo -m 600 ")+gpinfilename;
64 #ifdef DEBUG_PARI_SLAVE
65 cout<<"About to run command "<<comm<< " via system() call"<<endl;
66 #endif
67 system(comm.c_str());
68
69 comm = gpcommand+" -q -f < "+gpinfilename;
70 #ifdef DEBUG_PARI_SLAVE
71 cout<<"About to call popen( "<<comm<< " )"<<endl;
72 #endif
73 gp = popen(comm.c_str(),"r");
74 gpin.open(gpinfilename);
75 }
76
77 parislave::~parislave()
78 {
79 if(dummy) return;
80 #ifdef DEBUG_PARI_SLAVE
81 cout<< "Shutting down gp process..."<<endl;
82 #endif
83 ofstream gpin(gpinfilename);
84 gpin <<"\\q\n"<<flush; // to shut down the gp process
85 #ifdef DEBUG_PARI_SLAVE
86 cout<< "Deleting temp file "<<gpinfilename<<endl;
87 #endif
88 /*
89 string comm("rm ");
90 comm+=gpinfilename;
91 system(comm.c_str());
92 */
93 unlink(gpinfilename);
94 }
95
96 int parislave::is_prime(const bigint& n)
97 {
98 if(dummy)
99 {
100 #ifdef DEBUG_PARI_SLAVE
101 cout<<"dummy call to pari_slave::is_prime(): no gp running!"<<endl;
102 #endif
103 return 1;
104 }
105 #ifdef DEBUG_PARI_SLAVE
106 cout << "Writing to gp's input stream: "
107 << "print(isprime(" << n << "))\n"<<flush;
108 #endif
109 gpin << "print(isprime(" << n << "))\n"<<flush;
110 #ifdef DEBUG_PARI_SLAVE
111 cout << "Reading from gp's output stream"<<endl;
112 #endif
113 int ans;
114 fscanf(gp,"%s",gpoutput);
115 #ifdef DEBUG_PARI_SLAVE
116 cout<<"just read "<<gpoutput<<" from gp output"<<endl;
117 #endif
118 istringstream gpout(gpoutput);
119 gpout>>ans;
120 #ifdef DEBUG_PARI_SLAVE
121 cout<<"Read ans="<<ans<<" from gp output"<<endl;
122 cout<<"Finished reading from gp output"<<endl;
123 #endif
124 return ans;
125 }
126
127 vector<bigint> parislave::factor(const bigint& n, int proof)
128 {
129 vector<bigint> plist; bigint p;
130 if(dummy)
131 {
132 #ifdef DEBUG_PARI_SLAVE
133 cout<<"Calling pdivs_trial()"<<endl;
134 #endif
135 return pdivs_trial(n);
136 }
137 #ifdef DEBUG_PARI_SLAVE
138 cout << "Writing to gp's input stream: "
139 << "print(Vec(factor(" << n << ")[,1]))\n"<<flush;
140 #endif
141 gpin << "print(Vec(factor(abs(" << n << "))[,1]))\n"<<flush;
142 #ifdef DEBUG_PARI_SLAVE
143 cout << "Reading from gp's output stream"<<endl;
144 #endif
145 int first=1; char c = ',';
146 while(c!=']')
147 {
148 fscanf(gp,"%s",gpoutput);
149 #ifdef DEBUG_PARI_SLAVE
150 cout<<"just read "<<gpoutput<<" from gp output"<<endl;
151 #endif
152 istringstream gpout(gpoutput);
153 if(first) gpout>>skipws>>c; // swallow leading "["
154 first=0;
155 gpout>>p;
156 #ifdef DEBUG_PARI_SLAVE
157 cout<<"Reading p="<<p<<" from gp output"<<endl;
158 #endif
159 plist.push_back(p);
160 gpout>>skipws>>c>>skipws; // swallow ",", but it might turn out to be "]"
161 }
162 #ifdef DEBUG_PARI_SLAVE
163 cout<<"Finished reading from gp output"<<endl;
164 if(proof) cout<<"Proving primality of factors found..."<<flush;
165 #endif
166 if(proof)
167 for(vector<bigint>::const_iterator pi=plist.begin(); pi!=plist.end(); pi++)
168 {
169 p =*pi;
170 if(!is_prime(p))
171 {
172 cout<<"WARNING: pari's factor() returned p="<<p<<" for which isprim(p) FAILS!! Please report.";
173 }
174 }
175 return plist;
176 }
177 #endif // USE_GP_FACTORING
299299 cout << "pivots = "<<pivs << endl;
300300 cout << "denom = "<<d1 << endl;
301301 }
302 rk = ncols(sp);
302 rk = sp.ncols();
303303 coord_vecs.resize(ngens+1); // 0'th is unused
304 for(i=1; i<=ngens; i++)
304 for(i=1; i<=ngens; i++)
305305 coord_vecs[i]=sp.row(i);
306306 //sp=smat(0,0); // clear space
307307 #else
404404 }
405405 if (verbose)
406406 {
407 cout << "delta matrix done: size "<<nrows(deltamat)<<"x"<<ncols(deltamat)<<". "<<endl;
407 cout << "delta matrix done: size "<<deltamat.nrows()<<"x"<<deltamat.ncols()<<". "<<endl;
408408 if(verbose>1)
409409 cout<<"deltamat = "<<deltamat<<endl;
410410 cout << "About to compute kernel of delta"<<endl;
514514 long i= coordindex[ind];
515515 if (i>0) return m.row(i);
516516 if (i<0) return -m.row(-i);
517 return vec(ncols(m));
517 return vec(m.ncols());
518518 }
519519
520520 long homspace::nfproj_coords_from_index(int ind, const vec& bas) const
609609
610610 vec homspace::proj_coords(long nn, long dd, const mat& m) const
611611 {
612 vec ans = vec(ncols(m));
612 vec ans = vec(m.ncols());
613613 add_proj_coords(ans, nn, dd, m);
614614 return ans;
615615 }
328328
329329 // Definitions of non-member, friend operators and functions
330330
331 long nrows(const mat& m) {return m.nro;}
332 long ncols(const mat& m) {return m.nco;}
333
334331 // add/sub row i of mat to v (implemented in mat.cc)
335332 void add_row_to_vec(vec& v, const mat& m, long i)
336333 {
672669 mat transpose(const mat& m)
673670 {
674671 long i,j,nr,nc;
675 nr=ncols(m); nc=nrows(m);
672 nr=m.ncols(); nc=m.nrows();
676673 mat ans(nr, nc);
677674 for (i=1; i<=nr; i++)
678675 for (j=1; j<=nc; j++)
953950 return ans;
954951 }
955952
956 // Original version
957
958 // mat echelon0(const mat& entries, vec& pcols, vec& npcols,
959 // long& rk, long& ny, long& d)
960 // {
961 // long nc, nr;
962 // long r,c,r2,r3,rmin;
963 // long min, mr2c,lastpivot;
964 // rk=0; ny=0; r=1; lastpivot=1;
965 //
966 // mat m(entries);
967 // nc=ncols(m); nr=nrows(m);
968 // pcols.init(nc);
969 // npcols.init(nc);
970 // for (c=1; (c<=nc)&&(r<=nr); c++)
971 // {min = abs(m(r,c));
972 // rmin = r;
973 // for (r2=r+1; (r2<=nr)&&(min!=1); r2++)
974 // { mr2c = abs(m(r2,c));
975 // if ((0<mr2c) && ((mr2c<min) || (min==0))) { min=mr2c; rmin=r2 ;}
976 // }
977 // if (min==0) npcols[++ny] = c;
978 // else
979 // {pcols[++rk] = c;
980 // if (rmin>r) m.swaprows(r,rmin);
981 // for (r3 = r+1 ; r3<=nr; r3++)
982 // elimrows2(m,r,r3,c,lastpivot);
983 // lastpivot=min;
984 // r++;
985 // }
986 // }
987 // for (c = rk+ny+1; c<=nc; c++) npcols[++ny] = c;
988 // pcols = pcols.slice(rk);
989 // npcols = npcols.slice(ny); // truncate index vectors
990 // // cout << "In echelon:\n";
991 // // cout << "pcols = " << pcols << "\n";
992 // // cout << "npcols = " << npcols << "\n";
993 // d=1;
994 // lastpivot=1;
995 // if (ny>0)
996 // {for (r=1; r<=rk; r++) m.clearrow(r);
997 // for (r=1;r<=rk; r++)
998 // for (r2=r+1; r2<=rk; r2++)
999 // elimrows1(m,r2,r,pcols[r2]);
1000 // for (r=1; r<=rk; r++)
1001 // d = (d*m(r,pcols[r]))/gcd(d,m(r,pcols[r]));
1002 // d = abs(d);
1003 // for (r=1; r<=rk; r++)
1004 // {long fac = d/m(r,pcols[r]);
1005 // m.multrow(r,fac);
1006 // }
1007 // }
1008 // else
1009 // for (r=1; r<=rk; r++)
1010 // for (c=1; c<=nc; c++)
1011 // m.set(r,c, (c==pcols[r])); // 0 or 1 !
1012 // return m.slice(rk,nc);
1013 // }
1014
1015 long rank(const mat& entries)
953 long mat::rank() const
1016954 {
1017955 long rk,nr,nc,r,c,r2,r3,rmin;
1018956 long min, mr2c,lastpivot;
1019957 rk=0; r=1; lastpivot=1;
1020 mat m(entries);
1021 nc=ncols(m); nr=nrows(m);
958 mat m(*this);
959 nc=m.ncols(); nr=m.nrows();
1022960 for (c=1; (c<=nc)&&(r<=nr); c++)
1023961 { min = abs(m(r,c));
1024962 rmin = r;
1038976 return rk;
1039977 }
1040978
1041 long nullity(const mat& m)
1042 {
1043 return ncols(m)-::rank(m);
1044 }
1045
1046 long trace(const mat& a)
1047 { long i; long ans=0;
1048 for (i=1; i<=nrows(a); i++) ans += a(i,i);
979 long mat::nullity() const
980 {
981 return nco-rank();
982 }
983
984 long mat::trace() const
985 { long i=0; scalar* aii=entries; long ans=0;
986 for (; i<nro; i++, aii+=(nco+1))
987 ans += *aii;
1049988 return ans;
1050989 }
1051
1052 /* OLD VERSION
1053 vector<long> charpoly(const mat& a)
1054 { long i,k,r,n = nrows(a);
1055 vec tlist = vec(n);
1056 mat apower(a);
1057 vector<long> clist(n+1);
1058 tlist[1] = trace(a);
1059 for (i=2; i<=n; i++)
1060 { apower*=a;
1061 tlist[i] = trace(apower);
1062 }
1063 clist[n]=1;
1064 for (k=1; k<=n; k++)
1065 { long temp = 0;
1066 for (r=1; r<=k; r++) temp+= tlist[r]*clist[n+r-k];
1067 clist[n-k]= -temp/k;
1068 }
1069 return clist;
1070 }
1071 */
1072
1073 // NEW VERSION -- FADEEV'S METHOD
1074
1075 vector<long> charpoly(const mat& a)
1076 { long n = nrows(a);
1077 mat b(a);
990
991 // FADEEV'S METHOD
992
993 vector<long> mat::charpoly() const
994 { long n = nrows();
995 mat b(*this);
1078996 mat id(idmat((scalar)n));
1079997 vector<long> clist(n+1);
1080 long t = trace(a);
998 long t = trace();
1081999 clist[n] = 1;
10821000 clist[n-1] = -t;
10831001 for (long i=2; i<=n; i++)
1084 { b=a*(b-t*id); // cout << b; // (for testing only)
1085 t=trace(b)/i;
1002 { b=(*this)*(b-t*id); // cout << b; // (for testing only)
1003 t=b.trace()/i;
10861004 clist[n-i] = -t;
10871005 }
10881006 if (!(b==t*id))
10921010 return clist;
10931011 }
10941012
1095
1096 long determinant(const mat& m)
1097 {
1098 vector<long> cp = charpoly(m);
1099 long det = cp[0];
1100 if (nrows(m)%2==1) det=-det;
1101 return det;
1013 long mat::determinant() const
1014 {
1015 long det = charpoly()[0];
1016 if (nrows()%2==1)
1017 return -det;
1018 else
1019 return det;
11021020 }
11031021
11041022 mat addscalar(const mat& m, scalar c)
11051023 {
1106 return m+(c*idmat((scalar)nrows(m)));
1024 return m+(c*idmat((scalar)m.nrows()));
11071025 }
11081026
11091027 vec apply(const mat& m, const vec& v) // same as *(mat, vec)
11101028 {
1111 long nr=nrows(m), nc=ncols(m);
1029 long nr=m.nrows(), nc=m.ncols();
11121030 vec ans(nr);
11131031 if (nc==dim(v))
11141032 for (long i=1; i<=nr; i++)
13731291 #endif /* TRACE */
13741292 long nc,nr,r,c,r2,r3,rmin;
13751293 scalar min, mr2c;
1376 nr=nrows(entries), nc=ncols(entries);
1294 nr=entries.nrows(), nc=entries.ncols();
13771295 mat m(nr,nc);
13781296 scalar *mij=m.entries, *entriesij=entries.entries;
13791297 long n=nr*nc;
15991517
16001518 mat ref_via_flint(const mat& M, scalar pr)
16011519 {
1602 long nr=nrows(M), nc=ncols(M);
1520 long nr=M.nrows(), nc=M.ncols();
16031521 long i, j;
16041522
16051523 // copy of the modulus for FLINT
16401558 mat ref_via_flint(const mat& M, vec& pcols, vec& npcols,
16411559 long& rk, long& ny, scalar pr)
16421560 {
1643 long nr=nrows(M), nc=ncols(M);
1561 long nr=M.nrows(), nc=M.ncols();
16441562 long i, j, k;
16451563
16461564 #ifdef TRACE_FLINT_RREF
18361754
18371755 double sparsity(const mat& m)
18381756 {
1839 long nr=nrows(m), nc=ncols(m);
1757 long nr=m.nrows(), nc=m.ncols();
18401758 if(nr==0) return 1;
18411759 if(nc==0) return 1;
18421760 scalar* matij=m.entries;
386386
387387 // Definitions of non-member, friend operators and functions
388388
389 long nrows(const mat_m& m) {return m.nro;}
390 long ncols(const mat_m& m) {return m.nco;}
391
392389 mat_m operator*(const mat_m& m1, const mat_m& m2)
393390 {
394391 long j,k, m=m1.nro, n=m1.nco, p=m2.nco;
597594 mat_m transpose(const mat_m& m)
598595 {
599596 long i,j,nr,nc;
600 nr=ncols(m); nc=nrows(m);
597 nr=m.ncols(); nc=m.nrows();
601598 mat_m ans(nr, nc);
602599 for (i=1; i<=nr; i++)
603600 for (j=1; j<=nc; j++)
746743 return ans;
747744 }
748745
749 long rank(const mat_m& m1)
746 long mat_m::rank() const
750747 {
751748 long rk,nr,nc,r,c,r2,r3,rmin;
752749 bigint min, mr2c,lastpivot;
753750 rk=0; r=1; lastpivot=1;
754 mat_m m(m1);
755 nc=ncols(m); nr=nrows(m);
751 mat_m m(*this);
752 nc=m.ncols(); nr=m.nrows();
756753 for (c=1; (c<=nc)&&(r<=nr); c++)
757754 { min = abs(m(r,c));
758755 rmin = r;
776773 return rk;
777774 }
778775
779 long nullity(const mat_m& m)
780 {
781 return ncols(m)-rank(m);
782 }
783
784 bigint trace(const mat_m& a)
785 { long i; bigint ans;
786 for (i=1; i<=nrows(a); i++) ans += a(i,i);
776 long mat_m::nullity() const
777 {
778 return ncols()-rank();
779 }
780
781 bigint mat_m::trace() const
782 { long i=0; bigint* aii=entries; bigint ans=BIGINT(0);
783 for (; i<nro; i++, aii+=(nco+1))
784 ans += *aii;
787785 return ans;
788786 }
789
790 // CHARPOLY -- FADEEV'S METHOD
791
792 vector<bigint> charpoly(const mat_m& a)
793 { long n = nrows(a);
794 mat_m b(a);
787
788 // FADEEV'S METHOD
789
790 vector<bigint> mat_m::charpoly() const
791 { long n = nrows();
792 mat_m b(*this);
795793 mat_m id(midmat(n)), tid;
796794 vector<bigint> clist(n+1);
797 bigint t = trace(a), ii;
795 bigint t = trace(), ii;
798796 clist[n] = 1;
799797 clist[n-1] = -t;
800798 for (long i=2; i<=n; i++)
801799 { tid=t*id;
802800 b-=tid;
803 b=b*a; // cout << b; // (for testing only)
801 b=b*(*this); // cout << b; // (for testing only)
804802 ii=i;
805 t=trace(b)/ii;
803 t=b.trace()/ii;
806804 clist[n-i] = -t;
807805 }
808806 tid=t*id;
814812 return clist;
815813 }
816814
817
818 bigint determinant(const mat_m& m)
819 {
820 vector<bigint> cp = charpoly(m);
821 bigint det = cp[0];
822 if (nrows(m)%2==1) det=-det;
823 return det;
815 bigint mat_m::determinant() const
816 {
817 bigint det = charpoly()[0];
818 if (nrows()%2==1)
819 return -det;
820 else
821 return det;
824822 }
825823
826824 mat_m addscalar(const mat_m& m, const bigint& c)
827825 {
828 mat_m ans(midmat(nrows(m)));
826 mat_m ans(midmat(m.nrows()));
829827 ans*=c;
830828 ans+=m;
831829 return ans;
833831
834832 vec_m apply(const mat_m& m, const vec_m& v) // same as *(mat_m, vec_m)
835833 {
836 long nr=nrows(m), nc=ncols(m);
834 long nr=m.nrows(), nc=m.ncols();
837835 vec_m ans(nr);
838836 if (nc==dim(v))
839837 for (long i=1; i<=nr; i++)
868866 #endif /* TRACE */
869867 long nc,nr,r,c,r2,r3,rmin;
870868 bigint min, mr2c,lastpivot, temp;
871 nr=nrows(m1), nc=ncols(m1);
869 nr=m1.nrows(), nc=m1.ncols();
872870 mat_m m(nr,nc);
873871 for (c=1; c<=nc; c++)
874872 for (r=1; r<=nr; r++) m(r,c)=mod(m1(r,c),pr);
6868 // N.B. The following check is strictly unnecessary and slows it down,
6969 // but is advisable!
7070 #ifdef CHECK_RESTRICT
71 int check = 1; n = nrows(sb);
71 int check = 1; n = sb.nrows();
7272 for (i=1; (i<=n) && check; i++)
7373 for (j=1; (j<=d) && check; j++)
7474 check = (dd*m.row(i)*sb.col(j) == sb.row(i)*ans.col(j));
8787 bigint d, zero; zero=0;
8888 vec_i pcols,npcols;
8989 mat_m m = echelon(mat,pcols,npcols, rank, nullity, d, method);
90 long dim = ncols(m);
90 long dim = m.ncols();
9191 mat_m basis(dim,nullity);
9292 for (n=1; n<=nullity; n++) basis.set(npcols[n],n,d);
9393 for (r=1; r<=rank; r++)
173173 long rank, nullity, n, r, i, j;
174174 vec_i pcols,npcols;
175175 mat_m m = echmodp(mat,pcols,npcols, rank, nullity, pr);
176 long dim = ncols(m);
176 long dim = m.ncols();
177177 mat_m basis(dim,nullity);
178178 bigint one; one=1;
179179 for (n=1; n<=nullity; n++) basis.set(npcols[n],n,one);
329329 vec_m nfd::ap(long p)
330330 {
331331 mat K = basis(h1->kern).as_mat();
332 long rk = nrows(K);
332 long rk = K.nrows();
333333 matop *matlist;
334334 long k,l,n = h1->modulus, dims=dim(S);
335335 vec_m apvec(dims);
372372 mat_m nfd::heckeop(long p)
373373 {
374374 mat K = basis(h1->kern).as_mat();
375 long rk = nrows(K);
375 long rk = K.nrows();
376376 matop *matlist;
377377 long j,k,l,n = h1->modulus, dimh=h1->h1dim(), dims=dim(S);
378378 int bad = ::divides(p,n);
423423
424424 bigint inverse(const mat_m& a, mat_m& ainv)
425425 {
426 long d = nrows(a);
426 long d = a.nrows();
427427 mat_m aug=colcat(a,midmat(d));
428428 long rk, ny; vec pc,npc; bigint denom;
429429 mat_m ref = echelon(aug, pc, npc, rk, ny, denom);
435435 void showmatrix(const mat_m& m)
436436 {
437437 #ifdef OUTPUT_PARI_STYLE
438 long i,j, nc=ncols(m),nr=nrows(m);
438 long i,j, nc=m.ncols(),nr=m.nrows();
439439 cout << "[";
440440 for(i=0; i<nr; i++)
441441 {
474474
475475 mat smat::operator*( const mat& m )
476476 {
477 if( nco != nrows(m) )
477 if( nco != m.nrows() )
478478 {
479479 cerr << "incompatible smat & mat in operator*\n";
480480 abort();
481481 }
482 mat product( nro, ncols(m) );
482 mat product( nro, m.ncols() );
483483 int i, j, d, t;
484484 scalar ans;
485485 for( i = 1; i <= nro; i++ )
486486 {
487487 d = col[i-1][0];
488 for( j = 1; j <= ncols(m); j++ )
488 for( j = 1; j <= m.ncols(); j++ )
489489 {
490490 ans = 0;
491491 for( t = 0; t < d; t++ ) ans += val[i-1][t]*m(col[i-1][t+1],j);
495495 return product;
496496 }
497497
498 long smat::nullity(const scalar& lambda, scalar mod) // nullity of this-lambda*I
499 {
500 smat sma(*this); sma-=lambda; return sma.ncols()-sma.rank(mod);
501 }
498502
499503 // Definitions of non-member, friend operators and functions
500504
518522
519523 vec operator* (smat& m, const vec& v)
520524 {
521 int r = nrows(m), c=ncols(m);
525 int r = m.nrows(), c=m.ncols();
522526 if(c!=dim(v))
523527 {
524528 cout<<"Error in smat*vec: wrong dimensions ("<<r<<"x"<<c<<")*"<<dim(v)<<endl;
533537
534538 svec operator* ( const svec& v, const smat& A )
535539 {
536 if( v.d != nrows(A) )
540 if( v.d != A.nrows() )
537541 {
538542 cout << "incompatible sizes in v*A\n";
539543 cout << "Dimensions "<<v.d<<" and "<<dim(A)<<endl;
540544 abort();
541545 }
542 svec prod(ncols(A));
546 svec prod(A.ncols());
543547 map<int,scalar>::const_iterator vi;
544548 for(vi=v.entries.begin(); vi!=v.entries.end(); vi++)
545549 prod += (vi->second)*(A.row(vi->first));
548552
549553 svec mult_mod_p( const svec& v, const smat& A, const scalar& p )
550554 {
551 if( v.d != nrows(A) )
555 if( v.d != A.nrows() )
552556 {
553557 cout << "incompatible sizes in v*A\n";
554558 cout << "Dimensions "<<v.d<<" and "<<dim(A)<<endl;
555559 abort();
556560 }
557 svec prod(ncols(A));
561 svec prod(A.ncols());
558562 map<int,scalar>::const_iterator vi;
559563 for(vi=v.entries.begin(); vi!=v.entries.end(); vi++)
560564 prod.add_scalar_times_mod_p(A.row(vi->first), vi->second,p);
10401040 // the (i,j) entry of dmat goes in the remaining_rows[i-1]'th row,
10411041 // remaining_cols[j-1] column. For simplicity of coding, we create
10421042 // the new rows as svecs and the use setrow().
1043 int nrd = nrows(dmat); // may be less than nrr since 0 rows are trimmed
1043 int nrd = dmat.nrows(); // may be less than nrr since 0 rows are trimmed
10441044 svec rowi(nco);
10451045 for(i=1; i<=nrd; i++)
10461046 {
10741074 }
10751075
10761076
1077 long rank(smat& sm, scalar mod)
1078 {
1079 smat_elim sme(sm,mod);
1077 long smat::rank(scalar mod)
1078 {
1079 smat_elim sme(*this,mod);
10801080 vec pivs, npivs;
10811081 (void) sme.kernel(npivs,pivs);
10821082 return sme.get_rank();
7070 mat expressvectors(const mat& m, const subspace& s)
7171 { vec p = pivots(s);
7272 long n = dim(s);
73 mat ans(n,ncols(m));
73 mat ans(n,m.ncols());
7474 for (int i=1; i<=n; i++) ans.setrow(i, m.row(p[i]));
7575 return ans;
7676 }
100100 // N.B. The following check is strictly unnecessary and slows it down,
101101 // but is advisable!
102102 if(cr) {
103 // int check = 1, n = nrows(b);
103 // int check = 1, n = b.nrows();
104104 // for (i=1; (i<=n) && check; i++)
105105 // for (j=1; (j<=d) && check; j++)
106106 // check = (dd*m.row(i)*b.col(j) == b.row(i)*ans.col(j));
120120 scalar d;
121121 vec pcols,npcols;
122122 mat m = echelon(m1,pcols,npcols, rank, nullity, d, method);
123 int dim = ncols(m);
123 int dim = m.ncols();
124124 mat basis(dim,nullity);
125125 for (n=1; n<=nullity; n++) basis.set(npcols[n],n,d);
126126 for (r=1; r<=rank; r++)
211211 long rank, nullity, n, r, i, j;
212212 vec pcols,npcols;
213213 mat m = echmodp(m1,pcols,npcols, rank, nullity, pr);
214 int dim = ncols(m);
214 int dim = m.ncols();
215215 mat basis(dim,nullity);
216216 for (n=1; n<=nullity; n++) basis.set(npcols[n],n,1);
217217 for (r=1; r<=rank; r++)
228228 long rank, nullity, i, j, jj, t, tt;
229229 vec pcols,npcols;
230230 mat m = echmodp_uptri(m1,pcols,npcols, rank, nullity, pr);
231 int dim = ncols(m);
231 int dim = m.ncols();
232232 mat basis(dim,nullity);
233233 for(j=nullity; j>0; j--)
234234 {
9191 data.the_opmat_ = smat(0,0); // releases its space
9292 }
9393 else {
94 if( nrows(data.submat_) == 0 ) {
94 if( data.submat_.nrows() == 0 ) {
9595 if( depth == 0 ) data.submat_ = h -> s_opmat(depth,1,verbose);
9696 else data.submat_ = h -> s_opmat_restricted(depth,*(data.nest_),1,verbose);
9797 }
142142 // Save space (will recompute when needed)
143143 //if( ( depth == 0 )
144144 // && ( dim(s) > 0 )
145 // && ( nrows(data.submat_) > 1000 )
145 // && ( data.submat_.nrows() > 1000 )
146146 // && ( data.submatUsage_ == data.numChildren_ ) ) {
147147 // data.submat_ = smat(0,0);
148148 //}
541541
542542 mat sparse_restrict(const mat& m, const subspace& s)
543543 {
544 if(dim(s)==nrows(m)) return m; // trivial special case, s is whole space
544 if(dim(s)==m.nrows()) return m; // trivial special case, s is whole space
545545 scalar dd = denom(s); // will be 1 if s is a mod-p subspace
546546 mat b(basis(s));
547547 smat sm(m), sb(b);
575575
576576 smat restrict_mat(const smat& m, const subspace& s)
577577 {
578 if(dim(s)==nrows(m)) return m; // trivial special case, s is whole space
578 if(dim(s)==m.nrows()) return m; // trivial special case, s is whole space
579579 return mult_mod_p(m.select_rows(pivots(s)),smat(basis(s)),MODULUS);
580580 }
581581
0 // list_cubicx.cc: Program for listing integer cubics with given discriminant bound
0 // list_cubics.cc: Program for listing integer cubics with given discriminant bound
11 //////////////////////////////////////////////////////////////////////////
22 //
33 // Copyright 1990-2012 John Cremona
8787 {
8888 cout<<disc<<"\t";
8989 cubic g(a,b,c,d);
90 cout<<g<<"\t----------->\t";
90 cout<<g;
91 if(disc!=g.disc())
92 cout<<" [WRONG DISC]";
93 cout<<"\t---(reduces to)--->\t";
9194 if(neg)
9295 g.jc_reduce(m);
9396 else
94 g.hess_reduce(m);
95 cout<<g<<endl;
97 g.hess_reduce(m);
98 cout<<g;
99 if(disc!=g.disc())
100 cout<<" [WRONG DISC]";
101 cout<<endl;
96102 }
97103 }
98104 }
00 Enter discriminant bound (positive or negative): Positive discriminants up to 200
1 49 [1,-1,-2,1] -----------> [1,-1,-2,1]
2 81 [1,0,-3,1] -----------> [1,0,-3,1]
3 108 [1,0,-3,0] -----------> [1,0,-3,0]
4 117 [1,1,-3,0] -----------> [0,-3,-1,1]
5 125 [1,-1,-3,2] -----------> [1,2,-2,-1]
6 148 [1,0,-4,2] -----------> [1,-1,-3,1]
7 148 [1,1,-3,-1] -----------> [1,1,-3,-1]
8 169 [1,1,-4,1] -----------> [1,1,-4,1]
1 49 [1,-1,-2,1] ---(reduces to)---> [1,-2,-1,1]
2 81 [1,0,-3,1] ---(reduces to)---> [1,-3,0,1]
3 108 [1,0,-3,0] ---(reduces to)---> [1,0,-3,0]
4 117 [1,1,-3,0] ---(reduces to)---> [0,-3,-1,1]
5 125 [1,-1,-3,2] ---(reduces to)---> [1,2,-2,-1]
6 148 [1,0,-4,2] ---(reduces to)---> [1,-1,-3,1]
7 148 [1,1,-3,-1] ---(reduces to)---> [1,1,-3,-1]
8 169 [1,1,-4,1] ---(reduces to)---> [1,-4,1,1]
99 Enter discriminant bound (positive or negative): Negative discriminants down to 200
10 -23 [1,-1,0,1] -----------> [1,-1,0,1]
11 -23 [1,0,-1,1] -----------> [1,1,0,1]
12 -27 [1,0,0,1] -----------> [1,0,0,1]
13 -31 [1,1,-2,1] -----------> [1,-1,0,1]
14 -31 [1,1,0,1] -----------> [1,1,0,1]
15 -44 [1,1,-1,1] -----------> [1,1,-1,1]
16 -59 [1,-1,-1,2] -----------> [1,2,0,1]
17 -76 [1,0,-2,2] -----------> [1,-1,-3,1]
18 -83 [1,-1,-3,4] -----------> [1,-1,-1,2]
19 -87 [1,-1,-2,3] -----------> [1,1,-2,1]
20 -100 [1,-1,0,2] -----------> [1,-1,0,2]
21 -104 [1,0,-1,2] -----------> [1,0,-1,2]
22 -107 [1,1,-3,2] -----------> [1,-2,-4,1]
23 -108 [1,0,0,2] -----------> [1,0,0,2]
24 -116 [1,1,0,2] -----------> [1,1,0,2]
25 -135 [1,0,-3,3] -----------> [1,0,-3,1]
26 -147 [1,1,-1,2] -----------> [1,1,-1,2]
27 -152 [1,1,-2,2] -----------> [1,1,-2,2]
28 -172 [1,-1,-1,3] -----------> [1,2,0,2]
29 -175 [1,0,-5,5] -----------> [1,2,-3,1]
30 -176 [1,0,-4,4] -----------> [1,1,-3,1]
31 -199 [1,1,-4,3] -----------> [1,-1,-4,1]
32 -200 [2,2,-1,1] -----------> [1,1,-2,2]
10 -23 [1,-1,0,1] ---(reduces to)---> [1,-1,0,1]
11 -23 [1,0,-1,1] ---(reduces to)---> [1,-1,0,1]
12 -27 [1,0,0,1] ---(reduces to)---> [1,0,0,1]
13 -31 [1,1,-2,1] ---(reduces to)---> [1,1,0,1]
14 -31 [1,1,0,1] ---(reduces to)---> [1,1,0,1]
15 -44 [1,1,-1,1] ---(reduces to)---> [1,-1,1,1]
16 -59 [1,-1,-1,2] ---(reduces to)---> [1,2,0,1]
17 -76 [1,0,-2,2] ---(reduces to)---> [1,1,3,1]
18 -83 [1,-1,-3,4] ---(reduces to)---> [1,1,1,2]
19 -87 [1,-1,-2,3] ---(reduces to)---> [1,-1,2,1]
20 -100 [1,-1,0,2] ---(reduces to)---> [1,-1,0,2]
21 -104 [1,0,-1,2] ---(reduces to)---> [1,0,-1,2]
22 -107 [1,1,-3,2] ---(reduces to)---> [1,2,4,1]
23 -108 [1,0,0,2] ---(reduces to)---> [1,0,0,2]
24 -116 [1,1,0,2] ---(reduces to)---> [1,1,0,2]
25 -135 [1,0,-3,3] ---(reduces to)---> [1,0,3,1]
26 -147 [1,1,-1,2] ---(reduces to)---> [1,1,-1,2]
27 -152 [1,1,-2,2] ---(reduces to)---> [1,1,-2,2]
28 -172 [1,-1,-1,3] ---(reduces to)---> [1,2,0,2]
29 -175 [1,0,-5,5] ---(reduces to)---> [1,-2,3,1]
30 -176 [1,0,-4,4] ---(reduces to)---> [1,-1,3,1]
31 -199 [1,1,-4,3] ---(reduces to)---> [1,1,4,1]
32 -200 [2,2,-1,1] ---(reduces to)---> [1,-1,2,2]
3333 Enter discriminant bound (positive or negative):
1515 Mathews reduced cubic = [83,-149,294,-878]
1616 after transform by [14,23;3,5]
1717 Using JC/Julia reduction ...
18 JC/Julia reduced cubic = [83,-100,-245,-650]
18 JC/Julia reduced cubic = [83,100,245,-650]
1919 after transform by [14,9;3,2]
2020 Enter cubic coeffs a, b, c, d:
380380 double sparsity(const mat_m& m)
381381 {
382382 double count=0;
383 long i,j,nr=nrows(m), nc=ncols(m);
383 long i,j,nr=m.nrows(), nc=m.ncols();
384384 for(i=0; i<nr; i++)
385385 for(j=0; j<nc; j++)
386386 if(!is_zero(m(i+1,j+1))) count=count+1;
122122 cout << "Enter any number "; cin >> i;
123123 }
124124 {
125 vector<long> cp = charpoly(a);
125 vector<long> cp = a.charpoly();
126126 cout << "char. poly. of A has coefficients " << cp << endl;
127 cout << "det(A) = " << determinant(a) << endl;
127 cout << "det(A) = " << a.determinant() << endl;
128128 }
129129 {
130130 aug = colcat(a,idmat(r));
109109 cout << "Enter any number "; cin >> i;
110110 }
111111 {
112 vector<bigint> cp = charpoly(a);
112 vector<bigint> cp = a.charpoly();
113113 cout << "char. poly. of A has coefficients " << cp << endl;
114 cout << "det(A) = " << determinant(a) << endl;
114 cout << "det(A) = " << a.determinant() << endl;
115115 }
116116 {
117117 aug = colcat(a,midmat(r));
3939 cout << "Enter entries of M: ";
4040 cin >> m;
4141 cout << " M = " << m;
42 cout << "Trace(M) = " << trace(m) << endl;
42 cout << "Trace(M) = " << m.trace() << endl;
4343 //
4444 mat_m mpower=m;
4545 for (i=2; i<=r; i++)
4646 {mpower=mpower*m;
4747 cout << "m^" << i << " = " << mpower;
48 cout << "Trace(m^" << i << ") = " << trace(mpower) << endl;
48 cout << "Trace(m^" << i << ") = " << mpower.trace() << endl;
4949 }
5050 //
5151 {
52 vector<bigint> cp = charpoly(m);
52 vector<bigint> cp = m.charpoly();
5353 cout << "char. poly. of m has coefficients " << cp << endl;
5454 }
55 cout << "det(M) = " << determinant(m) << endl;
56 cout << "rank(M) = " << rank(m) << endl;
57 cout << "nullity(M) = " << nullity(m) << endl;
55 cout << "det(M) = " << m.determinant() << endl;
56 cout << "rank(M) = " << m.rank() << endl;
57 cout << "nullity(M) = " << m.nullity() << endl;
5858 {
5959 msubspace ker = kernel(m);
6060 mat_m kerbasis = basis(ker);
444444 mat ker_mat = echmodp( m, pc, npc, rk, ny, pr);
445445 cout << " rank using echmodp : " << rk;
446446 int pop = 0;
447 int nro = nrows(ker_mat);
448 int nco = ncols(ker_mat);
447 int nro = ker_mat.nrows();
448 int nco = ker_mat.ncols();
449449 for( int r = 1; r <= nro; r++ ) {
450450 for( int c = 1; c <= nco; c++ ) {
451451 pop += ( ker_mat( r, c ) != 0 );
3535 cout << "Enter entries of M: ";
3636 cin >> m;
3737 cout << " M = " << m;
38 cout << "Trace(M) = " << trace(m) << endl;
38 cout << "Trace(M) = " << m.trace() << endl;
3939 /*
4040 int i;
4141 mat mpower=m;
4242 for (i=2; i<=r; i++)
4343 {mpower=mpower*m;
4444 cout << "m^" << i << " = " << mpower;
45 cout << "Trace(m^" << i << ") = " << trace(mpower) << endl;
45 cout << "Trace(m^" << i << ") = " << mpower.trace() << endl;
4646 }
4747 {
48 vector<long> cp = charpoly(m);
48 vector<long> cp = m.charpoly();
4949 cout << "char. poly. of m has coefficients " << cp << endl;
5050 }
51 cout << "det(M) = " << determinant(m) << endl;
52 cout << "rank(M) = " << rank(m) << endl;
53 cout << "nullity(M) = " << nullity(m) << endl;
51 cout << "det(M) = " << m.determinant() << endl;
52 cout << "rank(M) = " << m.rank() << endl;
53 cout << "nullity(M) = " << m.nullity() << endl;
5454 */
5555 cout << endl << "Enter number of times to repeat kernel tests: ";
5656 cin >> ntimes;
8383 if(bad) cout<<"W("; else cout<<"T(";
8484 cout <<p<<") = ";
8585 showmatrix(tp);
86 vector<bigint> cptp = charpoly(tp);
86 vector<bigint> cptp = tp.charpoly();
8787 for(i=0; i<dims; i++)
8888 {
8989 bigint temp = cptp[i];