\\ --------------- GP code --------------------------------------- \\ \\ Time-stamp: \\ \\ Description: Routines for arithmetic in quaternion algebras \\ ramified at a prime p, and infinity, so as to get theta functions, \\ following the paper: "An Algorithm for Computing Modular Forms on \\ \Gamma_{0}(N). A.Pizer, Journal of Algebra 64, 340-390. \\ \\ \\ Original Authors: Fernando Rodriguez-Villegas \\ villegas@math.utexas.edu \\ University of Texas at Austin \\ \\ Ariel Martin Pacetti \\ apacetti@math.utexas.edu \\ University of Texas at Austin \\ \\ Created: Wed Nov 22 2000 \\ \r qforms \r qalg \r bforms \\====================================================================== \\ Sets the quaternion algebra ramified at p and infinity, and \\ computes a maximal order in this quaternion algebra. qsetprime(N)= {local(q,aux); if(isprime(N),,error("not a prime")); brandtinfo=[]; brandtinfo2=[[],[]];smallbrandtinfo=[[],[]];brandtinfo3=[[],[]]; if(N==2, qset(-1,-1), if(N%4==3,qset(-1,-N), if(N%8==5,qset(-2,-N), q=3; while(kronecker(N,q)+1, q=nextprime(q+2); while((q%4-3),q=nextprime(q+2))); qset(-N,-q)))); mxl=qmxlorder(N,q)} \\====================================================================== \\ This is a routien for computing a maximal order in the case of a \\ quaternion algebra ramified at a prime N and infinity. The \\ parameter q is optional and is just needed in the case N=1 mod 8. qmxlorder(N,q)= {local(aux,mxl); if(N==2, [[1/2,1/2,1/2,1/2],[0,1,0,0],[0,0,1,0],[0,0,0,1],1], if(N%4==3, [[1/2,0,1/2,0],[0,1/2,0,1/2],[0,0,1,0],[0,0,0,1],1], if(N%8==5, [[1/2,0,1/2,1/2],[0,1/4,1/2,1/4],[0,0,1,0],[0,0,0,1],1], if(q,,q=3; while(kronecker(N,q)+1, q=nextprime(q+2); while((q%4-3),q=nextprime(q+2)))); aux=sqrt(Mod(-N,q)); aux=lift(chinese(aux,Mod(-q,N))); [[1/2,0,1/2,0],[0,1/2,0,1/2],[0,0,1/q,(aux+q)/N/q],[0,0,0,1],1])))} \\====================================================================== \\ Gives a list of the primes in which the quaternion algebra U es ramified \\ Note that inf means that the algebra is ramified at infinity ramifiedprimes(U)= {local(list,factors,l); list=veclistelem(concat(concat(factor(U[1])[,1]~,factor(U[2])[,1]~),2)); if(list[1]==-1,list=vectorkill(list,1)); l=length(list); for(k=1,l,if(hilbert(U[1],U[2],list[l-k+1])==1,list=vectorkill(list,l-k+1))); l=length(list); if(l%2==1,list=concat(list,inf)); list } \\====================================================================== \\ Given an order, answers if it's maximal qorderismaximal(L)= {local(aux,N); if(length(L)==4,L=qsetlat(L)); aux=ramifiedprimes(qdef); if(aux[length(aux)]==inf,aux=vectorkill(aux,length(aux))); N=1; for(k=1,length(aux),N=N*aux[k]); sqr(N)==qdisc(L) } \\====================================================================== \\ Computes the discriminant of an order L, in a quaternion algebra U qdisc(L)=matdet(qgram(L)) \\====================================================================== \\ Given an order O of level N, computes N. (see A. Pizer Journal of \\Algebra 64, 340-390 (1980), for the definition of level, and the next \\formulas) qlevel(L)=sqrtint(qdisc(L)) \\====================================================================== \\ Given an order of level N=p^(2r+1)*M or N=p^2*M, on an algebra ramified \\ at p, and infinity, computes the class number H(p^(2r+1)*M) qclassnumber(L,N,p)= {local(aux,ans,aux2); if(N,,aux=ramifiedprimes(qdef);if(aux[2]!=inf,error("U is not ramified at a prime p and inf")); \\N=qlevel(L); N=sqrtint(qdisc(L));p=aux[1]); if(valuation(N,p)==2||valuation(N,p)%2==1,,error("not implemented yet the case level(L)= p^(2*k)*M")); if(valuation(N,p)%2==1, ans=N/12*(1-1/p); if(N/p^(valuation(N,p))==1,aux=[;],aux=factprimes(N/p^(valuation(N,p)))); for(k=1,length(aux),ans=ans*(1+1/(aux[k]))); if(N%4!=0, aux2=1; for(k=1,length(aux),aux2=aux2*(1+kronecker(-4,aux[k]))); ans=ans+1/4*(1-kronecker(-4,p))*aux2); if(N%9!=0, aux2=1; for(k=1,length(aux),aux2=aux2*(1+kronecker(-3,aux[k]))); ans=ans+1/3*(1-kronecker(-3,p))*aux2), if(N/sqr(p)==1,aux=[;],aux=factprimes(N/p^2)); ans=(sqr(p)-1)/12*N/sqr(p); for(k=1,length(aux),ans=ans*(1+1/(aux[k]))); if(p==3,ans=ans+4/3*prod(x=1,length(aux),1+kronecker(-3,aux[x])))); ans } \\====================================================================== \\ Given an intenger N=p^(2r+1)*M or N=p^2*M and the prime p, computes \\ the class number of an order of this level in a quaternion algebra \\ ramified at p, and infinity. qclassnumber2(N,p)= {local(aux,ans,aux2); if(valuation(N,p)==2||valuation(N,p)%2==1,,error("not implemented yet the case level(L)= p^(2*k)*M")); if(valuation(N,p)%2==1, ans=N/12*(1-1/p); if(N/p^(valuation(N,p))==1,aux=[;],aux=factprimes(N/p^(valuation(N,p)))); for(k=1,length(aux),ans=ans*(1+1/(aux[k]))); if(N%4!=0, aux2=1; for(k=1,length(aux),aux2=aux2*(1+kronecker(-4,aux[k]))); ans=ans+1/4*(1-kronecker(-4,p))*aux2); if(N%9!=0, aux2=1; for(k=1,length(aux),aux2=aux2*(1+kronecker(-3,aux[k]))); ans=ans+1/3*(1-kronecker(-3,p))*aux2), if(N/sqr(p)==1,aux=[;],aux=factprimes(N/p^2)); ans=(sqr(p)-1)/12*N/sqr(p); for(k=1,length(aux),ans=ans*(1+1/(aux[k]))); if(p==3,ans=ans+4/3*prod(x=1,length(aux),1+kronecker(-3,aux[x]))); ans) } \\====================================================================== \\ Same as before, but for a prime number, with respect to the maximal \\ one qcln(p)=p/12*(1-1/p)+1/4*(1-kronecker(-4,p))+1/3*(1-kronecker(-3,p)) \\====================================================================== \\ Given a quaternion algebra U ramified at p and infinity, and a number \\ N=p^(2r+1)*M, computes an order of level N. qorderlevel(M)= {local(fact,L,aux,n,val); aux=ramifiedprimes(qdef)[1]; val=valuation(M=M/aux,aux); if(val%2!=0,error("not a level of order p^(2*r+1)*N"), fact=factor(M/aux^val); L=mxl; n=length(fact[,1]); for(k=1,n, for(j=1,fact[k,2], L=qsuborder(L,fact[k,1]))); for(k=1,val/2,L=qsuborder(L,aux^2))); L} \\====================================================================== \\ Given an order L, computes a suborder of index q (q a prime, or the \\ ramified prime squared) of L. If no order is given, takes the \\ maximal one as default. qsuborder(L,q)= {local(aux,cand,l,cont,teste); if(L==0,L=mxl); if(qlatisideal(L),,error("not an order")); if(isprime(q),teste=0,teste=1; if(ramifiedprimes(qdef)[1]^2!=q,error("not a prime number, or not the ramified prime squared"))); l=qmat(L); if(teste==0, aux=matid(4); aux[1,1]=q; if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,return(cand))); aux=matid(4); aux[2,2]=q; for(k=1,q,aux[2,1]=k-1; if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,return(cand)))); aux=matid(4); for(k=0,q^2-1,aux[3,]=concat(vectorkill(base(q^2+k,q),1),[q,0]); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,return(cand)))); aux=matid(4); for(k=0,q^3-1,aux[4,]=concat(vectorkill(base(q^3+k,q),1),q); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,return(cand)))), q=sqrtint(q); for(i=1,4, teste=vector(4,x,if(x==i,1,0)); for(j=1,4,if(i<=j, aux=matdiagonal(vector(4,x,q^(teste+vector(4,y,if(y==j,1,0)))[x])); for(k1=0,aux[2,2]-1,aux[2,1]=k1; for(k2=0,aux[3,3]^2-1, if(aux[3,3]!=1,aux[3,]=concat(vectorkill(base(aux[3,3]^2+k2,aux[3,3]),1),[aux[3,3],0])); for(k3=0,aux[4,4]^3-1, if(aux[4,4]!=1,aux[4,]=concat(vectorkill(base(aux[4,4]^3+k3,aux[4,4]),1),aux[4,4])); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,return(cand))))))))))} \\====================================================================== \\ Given an order L, computes all the eichler suborders of index q (q \\ a prime, or the ramified prime squared) of L. If no order is given, \\ takes the maximal one as default. qsuborders(L,q)= {local(ans,aux,cand,l,cont,teste); if(L==0,L=mxl); if(qlatisideal(L),,error("not an order")); if(isprime(q),teste=0,teste=1; if(ramifiedprimes(qdef)[1]^2!=q,error("not a prime number, or not the ramified prime squared"))); l=qmat(L); ans=[]; if(teste==0, aux=matid(4); aux[1,1]=q; if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,ans=concat(ans,cand))); aux=matid(4); aux[2,2]=q; for(k=1,q,aux[2,1]=k-1; if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,ans=concat(ans,cand)))); aux=matid(4); for(k=0,q^2-1,aux[3,]=concat(vectorkill(base(q^2+k,q),1),[q,0]); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,ans=concat(ans,cand)))); aux=matid(4); for(k=0,q^3-1,aux[4,]=concat(vectorkill(base(q^3+k,q),1),q); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,ans=concat(ans,cand)))), q=sqrtint(q); for(i=1,4, teste=vector(4,x,if(x==i,1,0)); for(j=1,4,if(i<=j, aux=matdiagonal(vector(4,x,q^(teste+vector(4,y,if(y==j,1,0)))[x])); for(k1=0,aux[2,2]-1,aux[2,1]=k1; for(k2=0,aux[3,3]^2-1, if(aux[3,3]!=1,aux[3,]=concat(vectorkill(base(aux[3,3]^2+k2,aux[3,3]),1),[aux[3,3],0])); for(k3=0,aux[4,4]^3-1, if(aux[4,4]!=1,aux[4,]=concat(vectorkill(base(aux[4,4]^3+k3,aux[4,4]),1),aux[4,4])); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime(cand,q)!=1,,ans=concat(ans,cand))))))))))} \\====================================================================== \\ Given an order L, computes all the suborders of index q (q a prime, \\ or the ramified prime squared) of L. If no order is given, takes \\ the maximal one as default. Note that some of them may be the same. qsuborders2(L,q)= {local(aux); aux=qidcl(qsuborder(L,q)); vector(length(aux),k,qrorder2(aux[k])) } \\====================================================================== \\ Computes given an ideal L, the number of elements of norm <= n with \\ the bilinear form induced by L. qrepnum(L,n)=if(n==0,0,qfminim(qgram(L),2*n,0)[1]) \\====================================================================== \\ Computes given a bilinear form L, the number of elements of norm <= n. qrepnum2(L,n)=if(n==0,0,qfminim(L,2*n,0)[1]) \\====================================================================== \\ Given an order L, computes left ideals representatives of \\ the class group of ideals corresponding to that order. qidcl(m0,bd)= {local(n,mx,v,q,k,j,mz,l,fl,d,cont); if(bd,n=bd,n=qclassnumber(m0)); cont=0; mx=[m0]; if(n==1, return(mx)); mz=qtern(m0); k=0; j=2; until(clnof(-d)>1 && (d%4==3||d%4==0), k=k+1; d=qn(k*mz[1]+mz[2])); v=hvecf(-d); q=v[j]; until(length(mx)==n, mk=qlatprod(m0,[[q[1],0,0,0],([q[2],0,0,0]+k*mz[1]+mz[2])/2,q[1]]); fl=0; l=1; until(fl || l>length(mx), fl=qareequiv(mx[l],mk); l=l+1); if(fl,,mx=concat(mx,[mk])); if((j+2)>length(v), j=2; until(clnof(-d)>1 && (d%4==3||d%4==0), k=k+1; d=qn(k*mz[1]+mz[2])); v=hvecf(-d), j=j+2); q=v[j]); brandtinfo=[mx]; mx} \\====================================================================== \\ Given a basis of an ideal, computes a basis (over Q) of trace 0 \\ elements. qtern(m0)= {local(mx,aux,den); mx=[]; for(k=1,4, u=[2*m0[k]-[qtr(m0[k]),0,0,0]]; if(norml2(u),mx=concat(mx,u),)); mx=qmat(concat(mx,2)); den=denominator(mx); qextract(mathnf(mx*den)/den)} \\====================================================================== \\ Given an order L of the quaternion algebra U, ramified at \\ {p,infinity}, and n, computes the Brandt Matrix B(n). brandt(L,n,BI)= {local(B,h,aux,rorders,e,norms,aux2,p); p=ramifiedprimes(qdef)[1]; h=if(BI,length(BI),qclassnumber(L)); if(brandtinfo==[]||length(brandtinfo)<=3, brandtinfo=[if(BI,aux=BI,aux=qidcl(L)), rorders=vector(h,k,qrorder2(aux[k])), vector(h,k,qrepnum(rorders[k],1)), vector(length(aux),k,aux[k][5]), matrix(h,h,i,j,if(i<=j, qgram(qlatprod(qinvlat(aux[j]),aux[i])),0))], if(qaresamelat(brandtinfo[1][1],L)||if(BI,qaresamelat(qlorder(BI[1]),L),0),, brandtinfo=[aux=qidcl(L), rorders=vector(h,k,qrorder2(aux[k])), vector(h,k,qrepnum(rorders[k],1)), vector(length(aux),k,aux[k][5]), matrix(h,h,i,j,if(i<=j, qgram(qlatprod(qinvlat(aux[j]),aux[i])),0))])); aux=brandtinfo[1]; rorders=brandtinfo[2]; e=brandtinfo[3]; norms=brandtinfo[4]; B=matrix(h,h,i,j,if(i<=j, aux2=brandtinfo[5][i,j]; if(n==0,e[j]^(-1),e[j]^(-1)*(qrepnum2(aux2,n)-qrepnum2(aux2,n-1))), aux2=brandtinfo[5][j,i]; if(n==0,e[j]^(-1),e[j]^(-1)*(qrepnum2(aux2,n)-qrepnum2(aux2,n-1))))); B} \\====================================================================== \\ Given an order and a prime dividing the level, determines if it is \\ an Eichler order. qiseichlerprime(L,q)= {local(k,aux,ans,primo,vec,aux2); primo=ramifiedprimes(qdef)[1]; k=1; vec=vector(length(L)-1,x,qtr(L[x])); if(q!=primo, if(q!=2,vec=vec%q; if(vec==0, aux=[x,y,z,w]; aux=aux*qgram(L)*aux~+2; if(qhassolution(aux,q)==1,return(1)), while(vec[k]==0,k=k+1); L=vectorswitch(L,[1,k]); aux=[(-x*qtr(L[2])-y*qtr(L[3])-z*qtr(L[4]))*lift(Mod(qtr(L[1]),q)^(-1)),x,y,z]; aux=aux*qgram(L)*aux~+2; if(qhassolution(aux,q)==1,return(1)))); k=1; if(vec%q!=vector(length(L)-1), while(vec[k]==0,k=k+1); L=vectorswitch(L,[1,k]); vec=vectorswitch(vec,[1,k]); aux=[(1-x*vec[2]-y*vec[3]-z*vec[4])*lift(Mod(vec[1],q)^(-1)),x,y,z]; aux=aux*qgram(L)*aux~; ans=qhassolution(aux,q); if(ans==1,return(1)),return(0)), if(q!=2,aux2=nonquadratic(q); vec=vec%q; if(vec==0, aux=[x,y,z,w]; aux=aux*qgram(L)*aux~+aux2*2; if(qhassolution(aux,q)==1,return(1),return(0)), while(vec[k]==0,k=k+1); L=vectorswitch(L,[1,k]); aux=[(-x*qtr(L[2])-y*qtr(L[3])-z*qtr(L[4]))*lift(Mod(qtr(L[1]),q)^(-1)),x,y,z]; aux=aux*qgram(L)*aux~+aux2*2; if(qhassolution(aux,q)==1,return(1),return(0))), if(vec%q!=vector(length(L)-1), while(vec[k]==0,k=k+1); L=vectorswitch(L,[1,k]); vec=vectorswitch(vec,[1,k]); aux=[(1-x*vec[2]-y*vec[3]-z*vec[4])*lift(Mod(vec[1],q)^(-1)),x,y,z]; aux=aux*qgram(L)*aux~+2; ans=qhassolution(aux,q); if(ans==1,return(1)),return(0)))) } \\====================================================================== \\ Given an order, answers if it's an Eichler order qiseichler(L)= {local(aux,ans); aux=factor(qlevel(L))[,1]~; ans=1; for(k=1,length(aux),ans=ans&&qiseichlerprime(L,aux[k])); ans} \\====================================================================== \\ The next routines are for the case of orders of level p^2*N, where \\gcd(p:N)=1, and p is the ramified prime. \\====================================================================== \\ Given an order and a prime dividing the level, determines if it is \\ an Eichler order qiseichlerprime2(L,q)= {local(k,aux,ans,primo,vec,aux2); primo=ramifiedprimes(qdef)[1]; k=1; vec=vector(length(L)-1,x,qtr(L[x])); if(q!=primo, if(q!=2,vec=vec%q; if(vec==0, aux=[x,y,z,w]; aux=aux*qgram(L)*aux~+2; if(qhassolution(aux,q)==1,return(1)), while(vec[k]==0,k=k+1); L=vectorswitch(L,[1,k]); aux=[(-x*qtr(L[2])-y*qtr(L[3])-z*qtr(L[4]))*lift(Mod(qtr(L[1]),q)^(-1)),x,y,z]; aux=aux*qgram(L)*aux~+2; if(qhassolution(aux,q)==1,return(1)))); k=1; if(vec%q!=vector(length(L)-1), while(vec[k]==0,k=k+1); L=vectorswitch(L,[1,k]); vec=vectorswitch(vec,[1,k]); aux=[(1-x*vec[2]-y*vec[3]-z*vec[4])*lift(Mod(vec[1],q)^(-1)),x,y,z]; aux=aux*qgram(L)*aux~; ans=qhassolution(aux,q); if(ans==1,return(1)),return(0)), qlatisorder(L)) } \\====================================================================== \\ Given an order, answers if it's an Eichler order qiseichler2(L)= {local(aux,ans,primo); if(qlatisorder(L),,error("not an order")); primo=ramifiedprimes(qdef)[1]; if(valuation(qlevel(L),primo)!=2,error("not a level p^2*M level")); aux=factor(qlevel(L)/sqr(primo))[,1]~; ans=1; for(k=1,length(aux),ans=ans&&qiseichlerprime2(L,aux[k])); ans} \\====================================================================== \\ Given an order L, computes a suborder of index q (q a prime) \\ of L. If no order is given, takes the maximal one as default. qsuborder2(L,q)= {local(aux,cand,l,cont); if(L==0,L=mxl); if(qlatisideal(L),,error("not an order")); l=qmat(L); aux=matid(4); aux[1,1]=q; if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime2(cand,q)!=1,,return(cand))); aux=matid(4); aux[2,2]=q; for(k=1,q,aux[2,1]=k-1; if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime2(cand,q)!=1,,return(cand)))); aux=matid(4); for(k=0,q^2-1,aux[3,]=concat(vectorkill(base(q^2+k,q),1),[q,0]); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime2(cand,q)!=1,,return(cand)))); aux=matid(4); for(k=0,q^3-1,aux[4,]=concat(vectorkill(base(q^3+k,q),1),q); if(qlatisorder(cand=concat(qextract(l*aux),1)),if(qiseichlerprime2(cand,q)!=1,,return(cand))))} \\====================================================================== \\ Given a quaternion algebra U ramified at p and infinity, and a number \\ N=p^2*M (or just M), computes an order of level N. qorderlevel2(M)= {local(fact,L,aux,n,val); aux=ramifiedprimes(qdef)[1]; val=valuation(M,aux); if(val==0||val==2,,error("not a level of order p^2*N")); fact=factor(M/aux^val); L=mxl; n=length(fact[,1]); for(k=1,n, for(j=1,fact[k,2], L=qsuborder2(L,fact[k,1]))); if(val==2,L=qsuborder2(L,aux)); L} \\---------------------------------------------------------------------- {helpqalgmodforms()= print("-------------------------------------------------------------------"); print(" Computational number Theory "); print("-------------------------------------------------------------------"); print(""); print("Description: Routines for computing the Brandt matrices for any eichler order of level N, on a ramified quaternion algebra at p, and infinity"); print(""); print("Original Authors: Fernando Rodriguez-Villegas"); print(" villegas@math.utexas.edu"); print(" University of Texas at Austin"); print(""); print(" Ariel Pacetti"); print(" apacetti@math.utexas.edu"); print(" University of Texas at Austin"); print("-------------------------------------------------------------------"); print(""); print("Help functions"); print(""); print("helpqsetprime helpramifiedprimes helpqorderismaximal"); print("helpqdisc helpqlevel helpqclassnumber"); print("helpqorderlevel helpqsuborder helpqsuborders"); print("helpqrepnum helpqidcl helpqtern"); print("helpbrandt helpqiseichler helpqiseichler2"); print("helpqsuborder2 helpqorderlevel2"); print(""); } addhelp(qsetprime,"Given a prime p, computes some needed information, for working on a quaternion algebra ramified precisely at p and infinity") addhelp(ramifiedprimes,"Given a quaternion algebra (by a pair [a,b]), computes a list of the ramified primes") addhelp(qorderismaximal,"Given an order (which is represented as a lattice, i.e. 4 vectors linearly independent over R, and the lattice norm), answers whether the order is maximal or not") addhelp(qdisc,"Computes the discriminant of an order L") addhelp(qlevel,"Computes the level of a given order") addhelp(qclassnumber,"Given any order of level N (the class number is independent of the order), on a quaternion algebra just ramified at p, and infinity, answers the classnumber") addhelp(qorderlevel,"Given a quaternion algebra ramified at p and infinity, and a number M (where M must be of the tipe p^(2*r+1)*N), computes an Eichler order, of level M") addhelp(qsuborder,"Given an Eichler order L in a quaternion algebra ramified at p and infinity, and a prime q (or p^2), computes an Eichler suborder of index q in L") addhelp(qsuborders,"Given an Eichler order L in a quaternion algebra ramified at p and infinity, and a prime q (or p^2), computes all Eichler suborders of index q in L") addhelp(qrepnum,"Given a lattice L, and a positive integer n, computes of the element in L, of norm <= n (where the norm is the induced one by the lattice") addhelp(qidcl,"Given an Eichler order L, computes left ideals representatives of the class group of ideals corresponding to that order.") addhelp(qtern,"Gives a specific basis over R of the elements of trace zero, needed for computing the ideals representatives of an order") addhelp(brandt,"Given an Eichler order in a quaternion algebra ramified at a prime p and infinity, and a positive integers n, computes the brandt matrix B(n)") addhelp(qiseichler,"Given an order L, answers if it is an Eichler order or not") addhelp(qiseichler2,"This is a special routine for working with Eichler orders of level p^2*N, where p is the ramified prime. It answers whether the given order is Eichler or not") addhelp(qsuborder2,"This is a special routine for working with Eichler orders of level p^2*N, where p is the ramified prime. Given an Eichler order (the maximal one as default), computes a suborder of the given prime level") addhelp(qorderlevel2,"This is a special routine for working with Eichler orders of level p^2*N, where p is the ramified prime. Given a positive integer of the form p^2*N or N (with gcd(N:p)=1), computes an Eichler suborder of the given number level")