Attachment 'lseries.m'

Download

   1 /***********************************************************************
   2 NOTE: 
   3   * I should write a p-adic characters package. -- WAS
   4   * His function name "Lseries" is bad.   It should be
   5     pAdicLSeriesApproximation
   6  ***********************************************************************/
   7 
   8 /*
   9 Date: Mon, 29 Jan 2001 01:26:54 -0500 (EST)
  10 From: Robert Pollack <[email protected]>
  11 To: "William A. Stein" <[email protected]>
  12 Subject: Lseries code
  13 
  14 > Hey, send me some magma code that involves p-adic L-functions!
  15 
  16 Okay...but the code is really awful.  I believe it works though.
  17 
  18 I will send you two more e-mails.  One containing a write-up in
  19 TeX of computing the p-adic L-series and the other will be my
  20 code.  The first will probably be more helpful than the later.
  21 
  22 As the code is not documented, let me at least lead you thru 
  23 what it is supposed to do.  The main procedure is called Lseries.
  24 It takes in five parameters - let's call them V,p,a_p,n,D.
  25 
  26 The V should be the space of modular symbols associated to E
  27 The p is the prime
  28 The a_p is the a_p value of E
  29 The n represents the level of accuracy.
  30 The D represents twisting by a quadratic character of conductor D.
  31          (you can always just take D=1)
  32 
  33 Then Lseries(V,p,a_p,n,D) returns in the ordinary case a polynomial
  34 of degree p^(n-1)-1 approximating the L-series.  In the supersingular
  35 case, it returns two polynomials say G and H so that G + H * alpha
  36 approximates the L-series where alpha is a root of x^2 - a_p x + p.
  37 
  38 The other main procedure is iwasawa_invariants_w_curve.  This
  39 takes 6 arguments, say N,V,p,a_p,n,D.
  40 
  41 Here N is the conductor of the curve
  42      V is the space of modular symbols of the curve
  43      p is some prime
  44      a_p is the a_p value of the curve
  45      n is the level of accuracy
  46      D represents twisting by a quadratic character of conductor D
  47 
  48 This procedure is supposed to return the iwasawa invariants of 
  49 the L-series.  
  50 
  51 Precisely, in the ordinary case it returns a 6-tuple of data,
  52 namely the rank of the curve, 
  53        the p-adic valuation of the leading non-zero term of the L-series,
  54        the mu invariant of the L-series
  55        the lambda invariant of the L-series
  56        the newton polygon of the L-series.
  57                  -this is returned as [ [m_1,s_1] , [m_2,s_2] , ... ]
  58                  where m_1 is the number of roots of slope s_1...;
  59                  a slope of 10000 represents the root 0.
  60        a boolean saying whether the above data is correct.
  61          (note if mu is positive then a "true" only means that the data
  62          is as accurate as it can be using a polynomial of degree
  63          p^(n-1)-1; that is it could have a another root of smaller slope)
  64 
  65 
  66 In the supersingular case, the p-adic L-series is not an iwasawa
  67 function so the above data couldn't make any sense.  Instead it
  68 returns an 11-tuple of data consisting of the rank and then the
  69 same data for the g and h functions i construct in my thesis.  i should
  70 have a rough draft of my thesis ready soon if you are interested
  71 in how they are defined.  basically, they are the "real" and "imaginary"
  72 parts of the L-series with their trivial zeroes removed.  They are
  73 in fact iwasawa functions (actually integral power series).
  74 
  75 I've been back and forth between NY and Boston for the last
  76 few weeks.  Now I should be back in Boston full time for the
  77 next month.
  78 
  79 Okay...let me try and send out the code.
  80 
  81 Robert
  82 *********************************************************************/
  83 
  84 R<x>:=PolynomialRing(Rationals());
  85 R<T>:=PolynomialRing(Rationals());
  86 
  87 //This function cuts out the subspace of H_1(X_0(N),Z) where
  88 //T_2 acts as a_2, T_3 acts as a_3, T_5 acts as a_5 and T_7 acts as a_7
  89 //Input:  	N - conductor
  90 //		a_2 - eigenvalue of T_2
  91 //		a_3 - eigenvalue of T_3
  92 //		a_5 - eigenvalue of T_5
  93 //		a_7 - eigenvalue of T_7
  94 //
  95 //Output:	space of modular symbols of level N and specified eigenvalues
  96 function form_curve(N,a_2,a_3,a_5,a_7)
  97 
  98    R<x>:=PolynomialRing(Rationals());
  99    M:=ModularSymbols(N,2,+1);
 100    I:=[<2,x-a_2>,<3,x-a_3>,<5,x-a_5>,<7,x-a_7>]; 
 101    V:=Kernel(I,M);
 102    ModularSymbolEven(V,1/2);
 103 
 104    return(V);
 105 end function;
 106 
 107 function table_of_modular_symbols(V,p,n,D) 
 108    local q,table,temp,k,scale,q1,mid,temp2,e;
 109 
 110    if (D mod p eq 0) then
 111       print "Twisting by something not relatively prime to p!";
 112    end if;
 113 
 114    if (KroneckerSymbol(D,-1) eq -1) then
 115       print "Twisting by an odd character!";
 116    end if;
 117 
 118    q1 := p^(n-1);
 119    q := q1*p;
 120 
 121    k:=1;
 122    while (ModularSymbolEven(V,k/p^10)[1] eq 0) do
 123       k := k+1;
 124    end while;
 125 
 126    scale := Denominator(ModularSymbolEven(V,k/q)[1]);
 127    table := [];
 128 
 129    for a in [0..(q-1) div 2] do
 130       if (Valuation(a,p) le 2) or (a eq 0) then
 131          temp2 :=0;
 132          for b in [1..D] do
 133             e := KroneckerSymbol(D,b);
 134             if (e ne 0) then
 135                temp := ModularSymbolEven(V,(D*a-q*b)/(D*q))[1] * scale;
 136                if Denominator(temp) ne 1 then   
 137                   print "PROBLEMS!  There are still denominators in ",
 138                         "the modsyms.";
 139                end if;   
 140                temp2 := temp2 + KroneckerSymbol(D,b)*temp;
 141             end if;
 142          end for;
 143          table := table cat [Numerator(temp2)];
 144       else
 145          table := table cat [0];
 146       end if;
 147    end for;
 148 
 149    //USING the fact that [r/s]^+ equals [-r/s]^+
 150    mid := ((q-1) div 2) + 1;
 151    for a in [mid..q-1] do
 152       table := table cat [table[q-a+1]];
 153    end for;
 154    table := table cat [scale];
 155 
 156    return(table);
 157 end function;
 158 
 159 //Multiplies a and b interpreted as a[1] + sqrt(-p)*a[2].
 160 function multiply(a,b,p)
 161    return([a[1]*b[1] - p*a[2]*b[2],a[1]*b[2]+a[2]*b[1]]);
 162 end function;
 163 
 164 //Here answer[a] = [alpha^-a]
 165 //n+1 is the maxl power and m is the accuracy
 166 function powers_of_alpha(p,a_p,n,m)
 167    local temp,answer,t,q;
 168 
 169    if a_p mod p ne 0 then
 170       temp := a_p mod p;
 171 
 172       for k in [2..m] do
 173          t := -(temp^2-a_p*temp+p) div p^(k-1) mod p *
 174             InverseMod(2*temp - a_p,p);
 175          temp := temp + t*p^(k-1);
 176       end for;
 177 
 178       q := p^m;
 179       temp := InverseMod(temp,q);
 180       answer := [[temp]];
 181 
 182       for k in [2..n+1] do
 183          Append(~answer,[answer[k-1][1]*answer[1][1] mod q]);
 184       end for;
 185 
 186       return(answer);
 187    else
 188       if a_p eq 0 then
 189          temp := [0,-1/p];
 190       else
 191          if a_p eq -3 then
 192             temp := [-1/2,-1/6];
 193          else
 194             temp := [1/2,-1/6];
 195          end if;
 196       end if;
 197       answer := [temp];
 198       for k in [2..n+1] do
 199          Append(~answer,multiply(answer[k-1],answer[1],p));
 200       end for;
 201       return(answer);
 202    end if;
 203 end function;
 204 
 205 //Here answer = {a} mod p^m
 206 function one_teich(a,p,m)
 207    local answer,t;
 208 
 209    answer := a mod p;
 210    for k in [2..m] do
 211       t := 0;
 212       while (answer + t*p^(k-1))^(p-1) mod p^k ne 1 do
 213          t := t+1;
 214       end while;
 215       answer := answer + t*p^(k-1); 
 216    end for;
 217 
 218    return(answer);
 219 end function;
 220          
 221 //Here answer[a] = {a} (mod p^m) 
 222 function list_of_teich(p,m)
 223    local answer;
 224 
 225    answer := [];
 226    for a in [1..p-1] do
 227       Append(~answer,one_teich(a,p,m));
 228    end for;
 229    return(answer);
 230 end function;
 231 
 232 //Here answer[a] = gamma^(a-1)
 233 //SO THERE IS A SHIFT
 234 //n is the maxl power and m is the accuracy
 235 function powers_of_gamma(gamma,p,n)
 236    local answer;
 237 
 238    answer := [1];
 239    for k in [2..p^(n-1)] do
 240       Append(~answer,answer[k-1]*gamma mod (p^n));
 241    end for;
 242 
 243    return answer;
 244 end function;
 245 
 246 
 247 function lift_polynomial(f)
 248    return PolynomialRing(Rationals()) ! 
 249                 (PolynomialRing(Integers()) ! f);
 250 end function;
 251 
 252 //Here answer[a]=(1+T)^(a-1)
 253 //SO THERE IS A SHIFT
 254 //n is the maxl power and m is the accuracy
 255 function powers_of_oneplusT(p,n,m)
 256    local R,S,answer,q;
 257 
 258    q := p^m;
 259    R := ResidueClassRing(q);
 260    S<T> := PolynomialRing(R);
 261    answer := [1];
 262    for k in [2..p^(n-1)] do
 263       answer := answer cat [answer[k-1]*(1+T)] ;
 264    end for;
 265 
 266    return(answer);
 267 end function;
 268 
 269 function alpha(n,ALPHA)
 270      return(ALPHA[n]);
 271 end function;
 272 
 273 function modsym(a,MODSYM)
 274    return(MODSYM[a+1]);
 275 end function;
 276 
 277 function oneplusT(j,POWER)
 278    return(POWER[j+1]);
 279 end function;
 280 
 281 function teich(a,TEICH)
 282    return(TEICH[a]);
 283 end function;
 284 
 285 function gamma(j,GAMMA)
 286    return(GAMMA[j+1]);
 287 end function;
 288 
 289 function scale(list,c)
 290    local k,answer;
 291 
 292    answer:=[];
 293    for k in [1..#list] do
 294       answer := answer cat [list[k]*c];
 295    end for;
 296    return(answer);
 297 end function;
 298 
 299 function add(list1,list2)
 300    local k,answer;
 301    
 302    if #list1 ne #list2 then
 303       print "Error in add";
 304    end if;
 305 
 306    answer:=[];
 307    for k in [1..#list1] do
 308       answer := answer cat [list1[k]+list2[k]];
 309     end for;
 310 
 311    return(answer);
 312 end function;
 313 
 314 function subtract(list1,list2)
 315    local k,answer;
 316    
 317    if #list1 ne #list2 then
 318       print "Error in subtract";
 319    end if;
 320 
 321    answer:=[];
 322    for k in [1..#list1] do
 323       answer := answer cat [list1[k]-list2[k]];
 324     end for;
 325 
 326    return(answer);
 327 end function;
 328 
 329 function measure(a,p,n,ALPHA,MODSYM)
 330    local q,q1;
 331 
 332    q := p^n; 
 333    q1 := q div p;
 334    return( subtract(scale(alpha(n,ALPHA),modsym(a,MODSYM)),
 335            scale(alpha(n+1,ALPHA),modsym((a mod q1) * p ,MODSYM))));
 336 
 337 end function;
 338 
 339 //This procedure returns a polynomial approximation to the p-adic
 340 //L-series of the elliptic curve corresponding to V twisted by a quadratic
 341 //character of discriminant D.  The degree of the polynomial is p^n-1. 
 342 //If a_p is prime to p (ordinary) then the answer is simply a polynomial.
 343 //Otherwise (in the supersingular case) the answer is in the form [G,H]
 344 //where the L-series is approximated by G + sqrt(-p) * H.
 345 //
 346 //Input:   V - space of modular symbols
 347 //      p - prime
 348 //      a_p - eigenvalue of T_p acting on V
 349 //      n - relates to degree of approximation
 350 //      D - value to twist by
 351 function Lseries(V,p,a_p,n,D)
 352    local answer,q;
 353 
 354    ALPHA := powers_of_alpha(p,a_p,n,n+1);
 355    MODSYM := table_of_modular_symbols(V,p,n,D);
 356    POWER := powers_of_oneplusT(p,n,n+1);
 357    TEICH := list_of_teich(p,n+1);
 358    GAMMA := powers_of_gamma(1+p,p,n+1); 
 359 
 360    q1 := p^(n-1);
 361    q := q1*p;
 362    if a_p mod p ne 0 then
 363       answer := [0];
 364    else
 365       answer := [0,0];
 366    end if;
 367 
 368    for a in [1..p-1] do
 369       for j in [0..q1-1] do
 370          answer := add(answer, 
 371                    scale(measure(teich(a,TEICH)*gamma(j,GAMMA) mod 
 372                                 q,p,n,ALPHA,MODSYM),
 373                         lift_polynomial(oneplusT(j,POWER))));
 374       end for;
 375    end for;
 376 
 377    answer:=scale(answer,1/D);
 378    answer:=scale(answer,1/MODSYM[#MODSYM]);
 379 
 380    return(answer);
 381 end function;
 382 
 383 function highest_power(n,p)
 384    local k,temp;
 385 
 386    k:=0;
 387    temp:=1;
 388    while (n ge temp) do
 389       temp := temp*p;
 390       k := k+1;
 391    end while;
 392    return(k-1);
 393 end function;
 394 
 395 function valuation_of_coefficients(f,p,n)
 396    local answer,j,temp,okay,bound,list_bad;
 397 
 398    answer := [];
 399    okay:=true;
 400    list_bad:=[];
 401    for j in [1..Degree(f)+1] do
 402       if Coefficient(f,j-1) ne 0 then
 403          answer := answer cat [Valuation(Coefficient(f,j-1),p)];
 404       else 
 405          answer := answer cat [10000];
 406       end if;
 407       
 408       bound := n-1-highest_power(j-1,p);
 409       if (Valuation(Coefficient(f,j-1),p) ge bound) and (j ne 1) then
 410          list_bad := list_bad cat [j];
 411       end if;
 412    end for;
 413 
 414    if f eq 0 then
 415       answer := [];
 416       answer := answer cat [10000] cat [10000] cat [10000];
 417    end if;
 418    
 419    return(<answer,list_bad>);
 420 end function;
 421    
 422 function newton_polygon(C)
 423    local k,here,next,min_slope,answer,okay,prev_slope;
 424 
 425    answer:= [];
 426    okay:=true;
 427    here:=1;
 428    next:=1;
 429 
 430    while here lt #C do
 431       min_slope:=100000;
 432       for k in [here+1..#C] do
 433          if (C[k]-C[here])*(1.0)/(k-here) le 1.0*min_slope then
 434             min_slope := (C[k]-C[here])/(k-here);
 435             next := k;
 436          end if;
 437       end for;
 438       answer := answer cat [[next-here,-min_slope]];
 439       here := next;
 440    end while;   
 441    return(answer);
 442 end function;
 443 
 444 function find_last_nontriv(NP,p,sign)
 445    local slope,place;
 446 
 447    place := 0;
 448    if sign mod 2 eq 0 then
 449       slope := 1/(p*(p-1));
 450    else
 451       slope := 1/(p-1);
 452    end if;
 453 
 454    for k in [1..#NP] do
 455       if (NP[k][2] gt 0) then
 456          if (NP[k][2] ne slope) or (NP[k][1] ne 1/slope) then
 457             place:=k;
 458          else
 459             slope:=slope/(p^2);
 460          end if;
 461       end if;
 462    end for;
 463 
 464    return(place);
 465 end function;
 466 
 467 
 468 function refine_newton_polygon(NP,p,a_p,sign)
 469    local answer,k,last;
 470    
 471    answer := [];
 472    if a_p mod p ne 0 then
 473       for k in [1..#NP] do
 474          if NP[k][2] gt 0 then
 475             answer := answer cat [NP[k]];
 476          end if;
 477       end for;
 478    else
 479       last := find_last_nontriv(NP,p,sign);
 480       for k in [1..last] do
 481          answer := answer cat [NP[k]];
 482       end for;
 483    end if;
 484             
 485    return(answer);
 486 end function;
 487 
 488 function minimize_ord(C,p,n) 
 489    local k,start;
 490 
 491    start:=1;
 492    if C[1] eq 10000 then
 493       start := 2;
 494    end if;
 495 
 496    for k in [start..#C] do
 497       if C[k] ge n-1-highest_power(k-1,p) then
 498          C[k] := n-1-highest_power(k-1,p);
 499       end if;
 500    end for;
 501    return(C);
 502 end function;
 503 
 504 function in_list(list,num)
 505    local k,flag;
 506 
 507    flag:=false;
 508    for k in [1..#list] do
 509       if list[k] eq num then
 510          flag := true;
 511       end if;
 512    end for;
 513    
 514    return(flag);
 515 end function;
 516 
 517 function compute_rank(C,N,r,D)
 518    local rank;
 519 
 520    if C[1] eq 10000 then
 521       rank := 1;
 522    else
 523       rank :=0;
 524     end if;
 525 
 526    if (r eq 0) and (rank eq 1) and (KroneckerSymbol(D,N) eq 1) then  
 527           //it has even rank >= 2.
 528       rank:=2;
 529       C[2]:=10000;
 530    end if;
 531 
 532    if (r eq 1) and (rank eq 1) and (KroneckerSymbol(D,N) eq -1) then  
 533           //it has even rank >= 2.
 534       rank:=2;
 535       C[2]:=10000;
 536    end if;
 537 
 538    return(<C,rank>);
 539 end function;
 540 
 541 
 542 function check_NP(NP,C,list_bad,rank,p,a_p,n,sign)
 543    local temp,val,k,good;
 544 
 545    //checks if break points are accurate.
 546    
 547    good:=true;
 548    temp := refine_newton_polygon(NP,p,a_p,sign);
 549    val := 1;
 550    for k in [1..#temp] do
 551       val := val + temp[k][1];
 552       if (in_list(list_bad,val)) then
 553          good := false;
 554          print "Failed at a breakpoint,",val;
 555       end if;
 556    end for;
 557 
 558    //checks if lowering the valuation of any unknown coefficient to its
 559    //minimal possible value affects the newton polygon.
 560 
 561    C_min := minimize_ord(C,p,n); //lowers all unknown coefficients 
 562                                  // to lowest possible valuation
 563    
 564    if rank eq 2 then
 565          C_min[2] := 10000;
 566    end if;
 567 
 568    NP_min := newton_polygon(C_min);
 569    if refine_newton_polygon(NP_min,p,a_p,sign) 
 570           ne refine_newton_polygon(NP,p,a_p,sign) then
 571       good := false;
 572       print "Failed while lowering.";   
 573    end if;
 574 
 575    return(good);
 576 end function;
 577 
 578 function lambda(NP)
 579    local k,lam;
 580 
 581    k:=1;
 582    lam := 0;
 583    while (k le #NP) and (NP[k][2] gt 0) do
 584         lam := lam + NP[k][1];
 585       k := k+1;
 586    end while;
 587 
 588    return(lam);
 589 end function;
 590 
 591 function mu(NP,C,rank)
 592    local k,val,m,start;
 593 
 594    k:=1;
 595    val := 0;
 596    if (rank ne 2) then
 597       while (k le #NP) and (NP[k][2] gt 0) do
 598          if NP[k][2] lt 1000 then
 599             val := val + NP[k][1]*NP[k][2];
 600          end if;
 601          k := k+1;
 602       end while;
 603    else
 604       if (#NP gt 0) and (NP[1][1] eq 1) then 
 605          start := 3;
 606       else
 607          if #NP eq 0 then
 608             start := 1;
 609          else
 610             start := 2;
 611          end if;
 612       end if;
 613       k:=start;
 614       while (k le #NP) and (NP[k][2] gt 0) do
 615          if NP[k][2] lt 1000 then
 616             val := val + NP[k][1]*NP[k][2];
 617          end if;
 618          k := k+1;
 619       end while;
 620    end if;
 621 
 622    if rank eq 0 then
 623       m := C[1]-val;
 624    else
 625       if rank eq 1 then
 626          m := C[2] - val;
 627       else
 628          m := C[3] - val;
 629       end if;
 630    end if;
 631 
 632    return(m);
 633 
 634 end function;
 635 
 636 function remove_two(list)
 637    local answer,k;
 638 
 639    answer := [];
 640 
 641    for k in [1..#list] do
 642       if list[k] ne 2 then
 643          answer := answer cat [list[k]];
 644       end if;
 645    end for;
 646 
 647    return(answer);
 648 
 649 end function;
 650 
 651 function leading_term(C,rank)
 652 
 653    if rank eq 0 then
 654       return(C[1]);
 655    else
 656       if rank eq 1 then
 657          return(C[2]);
 658       else
 659          if rank eq 2 then
 660             return(C[3]);
 661          end if;
 662       end if;
 663    end if;
 664 end function;
 665 
 666 function compute_untwisted_rank(V,p,a_p)
 667    local L,C;
 668 
 669    L:=Lseries(V,p,a_p,2,1);
 670    L:=L[1];
 671    C := valuation_of_coefficients(L,p,1);
 672    if C[1][1] ne 10000 then
 673       return(0);
 674    else 
 675       return(1);
 676    end if;
 677 end function;
 678 
 679 function remove_unit_zeroes(NP)
 680    local k,answer;
 681 
 682    answer := [];
 683    for k in [1..#NP] do
 684       if NP[k][2] gt 0 then
 685          answer := answer cat [NP[k]];
 686       end if;
 687    end for;
 688    return(answer);
 689 end function;
 690 
 691 //Has the space of modular symbols already pre-computed
 692 function iwasawa_invariants_w_curve_ord(N,V,p,a_p,n,D)
 693    local C,NP,k,lam,m,rank,j,list_bad,list_breapoints,
 694          C_min,NP_min,val,good,m2,lam2,temp,leading;
 695 
 696    L:=Lseries(V,p,a_p,n,D)[1];
 697    C := valuation_of_coefficients(L,p,n);
 698    list_bad:=C[2];
 699    C:=C[1];
 700       
 701    //FIRST COMPUTE RANK
 702    
 703    rank := compute_untwisted_rank(V,p,a_p);
 704    C := compute_rank(C,N,rank,D);
 705 
 706    rank := C[2];  //changes valuation of a_1 to 10000 if guesses rank 2.
 707    C := C[1];   
 708 
 709    if rank eq 2 then
 710       list_bad := remove_two(list_bad);
 711    end if;
 712 
 713    NP := newton_polygon(C);
 714    good := check_NP(NP,C,list_bad,rank,p,a_p,n,0);  //0 represents nothing.
 715    NP := remove_unit_zeroes(NP);
 716    leading := leading_term(C,rank);
 717    
 718    if (leading eq 0) and (in_list(list_bad,rank+1) eq false) then
 719         good:=true;
 720    end if;
 721 
 722    lam:=lambda(NP);
 723    m := mu(NP,C,rank);   
 724 
 725    return(<rank,leading,m,lam,NP,good>);
 726 end function;
 727 
 728 function scale_by_p(C)
 729    local k;
 730 
 731    for k in [1..#C] do
 732       if C[k] ne 10000 then
 733          C[k]:=C[k]+1;
 734       end if;
 735    end for;
 736 
 737    return(C);
 738 end function;
 739 
 740    
 741 function remove_forced_zeroes(NP,p,init_slope)
 742    local k,slope,temp;
 743 
 744    temp := [];
 745    k := 1;   
 746    slope:=init_slope;
 747    while (k le #NP) and (NP[k][2] gt 0)  do
 748       if NP[k][2] ne slope then
 749          temp := temp cat [NP[k]];
 750       else
 751          if NP[k][1] - 1/slope ne 0 then
 752             temp := temp cat [[NP[k][1] - 1/slope,slope]];
 753          end if;
 754           slope := slope/(p^2);
 755       end if;
 756       k := k+1;
 757    end while;
 758 
 759    return(temp);
 760 end function;
 761 
 762 //Has the space of modular symbols already pre-computed
 763 function iwasawa_invariants_w_curve_ss(N,V,p,a_p,n,D)
 764    local L,G,H,k,CG,CH,mg,mh,lamg,lamh,NPG,NPH,rank,rankg,rankh,
 765       list_badg,list_badh,denomg,denomh,goodg,goodh,
 766       list_breakpointsg,list_breakpointsh,
 767       leadingg,leadingh;
 768 
 769    L := Lseries(V,p,a_p,n,D);
 770    G := L[1];
 771    H := L[2];
 772 
 773    //   denomg and denomh represent the number of p's 
 774    //   in the denominator of the measure
 775 
 776    if n mod 2 eq 0 then
 777       denomg:=n div 2;
 778       denomh:=(n+2) div 2;
 779    else
 780       denomg:=(n+1) div 2;
 781       denomh:=(n+1) div 2;
 782    end if;   
 783       
 784    CG := valuation_of_coefficients(G,p,n-denomg);
 785    CH := valuation_of_coefficients(H,p,n-denomh);
 786 
 787    list_badg := CG[2];
 788    list_badh := CH[2];
 789 
 790    CG:=CG[1];
 791    CH:=CH[1];
 792 
 793    //Computing the rank
 794 
 795    rank:=compute_untwisted_rank(V,p,a_p);
 796 
 797    CG := compute_rank(CG,N,rank,D); //changes a_1 if guesses rank 2
 798    rankg := CG[2];
 799    CG := CG[1];
 800 
 801    CH := compute_rank(CH,N,rank,D);
 802    rankh := CH[2];
 803    CH := CH[1];
 804 
 805    if rankg ne rankh then
 806       print "WEIRD..ranks different in G and H";
 807       PrintFile("notes","ranks different in G and H");
 808       PrintFile("notes",D);
 809    end if;
 810 
 811    rank := rankg;
 812    if rank eq 2 then
 813       list_badg := remove_two(list_badg);
 814    end if;
 815 
 816    if rank eq 2 then
 817       list_badh := remove_two(list_badh);
 818    end if;
 819 
 820    NPG := newton_polygon(CG);
 821    NPH := newton_polygon(CH);
 822 
 823    goodg := check_NP(NPG,CG,list_badg,rank,p,a_p,n,0); //0 represents g
 824    goodh := check_NP(NPH,CH,list_badh,rank,p,a_p,n,1); //1 represents h
 825 
 826    leadingg := leading_term(CG,rank);
 827    leadingh := leading_term(CH,rank);
 828 
 829    if (a_p eq 0) then
 830       if (leadingg eq -1) and (in_list(list_badg,rank+1) eq false) then
 831           goodg:=true;
 832       end if;
 833 
 834       if (leadingh eq -1) and (in_list(list_badh,rank+1) eq false) then
 835           goodh:=true;
 836       end if;
 837    end if;
 838 
 839 
 840    if a_p eq 0 then
 841       NPG := remove_forced_zeroes(NPG,p,1/((p-1)*p));
 842       NPH := remove_forced_zeroes(NPH,p,1/(p-1));
 843    else
 844       if a_p eq -3 then
 845          NPG := remove_forced_zeroes(NPG,p,1/((p-1)*p));
 846          NPH := remove_forced_zeroes(NPH,p,1/(p-1)*p^2);
 847       end if;
 848    end if;
 849 
 850    lamg := lambda(NPG);
 851    lamh := lambda(NPH);   
 852 
 853    mg := mu(NPG,CG,rank)+1;
 854    mh := mu(NPH,CH,rank)+1;
 855 
 856    return(<rank,leadingg,mg,lamg,NPG,goodg,leadingh,mh,lamh,NPH,goodh>);
 857 end function;
 858 
 859 // This procedure returns many invariants of the curve corresponding
 860 // to V twisted by D.  
 861 //
 862 // In the ordinary case the data returned is:
 863 //   <rank,valuation of leading coefficient,mu invariant,lambda invariant,
 864 //    newton polygon of L-series, boolean saying whether the above data
 865 //    are accurate>
 866 //
 867 // The newton polygon is returned as [n_1,s_1],[n_2,s_2],... where there are
 868 // n_1 roots of slope s_1, etc.
 869 //
 870 // In the supersingular case the data returned is similar.  The first entry is
 871 // the rank, then the next five are the data for my "g" iwasawa function and
 872 // then the next five for my "h" iwasawa function.
 873 
 874 function iwasawa_invariants_w_curve(N,V,p,a_p,n,D)
 875    if a_p mod p ne 0 then
 876       return(iwasawa_invariants_w_curve_ord(N,V,p,a_p,n,D));
 877    else
 878       return(iwasawa_invariants_w_curve_ss(N,V,p,a_p,n,D));
 879    end if;
 880 end function;

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2010-07-02 04:07:31, 1.7 KB) [[attachment:Teich-twist.sage]]
  • [get | view] (2010-07-01 03:45:20, 1.2 KB) [[attachment:abelian_field_dirichlet_group.sage]]
  • [get | view] (2010-06-29 16:42:10, 1.1 KB) [[attachment:approximation_of_integral.sage]]
  • [get | view] (2010-07-01 03:48:17, 3.6 KB) [[attachment:computing_modular_symbols_via_complex_integration.sage]]
  • [get | view] (2010-06-29 06:10:26, 1.3 KB) [[attachment:find_gamma.sage]]
  • [get | view] (2010-07-01 05:45:56, 3.3 KB) [[attachment:iwasawa_invariants.sage]]
  • [get | view] (2010-06-30 05:36:30, 1.5 KB) [[attachment:lp_teichmuller.sage]]
  • [get | view] (2010-06-29 00:30:16, 21.9 KB) [[attachment:lseries.m]]
  • [get | view] (2010-06-29 22:37:11, 573.6 KB) [[attachment:modular_symbols_and_padic_lfunctions.pdf]]
  • [get | view] (2010-06-29 00:29:47, 33.9 KB) [[attachment:pLseries.m]]
  • [get | view] (2010-06-29 22:35:43, 265.9 KB) [[attachment:padic_bsd.pdf]]
  • [get | view] (2010-07-02 04:06:18, 3.4 KB) [[attachment:prime5.txt]]
  • [get | view] (2010-07-02 04:06:47, 3.5 KB) [[attachment:prime7.txt]]
  • [get | view] (2010-07-01 07:10:40, 64.1 KB) [[attachment:sha_data_3_11a1_10000.txt]]
  • [get | view] (2010-07-01 07:10:58, 8.5 KB) [[attachment:sha_data_3_11a3_1000.txt]]
  • [get | view] (2010-07-01 07:11:20, 63.9 KB) [[attachment:sha_data_3_42a1_10000.txt]]
  • [get | view] (2010-06-29 00:29:16, 5.3 KB) [[attachment:sha_fast.sage]]
  • [get | view] (2010-07-01 07:18:18, 8.1 KB) [[attachment:sha_v2.sage]]
  • [get | view] (2010-07-01 22:23:54, 1.8 KB) [[attachment:teich_twist.sage]]
  • [get | view] (2010-06-29 04:02:51, 0.7 KB) [[attachment:test.sage]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.