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