1 // FILE HOMSPACE.H: Declaration of class homspace
2 //////////////////////////////////////////////////////////////////////////
3 //
4 // Copyright 1990-2012 John Cremona
5 //
6 // This file is part of the eclib package.
7 //
8 // eclib is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 2 of the License, or (at your
11 // option) any later version.
12 //
13 // eclib is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 // for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with eclib; if not, write to the Free Software Foundation,
20 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 //
22 //////////////////////////////////////////////////////////////////////////
23
24 #ifndef _ECLIB_HOMSPACE_H
25 #define _ECLIB_HOMSPACE_H 1
26 //flags that this file has been included
27
28 #include <eclib/method.h>
29 #include <eclib/symb.h>
30
31
32 // If this is defined, the order of primes used for Wq and Tp
33 // operators is the natural order 2, 3, 5, 7, ..., mixing good and bad
34 // primes. Otherwise the order is as in primelist (see moddata.h)
35 // with the bad primes first. This is referred to in two places: the
36 // homspace method op_prime(i) which returns the i'th prime to be
37 // used; and in periods.cc where (when NEW_OP_ORDER is *not* set) some
38 // permutation of eigenvalues needs to be done.
39 #define NEW_OP_ORDER
40
41 class mat22; // fully defined below
42 class matop; // fully defined below
43
44 class homspace :public symbdata {
45 //private:
46 public:
47 int *coordindex,*needed,*freegens;
48 long rk,denom1,denom2;
49 ssubspace kern; // kernel(delta) basis
50 smat tkernbas; // transpose of kernel(delta) basis
51 modsym *freemods;
52 public:
53 vector<svec> coord_vecs;
54 mat projcoord; // # cols = # newforms after they are found
55 long dimension, denom3, ncusps, ncusps2;
56 int cuspidal; // if 1 then compute cuspidal homology
57 public:
58 // Constructor (does all the work):
59 homspace(long n, // the level
60 int hp, // plus-space flag (0 or 1 or -1)
61 int hcusp, // cuspidal flag (0 or 1)
62 int verbose // verbosity (0 : no output
63 // 1 : basic short output
64 // 2 : lots of detail)
65 );
66 ~homspace();
h1cuspdim()67 long h1cuspdim() const {return dim(kern);}
h1dim()68 long h1dim() const {return dimension;} // No confusion with subspace::dim
h1denom()69 long h1denom() const {return denom1;}
h1cdenom()70 long h1cdenom() const {return denom3;}
h1ncusps()71 long h1ncusps() const {return ncusps;}
72 vector<long> eigrange(long i);
73 long op_prime(int i); // the i'th operator prime for Tp or Wq
74 mat opmat(int i, int dual, int verb=0);
75 vec opmat_col(int i, int j, int verb=0);
76 mat opmat_cols(int i, const vec& jlist, int verb=0);
77 mat opmat_restricted(int i,const subspace& s, int dual, int verb=0);
78 // versions returning an smat:
79 smat s_opmat(int i,int dual,int verb=0);
80 svec s_opmat_col(int i, int j, int verb=0);
81 smat s_opmat_cols(int i, const vec& jlist, int verb=0);
82 smat s_opmat_restricted(int i,const ssubspace& s, int dual,int verb=0);
83
84 // Extend a dual vector of length rk to one of length nsymb:
85 vec extend_coords(const vec& v);
86 // Contract a dual vector of length nsymb to one of length rk:
87 vec contract_coords(const vec& v);
88
89 public:
90 // The next functions express M- & modular symbols in terms of the
91 // basis for H_1(X_0(N);cusps;Z) of dimension rk
zero_coords()92 svec zero_coords() const {return svec(rk);} // zero vector
93 svec coords_from_index(int ind) const;
94 vec proj_coords_from_index(int ind, const mat& m) const;
95 long nfproj_coords_from_index(int ind, const vec& bas) const;
96 svec coords(const symb& s) const;
97 svec coords_cd(long c, long d) const;
98 svec coords(long nn, long dd) const;
coords(const rational & r)99 svec coords(const rational& r) const {return coords(num(r),den(r));}
100 svec coords(const modsym& m) const;
101
102 // versions which add to an existing svec:
103 void add_coords(svec& v, const symb& s) const;
104 void add_coords_cd(svec& v, long c, long d) const;
105 void add_coords(svec& v, long nn, long dd) const;
add_coords(svec & v,const rational & r)106 void add_coords(svec& v, const rational& r) const {add_coords(v,num(r),den(r));}
107 void add_coords(svec& v, const modsym& r) const;
108
109 // The next functions express M- & modular symbols in terms of the
110 // basis of a (dual) subspace of the whole space
111 // The "projcoord" default (which requires the initialization of the
112 // projcoord matrix as done in newforms::createfromscratch()) which
113 // has one column for each newform
114 // NB these operate on vecs and not svecs
115 // The "nf" versions give scalars and instead of a matrix take a
116 // vector = unique column of a matrix, such as a newform's coordplus
117 // vector.
118 vec proj_coords_cd(long c, long d, const mat& m) const;
proj_coords_cd(long c,long d)119 vec proj_coords_cd(long c, long d) const {return proj_coords_cd(c,d,projcoord);}
120 long nfproj_coords_cd(long c, long d, const vec& bas) const;
121 void add_proj_coords_cd(vec& v, long c, long d, const mat& m) const;
add_proj_coords_cd(vec & v,long c,long d)122 void add_proj_coords_cd(vec& v, long c, long d) const {add_proj_coords_cd(v,c,d,projcoord);}
123 void add_nfproj_coords_cd(long& a, long c, long d, const vec& bas) const;
124
125 vec proj_coords(long n, long d, const mat& m) const;
proj_coords(long n,long d)126 vec proj_coords(long n, long d) const {return proj_coords(n,d,projcoord);}
127 long nfproj_coords(long n, long d, const vec& bas) const;
128
129 void add_proj_coords(vec& v, long n, long d, const mat& m) const;
add_proj_coords(vec & v,long n,long d)130 void add_proj_coords(vec& v, long n, long d) const {add_proj_coords(v,n,d,projcoord);}
131 void add_nfproj_coords(long& aa, long n, long d, const vec& bas) const;
132
cuspidalpart(const vec & v)133 vec cuspidalpart(const vec& v) const
134 {return v[pivots(kern)];}
135
136 svec applyop(const matop& mlist, const rational& q) const;
137 svec applyop(const matop& mlist, const modsym& m) const;
138 // {return applyop(mlist,m.beta())-applyop(mlist,m.alpha());}
139
140 mat calcop(string opname, long p, const matop& mlist, int dual, int display=0) const;
141 vec calcop_col(string opname, long p, int j, const matop& mlist, int display=0) const;
142 mat calcop_cols(string opname, long p, const vec& jlist, const matop& mlist, int display=0) const;
143 mat calcop_restricted(string opname, long p, const matop& mlist, const subspace& s, int dual, int display=0) const;
144
145 smat s_calcop(string opname, long p, const matop& mlist, int dual, int display=0) const;
146 svec s_calcop_col(string opname, long p, int j, const matop& mlist, int display=0) const;
147 smat s_calcop_cols(string opname, long p, const vec& jlist, const matop& mlist, int display=0) const;
148 smat s_calcop_restricted(string opname, long p, const matop& mlist, const ssubspace& s, int dual, int display=0) const;
149
150 public:
151
152 mat heckeop(long p, int dual, int display=0) const;
153 vec heckeop_col(long p, int j, int display=0) const;
154 mat heckeop_cols(long p, const vec& jlist, int display=0) const;
155 mat heckeop_restricted(long p, const subspace& s, int dual, int display=0) const;
156
157 smat s_heckeop(long p, int dual, int display=0) const;
158 svec s_heckeop_col(long p, int j, int display=0) const;
159 smat s_heckeop_cols(long p, const vec& jlist, int display=0) const;
160 smat s_heckeop_restricted(long p, const ssubspace& s, int dual, int display=0) const;
161
162 mat newheckeop(long p, int dual, int display=0) const;
163 mat wop(long q, int dual, int display=0) const;
164 smat s_wop(long q, int dual, int display=0) const;
165 mat fricke(int dual, int display=0) const;
166 mat conj(int dual, int display=0) const;
167 vec conj_col(int j, int display=0) const;
168 mat conj_cols(const vec& jlist, int display=0) const;
169 mat conj_restricted(const subspace& s, int dual,int display=0) const;
170 smat s_conj(int dual, int display=0) const;
171 svec s_conj_col(int j, int display=0) const;
172 smat s_conj_cols(const vec& jlist, int display=0) const;
173 smat s_conj_restricted(const ssubspace& s, int dual, int display=0) const;
174 vec maninvector(long p) const;
175 vec projmaninvector(long p) const;
176 vec projmaninvector(long p, const mat& m) const;
177 vec manintwist(long p) const;
178 vec newhecke(long p, long n, long d) const;
179 //
180 friend class jumps;
181 friend class newforms;
182 };
183
184 class mat22 { //2x2 matrix for linear fractional transformations
185 friend class homspace;
186 private:
187 long a,b,c,d;
188 public:
189 mat22(long ia=0, long ib=0, long ic=0, long id=0)
a(ia)190 :a(ia),b(ib),c(ic),d(id){;}
mat22(const mat22 & m)191 mat22(const mat22& m) :a(m.a),b(m.b),c(m.c),d(m.d)
192 {;}
193 void operator=(const mat22& m)
194 {a=m.a; b=m.b; c=m.c; d=m.d;}
show(ostream & s)195 void show(ostream& s) const
196 {s << "[" << a << "," << b << ";"<< c << "," << d << "]";}
operator()197 rational operator()(const rational& q)const
198 {
199 long n=num(q),de=den(q);
200 return rational(a*n+b*de,c*n+d*de);
201 }
operator()202 modsym operator()(const modsym& m)const
203 {
204 return modsym((*this)(m.alpha()),(*this)(m.beta()));
205 }
operator()206 svec operator()(const symb& s, const homspace* h)const
207 {
208 long u=s.ceered(),v=s.deered();
209 return h->coords_cd(a*u+c*v,b*u+d*v);
210 }
operator()211 vec operator()(const symb& s, const homspace* h, const mat& m)const
212 {
213 long u=s.cee(),v=s.dee();
214 return h->proj_coords_cd(a*u+c*v,b*u+d*v,m);
215 }
216 };
217
218 class matop { // formal sum of 2x2 matrices
219 private: vector<mat22> mats;
220 public:
221 matop(long p, long n); // constructor for hecke ops
222 matop(long p); // constructor for heilbronn matrices
223 matop(long a, long b, long c, long d); // constructor for a single matrix
size()224 long size() const {return mats.size();}
225 mat22 operator[](long i) const {return mats[i];}
226 friend matop degen_mat(long d);
227 };
228
degen_mat(long d)229 inline matop degen_mat(long d)
230 {
231 return matop(d,0,0,1);
232 }
233
234 inline ostream& operator<< (ostream& s, const mat22& m)
235 {
236 m.show(s);
237 return s;
238 }
239
240 #endif
241