Elliptic curves

174 days ago by jakub.konieczny

Elliptic curves

Mastermath, The Netherlands, Fall 2011

This worksheet introduces you to some basic things you can do with elliptic curves in SAGE. It includes several exercises, for which you might want to open a new worksheet to experiment in with all kinds of functions.

For those taking the class for credit, when you are ready, include in this worksheet what you did to solve the exercises. This will sometimes consist of a short proof instead of a list of commands (which you could include in a cell as commentary after a #-sign). Print out the worksheet when finished and hand it in as homework (in groups of two). Since grading will be done by checking the output, make sure your output is printed!

Help about sage in general is available through http://www.sagemath.org/ and in particular the tutorial at http://www.sagemath.org/doc/tutorial/ is very useful for beginners. Information about elliptic curves in particular is on http://www.sagemath.org/doc/reference/plane_curves.html.


Construction of elliptic curves and points (exercise 1)
Number of points of the reduction and torsion (exercise 2,3,4,5)
Bad reduction and Hasse-Weil (exercise 6,7,8,9,10,11,12,13)
Mordell-Weil groups (exercise 14,15,16)
Period lattices (exercise 17,18)
Porism of Diophantos (exercise 19)
Modularity (exercise 20)
Heights (exercise 21)


One way to specify an elliptic curve is by a pair [a,b] of coefficients in the Weierstrass equation y^2 = x^3 + ax + b.

a=-43 b=166 E1=EllipticCurve([a,b]) E1 
       
Elliptic Curve defined by y^2 = x^3 - 43*x + 166 over Rational Field
Elliptic Curve defined by y^2 = x^3 - 43*x + 166 over Rational Field
Verify the discriminant of E_1 equals a multiple of 4a^3+27b^2.
D1=E1.discriminant() D1 == -16*(4*a^3+27*b^2) 
       
True
True

Recall that <tab> after 'E1.' shows everything you can do with E_1.

E1.torsion_points() 
       
[(-5 : -16 : 1), (-5 : 16 : 1), (0 : 1 : 0), (3 : -8 : 1), (3 : 8 : 1),
(11 : -32 : 1), (11 : 32 : 1)]
[(-5 : -16 : 1), (-5 : 16 : 1), (0 : 1 : 0), (3 : -8 : 1), (3 : 8 : 1), (11 : -32 : 1), (11 : 32 : 1)]
A point is defined by just coercing a list of two affine or three homogeneous coordinates into E_1.
P = E1([3,8]) P 
       
(3 : 8 : 1)
(3 : 8 : 1)

Exercise 1: Compute nP for all integers n.


Answer:

N = 7 for n in range(0,N+1): print n, n*P print 'Veryfying that 7*P is the neutral element:', N*P == 0*P print 'Since 7*P = 0 we conclude that nP = (n%7)*P, so all values of nP have been computed above' 
       
0 (0 : 1 : 0)
1 (3 : 8 : 1)
2 (-5 : -16 : 1)
3 (11 : -32 : 1)
4 (11 : 32 : 1)
5 (-5 : 16 : 1)
6 (3 : -8 : 1)
7 (0 : 1 : 0)
Veryfying that 7*P is the neutral element: True
Since 7*P = 0 we conclude that nP = (n%7)*P, so all values of nP have
been computed above
0 (0 : 1 : 0)
1 (3 : 8 : 1)
2 (-5 : -16 : 1)
3 (11 : -32 : 1)
4 (11 : 32 : 1)
5 (-5 : 16 : 1)
6 (3 : -8 : 1)
7 (0 : 1 : 0)
Veryfying that 7*P is the neutral element: True
Since 7*P = 0 we conclude that nP = (n%7)*P, so all values of nP have been computed above

Back to top

With E.Np(r) we get the number of points on the reduction of E to the finite field of r elements, where r is prime (including the singular point, if it exists).

Exercise 2: Create a list of the number of \mathbb{F}_p-points on the reduction of E_1 modulo p for all primes p of good reduction under 100.


Answer:

def good_reduction(C, p): return p in Primes() and C.discriminant() % p != 0 L = [] for p in range(1,100): if good_reduction(E1, p): L.append([p, E1.Np(p)]) print L 
       
[[3, 7], [5, 7], [7, 7], [11, 14], [17, 21], [19, 14], [23, 28], [29,
28], [31, 28], [37, 35], [41, 42], [43, 49], [47, 35], [53, 42], [59,
70], [61, 70], [67, 70], [71, 77], [73, 84], [79, 84], [83, 84], [89,
84], [97, 84]]
[[3, 7], [5, 7], [7, 7], [11, 14], [17, 21], [19, 14], [23, 28], [29, 28], [31, 28], [37, 35], [41, 42], [43, 49], [47, 35], [53, 42], [59, 70], [61, 70], [67, 70], [71, 77], [73, 84], [79, 84], [83, 84], [89, 84], [97, 84]]

Exercise 3: What is the greatest common divisor of those numbers and what does this say about the torsion subgroup of E_1(\mathbb{Q})?


Answer:
print 'Computing the greatest common divisor:', gcd([ Np for [p,Np] in L]) print 'The greatest common divisor is 7. It means that the torsion group is either trivial or Z/7Z (since its order divides 7)' 
       
Computing the greatest common divisor: 7
The greatest common divisor is 7. It means that the torsion group is
either trivial or Z/7Z (since its order divides 7)
Computing the greatest common divisor: 7
The greatest common divisor is 7. It means that the torsion group is either trivial or Z/7Z (since its order divides 7)

Exercise 4: Find a function that computes the size of the torsion group so that you can verify the answer to your last statement directly.


Answer
E1.torsion_order() 
       
7
7

Note that you can also define an elliptic curve by its Weierstrass equation after declaring x and y as variables. 

x,y = var('x,y') C = EllipticCurve(y^2 + y == x^3 + x) C 
       
Elliptic Curve defined by y^2 + y = x^3 + x over Rational Field
Elliptic Curve defined by y^2 + y = x^3 + x over Rational Field

Exercise 5: Compute the torsion subgroup of the elliptic curve given by y^2 + xy - 5y = x^3 - 5x^2.


Answer:

C = EllipticCurve(y^2 + x*y - 5*y == x^3 - 5*x^2) C.torsion_subgroup() 
       
Torsion Subgroup isomorphic to Z/2 + Z/4 associated to the Elliptic
Curve defined by y^2 + x*y - 5*y = x^3 - 5*x^2 over Rational Field
Torsion Subgroup isomorphic to Z/2 + Z/4 associated to the Elliptic Curve defined by y^2 + x*y - 5*y = x^3 - 5*x^2 over Rational Field

Back to top

Bad reduction and Hasse-Weil

We can also define an elliptic curve E_2 by specifying the coefficients a_1,a_2,a_3,a_4,a_6 of a long Weierstrass equation.
a1=0 a2=0 a3=1 a4=9 a6=0 E2=EllipticCurve(QQ,[a1,a2,a3,a4,a6]) E2 
       
Elliptic Curve defined by y^2 + y = x^3 + 9*x over Rational Field
Elliptic Curve defined by y^2 + y = x^3 + 9*x over Rational Field

Exercise 6: Compute the discriminant of E_2 and factorize it.


Answer:

D = E2.discriminant() print 'The discriminant is equal to:', D print 'The discriminant factors as:', factor(D) 
       
The discriminant is equal to: -46683
The discriminant factors as: -1 * 3^3 * 7 * 13 * 19
The discriminant is equal to: -46683
The discriminant factors as: -1 * 3^3 * 7 * 13 * 19

From the (correct) answer to the previous exercise, we see that the only primes of bad reduction are 3, 7, 13, and 19.

Exercise 7: Compute for each prime of bad reduction of E_2 the number of points on the reduction.


Answer:

Pbr = [3,7,13,19] for p in Pbr: print p, E2.Np(p) 
       
3 4
7 9
13 15
19 19
3 4
7 9
13 15
19 19

Recall that (at least in characteristic not equal to 2) the nonsingular points on a singular curve given by a Weierstrass equation over a field k are in bijection with the elements of one of three groups, namely k (additive, when the singular point is a cusp), or k^* (split multiplicative, for a node with tangents defined over k), or the kernel of the norm from l^* to k^* where l is a quadratic field extension of k (nonsplit multiplicative, for a node whose tangents are defined over l).

Exercise 8: Use the number of points counted above to read off the types of singular reduction (additive, split multiplicative or nonsplit multiplicative) of E_2 at its primes of bad reduction.


Answer: (just text, so no sage-commands)

# Note that in our cases K = F_p, so #K = p, #K^* = p-1, so in the additive and split multiplicative cases we have p+1 and p (we add one for the singular point) points on the reduction of E2. Thus, we expect additive reduction for 3, and multiplicative reduction for 19. The other cardinalities, for 7 and 13, correspond to the split nonsplit case. 
       

Exercise 9: Check that the following gives a result that is consistent with your previous answer.

[(p,E2.local_data(p).bad_reduction_type()) for p in range(50) if p in Primes()] 
       
[(2, None), (3, 0), (5, None), (7, -1), (11, None), (13, -1), (17,
None), (19, 1), (23, None), (29, None), (31, None), (37, None), (41,
None), (43, None), (47, None)]
[(2, None), (3, 0), (5, None), (7, -1), (11, None), (13, -1), (17, None), (19, 1), (23, None), (29, None), (31, None), (37, None), (41, None), (43, None), (47, None)]
#Answer to the next question; sorry, I must have done something wrong, since the place below the text disappeared, and I don't know how to get it back. #The manual says that: # bad_reduction_type == None means good reduction, so we have bad reduction for 3,7,13,19, as expected; # bad_reduction_type == +1 means split multiplicative reduction, and we have this for 19, as expected; # bad_reduction_type == -1 means non-split multiplicative reduction, and we have this for 7 and 13, as expected; # bad_reduction_type == 0 means additive reduction, and we have this 3, as expected; 
       

Answer: (just explain with text, so no sage-commands)


We compute the number of points on E_2 over the field of 5^n elements for n from 1 to 20.
r=[E2.base_extend(GF(5^n,'x')).cardinality() for n in range(1,21)] r 
       
[8, 32, 104, 640, 3208, 15392, 78184, 391680, 1950728, 9765152,
48841064, 244117120, 1220685448, 6103668512, 30517360744, 152587560960,
762941199368, 3814695421472, 19073481285224, 95367450947200]
[8, 32, 104, 640, 3208, 15392, 78184, 391680, 1950728, 9765152, 48841064, 244117120, 1220685448, 6103668512, 30517360744, 152587560960, 762941199368, 3814695421472, 19073481285224, 95367450947200]

Another command that would do this is 'E2.count_points(20)', but that works for any scheme over a field of a prime number of elements and does not use the fact that E_2 is an elliptic curve, making it very slow.

Exercise 10: Instead of the list of the numbers \#E_2(\mathbb{F}_{5^n}), compute a list with the numbers c_n = 5^n+1 - \#E_2(\mathbb{F}_{5^n}).


Answer:

c=[5^n+1-E2.base_extend(GF(5^n,'x')).cardinality() for n in range(1,21)] c 
       
[-2, -6, 22, -14, -82, 234, -58, -1054, 2398, 474, -12938, 23506, 17678,
-152886, 217382, 329666, -1746242, 1844154, 5042902, -19306574]
[-2, -6, 22, -14, -82, 234, -58, -1054, 2398, 474, -12938, 23506, 17678, -152886, 217382, 329666, -1746242, 1844154, 5042902, -19306574]

Exercise 11: Find a recursive formula for this sequence and use it to give an explicit equation for these numbers. Then use this to prove | c_n | \leq 2\sqrt{5^n}, assuming your recursive formula is correct.
(Hint: the recursion is of degree 2, so there exist u,v such that c_n = u c_{n-1} +vc_{n-2}. After finding u and v and \lambda_1,\lambda_2 satisfying \lambda_i^2 = u \lambda_i +v, we know that there are \alpha_1,\alpha_2 such that c_n = \alpha_1\lambda_1^n + \alpha_2 \lambda_2^n.)


Answer

u, v = var('u, v') eq0 = u*c[0] + v*c[1] == c[2] eq1 = u*c[1] + v*c[2] == c[3] solve( [eq0, eq1],u,v) u = -5; v = -2 d = [c[0], c[1]] for n in range(2,len(c)): d.append( u*d[n-2] + v*d[n-1] ) print 'Checking if c[n] agrees with d[n] (for computed values):', c == d lam, eta, a, b = var('lam, eta, a, b') eq0 = a + b == c[0] eq1 = a*lam + b*eta == c[1] eq2 = a*lam^2 + b*eta^2 == c[2] eq3 = a*lam^3 + b*eta^3 == c[3] sol = solve( [eq0, eq1, eq2, eq3],lam,eta,a,b) lam = sol[1][0].right_hand_side(); eta = sol[1][1].right_hand_side(); a = sol[1][2].right_hand_side(); b = sol[1][3].right_hand_side() print 'Checking the formula d[n] == (a*lam^n + b*eta^n):', [ a*lam^n + b*eta^n for n in range(0,len(d))] == d print 'Note: Checking only for computed values. (We are not very strict here, so I hope this will suffice.)' n = var('n') print 'Computing approximation of c_n:', simplify(abs(a)*abs(lam)^(n-1) + abs(b)*abs(eta)^(n-1)) print 'Note: The notation is somewhat contra-intuitive: note that the value c_n is stored in c[n-1]' 
       
Checking if c[n] agrees with d[n] (for computed values): True
Checking the formula d[n] == (a*lam^n + b*eta^n): True
Note: Checking only for computed values. (We are not very strict here,
so I hope this will suffice.)
Computing approximation of c_n: 2*5^(1/2*n)
Note: The notation is somewhat contra-intuitive: note that the value c_n
is stored in c[n-1]
Checking if c[n] agrees with d[n] (for computed values): True
Checking the formula d[n] == (a*lam^n + b*eta^n): True
Note: Checking only for computed values. (We are not very strict here, so I hope this will suffice.)
Computing approximation of c_n: 2*5^(1/2*n)
Note: The notation is somewhat contra-intuitive: note that the value c_n is stored in c[n-1]

A recursive formula similar to the one you found above holds in general, and also the inequality holds in general:

The Hasse-Weil Theorem says that if C is an elliptic curve over \mathbb{F}_q, then the inequality |\#C(\mathbb{F}_q) - q - 1| \leq 2\sqrt{q} holds.

Exercise 12: Check that this is true for the reductions of E_1 modulo all primes of good reduction that are less than 100 (as computed before).


Answer:

for p in range(1,100): if good_reduction(E1,p): print 'Checking for p = ', p, ':' print 'Checking if the inequality:',\ abs(E1.Np(p) - p - 1),\ '<', 2 * sqrt(p),\ 'is satisfied:', \ simplify( RR(abs(E1.Np(p) - p - 1)-2* sqrt(p)) < 0 ) print ' ' print 'Checking if the inequality was true for all p:',\ prod( [ simplify( RR(abs(E1.Np(p) - p - 1)-2* sqrt(p)) < 0 ) for p in range(1,100) if good_reduction(E1,p)] ) == true 
       
Checking for p =  3 :
Checking if the inequality: 3 < 2*sqrt(3) is satisfied: True
Checking for p =  5 :
Checking if the inequality: 1 < 2*sqrt(5) is satisfied: True
Checking for p =  7 :
Checking if the inequality: 1 < 2*sqrt(7) is satisfied: True
Checking for p =  11 :
Checking if the inequality: 2 < 2*sqrt(11) is satisfied: True
Checking for p =  17 :
Checking if the inequality: 3 < 2*sqrt(17) is satisfied: True
Checking for p =  19 :
Checking if the inequality: 6 < 2*sqrt(19) is satisfied: True
Checking for p =  23 :
Checking if the inequality: 4 < 2*sqrt(23) is satisfied: True
Checking for p =  29 :
Checking if the inequality: 2 < 2*sqrt(29) is satisfied: True
Checking for p =  31 :
Checking if the inequality: 4 < 2*sqrt(31) is satisfied: True
Checking for p =  37 :
Checking if the inequality: 3 < 2*sqrt(37) is satisfied: True
Checking for p =  41 :
Checking if the inequality: 0 < 2*sqrt(41) is satisfied: True
Checking for p =  43 :
Checking if the inequality: 5 < 2*sqrt(43) is satisfied: True
Checking for p =  47 :
Checking if the inequality: 13 < 2*sqrt(47) is satisfied: True
Checking for p =  53 :
Checking if the inequality: 12 < 2*sqrt(53) is satisfied: True
Checking for p =  59 :
Checking if the inequality: 10 < 2*sqrt(59) is satisfied: True
Checking for p =  61 :
Checking if the inequality: 8 < 2*sqrt(61) is satisfied: True
Checking for p =  67 :
Checking if the inequality: 2 < 2*sqrt(67) is satisfied: True
Checking for p =  71 :
Checking if the inequality: 5 < 2*sqrt(71) is satisfied: True
Checking for p =  73 :
Checking if the inequality: 10 < 2*sqrt(73) is satisfied: True
Checking for p =  79 :
Checking if the inequality: 4 < 2*sqrt(79) is satisfied: True
Checking for p =  83 :
Checking if the inequality: 0 < 2*sqrt(83) is satisfied: True
Checking for p =  89 :
Checking if the inequality: 6 < 2*sqrt(89) is satisfied: True
Checking for p =  97 :
Checking if the inequality: 14 < 2*sqrt(97) is satisfied: True
 
Checking if the inequality was true for all p: True
Checking for p =  3 :
Checking if the inequality: 3 < 2*sqrt(3) is satisfied: True
Checking for p =  5 :
Checking if the inequality: 1 < 2*sqrt(5) is satisfied: True
Checking for p =  7 :
Checking if the inequality: 1 < 2*sqrt(7) is satisfied: True
Checking for p =  11 :
Checking if the inequality: 2 < 2*sqrt(11) is satisfied: True
Checking for p =  17 :
Checking if the inequality: 3 < 2*sqrt(17) is satisfied: True
Checking for p =  19 :
Checking if the inequality: 6 < 2*sqrt(19) is satisfied: True
Checking for p =  23 :
Checking if the inequality: 4 < 2*sqrt(23) is satisfied: True
Checking for p =  29 :
Checking if the inequality: 2 < 2*sqrt(29) is satisfied: True
Checking for p =  31 :
Checking if the inequality: 4 < 2*sqrt(31) is satisfied: True
Checking for p =  37 :
Checking if the inequality: 3 < 2*sqrt(37) is satisfied: True
Checking for p =  41 :
Checking if the inequality: 0 < 2*sqrt(41) is satisfied: True
Checking for p =  43 :
Checking if the inequality: 5 < 2*sqrt(43) is satisfied: True
Checking for p =  47 :
Checking if the inequality: 13 < 2*sqrt(47) is satisfied: True
Checking for p =  53 :
Checking if the inequality: 12 < 2*sqrt(53) is satisfied: True
Checking for p =  59 :
Checking if the inequality: 10 < 2*sqrt(59) is satisfied: True
Checking for p =  61 :
Checking if the inequality: 8 < 2*sqrt(61) is satisfied: True
Checking for p =  67 :
Checking if the inequality: 2 < 2*sqrt(67) is satisfied: True
Checking for p =  71 :
Checking if the inequality: 5 < 2*sqrt(71) is satisfied: True
Checking for p =  73 :
Checking if the inequality: 10 < 2*sqrt(73) is satisfied: True
Checking for p =  79 :
Checking if the inequality: 4 < 2*sqrt(79) is satisfied: True
Checking for p =  83 :
Checking if the inequality: 0 < 2*sqrt(83) is satisfied: True
Checking for p =  89 :
Checking if the inequality: 6 < 2*sqrt(89) is satisfied: True
Checking for p =  97 :
Checking if the inequality: 14 < 2*sqrt(97) is satisfied: True
 
Checking if the inequality was true for all p: True

Exercise 13: For p =23, is there for every N in the Hasse-Weil interval

[ p+1-2\sqrt{p}, p+1+2\sqrt{p} ]
an elliptic curve C over \mathbb{F}_p with \#C(\mathbb{F}_p) = N ?


Answer:

p = 23 S = Set( range( floor(p + 2 - 2*sqrt(p) ), floor(p + 2 + 2*sqrt(p))) ) F = Set([]).frozenset() # Checking a lot of curves in hope we will find en example of every cardina for a in range(p): for b in range(p): if ((4*a^3 + 27*b^2) % p) != 0 : C = EllipticCurve(y^2 == x^3 + a*x + b) n = C.Np(p) if not(F.issuperset(Set([n]))): print 'We have found a curve cardinality:', n, 'given by ', y^2 == x^3 + a*x + b F = F.union(Set([n])) print 'The integers in the Hasse-Weil interval are: ', S print 'The integers that have been found: ', Set(F) print 'The integers that are missing: ', S.difference(F) print 'The evidence suggests that for every N in the interval there is a corresponding curve.' 
       
We have found a curve cardinality: 24 given by  y^2 == x^3 + 1
We have found a curve cardinality: 28 given by  y^2 == x^3 + x + 1
We have found a curve cardinality: 27 given by  y^2 == x^3 + x + 3
We have found a curve cardinality: 29 given by  y^2 == x^3 + x + 4
We have found a curve cardinality: 22 given by  y^2 == x^3 + x + 5
We have found a curve cardinality: 21 given by  y^2 == x^3 + x + 6
We have found a curve cardinality: 18 given by  y^2 == x^3 + x + 7
We have found a curve cardinality: 20 given by  y^2 == x^3 + x + 9
We have found a curve cardinality: 32 given by  y^2 == x^3 + x + 10
We have found a curve cardinality: 33 given by  y^2 == x^3 + x + 11
We have found a curve cardinality: 15 given by  y^2 == x^3 + x + 12
We have found a curve cardinality: 16 given by  y^2 == x^3 + x + 13
We have found a curve cardinality: 30 given by  y^2 == x^3 + x + 16
We have found a curve cardinality: 26 given by  y^2 == x^3 + x + 18
We have found a curve cardinality: 19 given by  y^2 == x^3 + x + 19
We have found a curve cardinality: 31 given by  y^2 == x^3 + 5*x + 1
We have found a curve cardinality: 23 given by  y^2 == x^3 + 5*x + 3
We have found a curve cardinality: 25 given by  y^2 == x^3 + 5*x + 9
We have found a curve cardinality: 17 given by  y^2 == x^3 + 5*x + 22
The integers in the Hasse-Weil interval are:  {15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}
The integers that have been found:  {15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33}
The integers that are missing:  {}
The evidence suggests that for every N in the interval there is a
corresponding curve.
We have found a curve cardinality: 24 given by  y^2 == x^3 + 1
We have found a curve cardinality: 28 given by  y^2 == x^3 + x + 1
We have found a curve cardinality: 27 given by  y^2 == x^3 + x + 3
We have found a curve cardinality: 29 given by  y^2 == x^3 + x + 4
We have found a curve cardinality: 22 given by  y^2 == x^3 + x + 5
We have found a curve cardinality: 21 given by  y^2 == x^3 + x + 6
We have found a curve cardinality: 18 given by  y^2 == x^3 + x + 7
We have found a curve cardinality: 20 given by  y^2 == x^3 + x + 9
We have found a curve cardinality: 32 given by  y^2 == x^3 + x + 10
We have found a curve cardinality: 33 given by  y^2 == x^3 + x + 11
We have found a curve cardinality: 15 given by  y^2 == x^3 + x + 12
We have found a curve cardinality: 16 given by  y^2 == x^3 + x + 13
We have found a curve cardinality: 30 given by  y^2 == x^3 + x + 16
We have found a curve cardinality: 26 given by  y^2 == x^3 + x + 18
We have found a curve cardinality: 19 given by  y^2 == x^3 + x + 19
We have found a curve cardinality: 31 given by  y^2 == x^3 + 5*x + 1
We have found a curve cardinality: 23 given by  y^2 == x^3 + 5*x + 3
We have found a curve cardinality: 25 given by  y^2 == x^3 + 5*x + 9
We have found a curve cardinality: 17 given by  y^2 == x^3 + 5*x + 22
The integers in the Hasse-Weil interval are:  {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}
The integers that have been found:  {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}
The integers that are missing:  {}
The evidence suggests that for every N in the interval there is a corresponding curve.

Back to top

Mordell-Weil groups

Exercise 14: Compute the rank of the elliptic curves given by

y^2 = x(x-3)(x+4)
y^2 = x(x-1)(x+3)
y^2 = x(x+1)(x-14)
y^2 = x(x^2+1)
See exercise 4.3 and 4.6 in the notes by Peter Stevenhagen.


Answer:

x,y = var('x,y') eqs = [ y^2 == x*(x-3)*(x+4), y^2 == x*(x-1)*(x+3), y^2 == x*(x+1)*(x-14), y^2 == x*(x^2+1)] for i in range(len(eqs)): C = EllipticCurve( eqs[i] ) print C, 'has rank equal to:', C.rank() 
       
Elliptic Curve defined by y^2 = x^3 + x^2 - 12*x over Rational Field has
rank equal to:  0
Elliptic Curve defined by y^2 = x^3 + 2*x^2 - 3*x over Rational Field
has rank equal to:  0
Elliptic Curve defined by y^2 = x^3 - 13*x^2 - 14*x over Rational Field
has rank equal to:  0
Elliptic Curve defined by y^2 = x^3 + x over Rational Field has rank
equal to:  0
Elliptic Curve defined by y^2 = x^3 + x^2 - 12*x over Rational Field has rank equal to:  0
Elliptic Curve defined by y^2 = x^3 + 2*x^2 - 3*x over Rational Field has rank equal to:  0
Elliptic Curve defined by y^2 = x^3 - 13*x^2 - 14*x over Rational Field has rank equal to:  0
Elliptic Curve defined by y^2 = x^3 + x over Rational Field has rank equal to:  0

Exercise 15: Compute the rank of the curve y^2 = x^3 + a for a \in \{1,...,100\}. Also compare how long this takes for a=11 to how long it takes for a=10000001.


Answer:

def s_rank(a): x,y = var('x, y') C = EllipticCurve( y^2 == x^3 + a ) return C.rank() for a in range(1,101): print a, s_rank(a) time s_rank(11) time s_rank(10000001) 
       
1 0
2 1
3 1
4 0
5 1
6 0
7 0
8 1
9 1
10 1
11 1
12 1
13 0
14 0
15 2
16 0
17 2
18 1
19 1
20 0
21 0
22 1
23 0
24 2
25 0
26 1
27 0
28 1
29 0
30 1
31 1
32 0
33 1
34 0
35 1
36 1
37 2
38 1
39 1
40 1
41 1
42 0
43 2
44 1
45 0
46 1
47 1
48 1
49 0
50 1
51 0
52 1
53 0
54 1
55 1
56 1
57 2
58 1
59 0
60 0
61 1
62 1
63 2
64 0
65 2
66 1
67 1
68 1
69 1
70 0
71 1
72 1
73 2
74 1
75 0
76 1
77 1
78 0
79 2
80 1
81 0
82 1
83 1
84 0
85 0
86 0
87 0
88 0
89 2
90 0
91 1
92 1
93 0
94 1
95 0
96 0
97 1
98 1
99 1
100 1
Time: CPU 0.09 s, Wall: 0.09 s
2
Time: CPU 12.54 s, Wall: 12.91 s
1 0
2 1
3 1
4 0
5 1
6 0
7 0
8 1
9 1
10 1
11 1
12 1
13 0
14 0
15 2
16 0
17 2
18 1
19 1
20 0
21 0
22 1
23 0
24 2
25 0
26 1
27 0
28 1
29 0
30 1
31 1
32 0
33 1
34 0
35 1
36 1
37 2
38 1
39 1
40 1
41 1
42 0
43 2
44 1
45 0
46 1
47 1
48 1
49 0
50 1
51 0
52 1
53 0
54 1
55 1
56 1
57 2
58 1
59 0
60 0
61 1
62 1
63 2
64 0
65 2
66 1
67 1
68 1
69 1
70 0
71 1
72 1
73 2
74 1
75 0
76 1
77 1
78 0
79 2
80 1
81 0
82 1
83 1
84 0
85 0
86 0
87 0
88 0
89 2
90 0
91 1
92 1
93 0
94 1
95 0
96 0
97 1
98 1
99 1
100 1
Time: CPU 0.09 s, Wall: 0.09 s
2
Time: CPU 12.54 s, Wall: 12.91 s

Exercise 16: What is the smallest integer a>0 for which the rank of the Mordell-Weil group of the curve y^2 = x^3+a is at least 3?


Answer:

a = 1 while s_rank(a) != 3: a = a+1 print 'The smallest such a is:', a 
       
The smallest such a is: 113
The smallest such a is: 113

Back to top

Period lattices

Exercise 17: Find the period lattice of E_1 (a lattice L in the complex numbers \mathbb{C}, such that \mathbb{C}/L is isomorphic to E_1) and a basis for it. If one scaled the lattice so that one of the basis vectors becomes 1, then what do you notice about the real part of the other basis vector after scaling? Try the same with some other elliptic curves that are defined over the real numbers. How are the real parts related to the number of components of the elliptic curve over the reals?


Answer:

x,y,z =var('x,y,z') def real_components(C): return (sgn(C.discriminant()) + 3)/2 L = E1.period_lattice() print L print 'The lattice has basis:', L.basis() print 'After scaling, the second basis vector becomes:', L.basis()[1]/L.basis()[0] print 'The real part is equal is equal to: ', (L.basis()[1]/L.basis()[0]).real_part() print 'We notice that the real part of the second vector becomes equal to 1/2' print 'The number of real components is:', real_components(E1) #We borrow some curves from previous exercise eqs = [ y^2 == x*(x-3)*(x+4), y^2 == x*(x-1)*(x+3), y^2 == x*(x+1)*(x-14), y^2 == x*(x^2+1)] for i in range(len(eqs)): C = EllipticCurve( eqs[i] ) print ' ' print 'We check curve', C L = C.period_lattice() print 'The lattice has basis:', L.basis() print 'After scaling, the second basis vector becomes:', L.basis()[1]/L.basis()[0] print 'The real part is equal is equal to: ', (L.basis()[1]/L.basis()[0]).real_part() print 'The number of real components is:', real_components(C) print ' ' print 'It seems that the real part is 1/2 when there is one component, and 0 if there are two' 
       
Period lattice associated to Elliptic Curve defined by y^2 = x^3 - 43*x
+ 166 over Rational Field
The lattice has basis: (2.17337872342169, 1.08668936171085 +
0.451014298345391*I)
After scaling, the second basis vector becomes: 0.500000000000000 +
0.207517582409811*I
The real part is equal is equal to:  0.500000000000000
We notice that the real part of the second vector becomes equal to 1/2
The number of real components is: 1
 
We check curve Elliptic Curve defined by y^2 = x^3 + x^2 - 12*x over
Rational Field
The lattice has basis: (1.45126237045460, 1.35906289225074*I)
After scaling, the second basis vector becomes: 0.936469462668576*I
The real part is equal is equal to:  0.000000000000000
The number of real components is: 2
 
We check curve Elliptic Curve defined by y^2 = x^3 + 2*x^2 - 3*x over
Rational Field
The lattice has basis: (2.15651564749964, 1.68575035481260*I)
After scaling, the second basis vector becomes: 0.781700961348056*I
The real part is equal is equal to:  0.000000000000000
The number of real components is: 2
 
We check curve Elliptic Curve defined by y^2 = x^3 - 13*x^2 - 14*x over
Rational Field
The lattice has basis: (0.825206707256857, 1.43060476722459*I)
After scaling, the second basis vector becomes: 1.73363201564393*I
The real part is equal is equal to:  0.000000000000000
The number of real components is: 2
 
We check curve Elliptic Curve defined by y^2 = x^3 + x over Rational
Field
The lattice has basis: (3.70814935460274, 1.85407467730137 +
1.85407467730137*I)
After scaling, the second basis vector becomes: 0.500000000000000 +
0.500000000000000*I
The real part is equal is equal to:  0.500000000000000
The number of real components is: 1
 
It seems that the real part is 1/2 when there is one component, and 0 if
there are two
Period lattice associated to Elliptic Curve defined by y^2 = x^3 - 43*x + 166 over Rational Field
The lattice has basis: (2.17337872342169, 1.08668936171085 + 0.451014298345391*I)
After scaling, the second basis vector becomes: 0.500000000000000 + 0.207517582409811*I
The real part is equal is equal to:  0.500000000000000
We notice that the real part of the second vector becomes equal to 1/2
The number of real components is: 1
 
We check curve Elliptic Curve defined by y^2 = x^3 + x^2 - 12*x over Rational Field
The lattice has basis: (1.45126237045460, 1.35906289225074*I)
After scaling, the second basis vector becomes: 0.936469462668576*I
The real part is equal is equal to:  0.000000000000000
The number of real components is: 2
 
We check curve Elliptic Curve defined by y^2 = x^3 + 2*x^2 - 3*x over Rational Field
The lattice has basis: (2.15651564749964, 1.68575035481260*I)
After scaling, the second basis vector becomes: 0.781700961348056*I
The real part is equal is equal to:  0.000000000000000
The number of real components is: 2
 
We check curve Elliptic Curve defined by y^2 = x^3 - 13*x^2 - 14*x over Rational Field
The lattice has basis: (0.825206707256857, 1.43060476722459*I)
After scaling, the second basis vector becomes: 1.73363201564393*I
The real part is equal is equal to:  0.000000000000000
The number of real components is: 2
 
We check curve Elliptic Curve defined by y^2 = x^3 + x over Rational Field
The lattice has basis: (3.70814935460274, 1.85407467730137 + 1.85407467730137*I)
After scaling, the second basis vector becomes: 0.500000000000000 + 0.500000000000000*I
The real part is equal is equal to:  0.500000000000000
The number of real components is: 1
 
It seems that the real part is 1/2 when there is one component, and 0 if there are two

The elliptic curve given by y^2 = x^3 + 5 has complex multiplication: there is an automorphism that multiplies the x-coordinate by a cube root of unity. This implies that after scaling, the period lattice is contained in an imaginary quadratic field.

Exercise 18: Use the function algebraic_dependency to find generators of the scaled lattice that are contained in an imaginary quadratic field.


Answer:

x,y = var('x,y') C = EllipticCurve( y^2 == x^3 + 5) L = C.period_lattice() b = L.basis() alg_dep = algebraic_dependency(b[1]/b[0],2) z1 = solve( alg_dep(x), x )[1].right_hand_side() print 'The scaled lattice is generated by ', [1,z1], 'and is contained in:', QQ[ z1 ] 
       
The scaled lattice is generated by  [1, 1/6*I*sqrt(3) + 1/2] and is
contained in: Number Field in a with defining polynomial x^2 - x + 1/3
The scaled lattice is generated by  [1, 1/6*I*sqrt(3) + 1/2] and is contained in: Number Field in a with defining polynomial x^2 - x + 1/3

Back to top

Porism of Diophantos

Diophantos shows that if a postive rational number d is the difference of two rational cubes, then it is also the sum of two rational cubes. For instance, since 7 = 2^3 - 1^3, there should also be positive rational numbers x and y with x^3 + y^3 = 7. Indeed, one has (\tfrac{4}{3})^3+(\tfrac{5}{3})^3=7.

We consider the projective curve given by x^3 + y^3 = dz^3 with the point [1:-1:0] and make a substitution to obtain a Weierstrass model of the elliptic curve.

P2.<x,y,z> = ProjectiveSpace(QQ,2) d=7 C=Curve(x^3 + y^3 - d*z^3) E=EllipticCurve([0,-432*d^2]) transformation=[(36*d*z-y)/(72*d),(36*d*z+y)/(72*d),x/(12*d)] D=Curve(E) phi = hom(D,C,transformation) phi 
       
Scheme morphism:
  From: Projective Curve over Rational Field defined by -x^3 + y^2*z +
21168*z^3
  To:   Projective Curve over Rational Field defined by x^3 + y^3 -
7*z^3
  Defn: Defined on coordinates by sending (x : y : z) to
        (-1/504*y + 1/2*z : 1/504*y + 1/2*z : 1/84*x)
Scheme morphism:
  From: Projective Curve over Rational Field defined by -x^3 + y^2*z + 21168*z^3
  To:   Projective Curve over Rational Field defined by x^3 + y^3 - 7*z^3
  Defn: Defined on coordinates by sending (x : y : z) to
        (-1/504*y + 1/2*z : 1/504*y + 1/2*z : 1/84*x)
We can check that the transformation does indeed map E to C by doing a substitution.
f=C.defining_polynomial() g=E.defining_polynomial() 64*27*d^2*f(transformation); g; 
       
-x^3 + y^2*z + 21168*z^3
-x^3 + y^2*z + 21168*z^3
-x^3 + y^2*z + 21168*z^3
-x^3 + y^2*z + 21168*z^3

Exercise 19: Find positive rational x,y, other than \{x,y\} = \{\tfrac{4}{3},\tfrac{5}{3}\} with x^3 + y^3 = 7.


Answer:
def bad_point(P): Q = phi(P) if Q[0] <= 0 : return true if Q[1] <= 0 : return true if Q[2] <= 0 : return true if Q[0]/Q[2] == 4/3 and Q[1]/Q[2] == 5/3 : return true if Q[0]/Q[2] == 5/3 and Q[1]/Q[2] == 4/3 : return true return false x,y,z = var('x,y,z') sol = solve( [ transformation[0] + 1 , transformation[1] - 2 , transformation[2] - 1 ], x,y,z) coord = [sol[0][0].right_hand_side(), sol[0][1].right_hand_side(), sol[0][2].right_hand_side()] P = E.point( coord ) k = 1 k_max = 100 while k < k_max and bad_point(k*P): k = k+1 if k == k_max: print 'Error: point not found' else: Q = phi(k*P) xs = Q[0]/Q[2] ys = Q[1]/Q[2] print 'We have found the pair:', [xs,ys] print 'We check that it is indeed a solution to', x^3 + y^3 == 7, ' : ', xs^3 + ys^3 == 7 
       
We have found the pair: [4381019/4989780, 9226981/4989780]
We check that it is indeed a solution to x^3 + y^3 == 7  :  True
We have found the pair: [4381019/4989780, 9226981/4989780]
We check that it is indeed a solution to x^3 + y^3 == 7  :  True

Back to top

Modularity

Exercise 20 For any prime p, let N_p denote the number of points on the elliptic curve given by y^2 = x^3-4x^2+16 over \mathbb{F}_p (at least when this is nonsingular). Let M_n denote the coefficient of q^n in the formal power series expansion of the infinite product

q\prod_{n\geq 1} (1-q^n)^2(1-q^{11n})^2.
Compute M_p+N_p for all primes p up to 100. Conjecture what M_p+N_p equals for general primes p.


Answer:

def C(p): return EllipticCurve(GF(p), [0,-4,0,0,16]) def N(p): if p in Primes(): myC = C(p) return myC.cardinality() else: return 0 def M(p): X = var('X') R = ZZ[X].quotient(X^(p+1)) fact = [ R( (1-X^n)^2*(1-X^(11*n))^2 ) for n in range(1,p+1)] F = R(X)*prod(fact) return F.matrix()[0,p] def good_Primes(n): P = [] for p in Set(range(n)).intersection(Primes()) : if EllipticCurve([0,-4,0,0,16]).discriminant() %p != 0 : P.append(p) return P for p in good_Primes(101): print p, M(p) + N(p) print 'Conjecture: M(p) + N(p) == p+1' print 'Checking if conjecture holds for small p:', prod( [ M(p) + N(p) == p + 1 for p in good_Primes(101)] ) == True 
       
3 4
5 6
7 8
13 14
17 18
19 20
23 24
29 30
31 32
37 38
41 42
43 44
47 48
53 54
59 60
61 62
67 68
71 72
73 74
79 80
83 84
89 90
97 98
Conjecture: M(p) + N(p) == p+1
Checking if conjecture holds for small p: True
3 4
5 6
7 8
13 14
17 18
19 20
23 24
29 30
31 32
37 38
41 42
43 44
47 48
53 54
59 60
61 62
67 68
71 72
73 74
79 80
83 84
89 90
97 98
Conjecture: M(p) + N(p) == p+1
Checking if conjecture holds for small p: True

Back to top

Heights

Given a Weierstrass model of an elliptic curve C over \mathbb{Q}, we define the naive logarithmic height of a rational point P \in C(\mathbb{Q}) by

h_{\rm n}(P) = \log \left( \max (|d|,|n|)\right),
with d,n \in \mathbb{Z} such that \gcd(d,n)=1 and x(P) = \tfrac{d}{n}.

Exercise 21: Take your favorite elliptic curve in short Weierstrass form with a point P of infinite order. For m \in \{1,\ldots,100\}, compute the square root of h_{\rm n}(mP). How do the values seem to grow asymptotically?


Answer:

x,y = var('x,y') def h(P): x = P.xy()[1] return log(max( [ abs(x.denominator()), abs(x.numerator()) ])) C = EllipticCurve('43') k = 1; k_max = 10 #all due respect, but manually looking for point on a curve is not my favorite thing to do P = C.point_set().an_element() while P in C.torsion_points() and k < k_max: S = Set(C.point_set().points(B = k)).difference(C.torsion_points()) if S.cardinality() > 0: P = S.an_element() k = k+1 if k == k_max: print 'Error: No points found' else: for m in range(1,101): x = RR( sqrt( h(m*P) ) ) print m, x, x/m print 'The values appear to grow more or less as quickly as ', RR(sqrt( h(100*P) )/100).N(digits = 4) , ' times the number of steps.' 
       
1 0.000000000000000 0.000000000000000
2 0.000000000000000 0.000000000000000
3 0.000000000000000 0.000000000000000
4 1.17741002251547 0.294352505628869
5 1.48230380736751 0.296460761473502
6 1.81544398591759 0.302573997652931
7 2.14125371655733 0.305893388079618
8 2.42783912858016 0.303479891072519
9 2.68210473665648 0.298011637406275
10 2.99786537734135 0.299786537734135
11 3.36596368223241 0.305996698384764
12 3.67427259871219 0.306189383226016
13 3.96948614862678 0.305345088355906
14 4.27984795441094 0.305703425315067
15 4.58695582107769 0.305797054738513
16 4.86639860828394 0.304149913017746
17 5.19926666065002 0.305839215332354
18 5.52317636041921 0.306843131134401
19 5.82717389263560 0.306693362770295
20 6.11700469660172 0.305850234830086
21 6.41531254757732 0.305491073694158
22 6.74159905810135 0.306436320822789
23 7.03312615848499 0.305788093847173
24 7.36054263309730 0.306689276379054
25 7.67401065554653 0.306960426221861
26 7.97516709696273 0.306737196037028
27 8.26535791178422 0.306124367103119
28 8.54661573284228 0.305236276172939
29 8.89494856293102 0.306722364239001
30 9.19991646206683 0.306663882068894
31 9.51079561831533 0.306799858655333
32 9.82123233984048 0.306913510620015
33 10.1230491983530 0.306759066616758
34 10.4156886935877 0.306343785105521
35 10.7227946157636 0.306365560450389
36 11.0472566788736 0.306868241079822
37 11.3544699818635 0.306877567077391
38 11.6574791729444 0.306775767709063
39 11.9654185183096 0.306805603033579
40 12.2719037008736 0.306797592521840
41 12.5678566323561 0.306533088594051
42 12.8844009679590 0.306771451618071
43 13.1983617253231 0.306938644774955
44 13.5040957050341 0.306911266023502
45 13.8035143012390 0.306744762249755
46 14.1065433194617 0.306663985205688
47 14.4217252116525 0.306845217269202
48 14.7210982466786 0.306689546805805
49 15.0378186445131 0.306894258051289
50 15.3480213436956 0.306960426873912
51 15.6520772011161 0.306903474531687
52 15.9503381240622 0.306737271616581
53 16.2440712557192 0.306491910485269
54 16.5721121054460 0.306890964915667
55 16.8778102522147 0.306869277312994
56 17.1870732127928 0.306912021657015
57 17.4959731944123 0.306946898147584
58 17.7999669107201 0.306895981219312
59 18.0986322749302 0.306756479236105
60 18.4051668224679 0.306752780374465
61 18.7225799201786 0.306927539675058
62 19.0296751866678 0.306930244946254
63 19.3343663895066 0.306894704595342
64 19.6419491293394 0.306905455145929
65 19.9484352427306 0.306899003734317
66 20.2484873782781 0.306795263307243
67 20.5612249689937 0.306883954761100
68 20.8726842185895 0.306951238508669
69 21.1789078658196 0.306940693707530
70 21.4810898576056 0.306872712251509
71 21.7856283763469 0.306839836286577
72 22.0976050329308 0.306911181012928
73 22.3995002522791 0.306842469209302
74 22.7128862914259 0.306930895830080
75 23.0220320643171 0.306960427524228
76 23.3270806129920 0.306935271223579
77 23.6281914890649 0.306859629728116
78 23.9264631443001 0.306749527491026
79 24.2472815835689 0.306927614981885
80 24.5532741185037 0.306915926481296
81 24.8619506926407 0.306937662872107
82 25.1702679614597 0.306954487334875
83 25.4751347927389 0.306929334852276
84 25.7762573493646 0.306860206540055
85 26.0826133365776 0.306854274547971
86 26.3971412985040 0.306943503470977
87 26.7041930134459 0.306944747280988
88 27.0096191664443 0.306927490527776
89 27.3170620041596 0.306933280945614
90 27.6235679810017 0.306928533122241
91 27.9254811640436 0.306873419385094
92 28.2365175589096 0.306918669118582
93 28.5468397749223 0.306955266397014
94 28.8532938583025 0.306949934662793
95 29.1567897372642 0.306913576181729
96 29.4620663979670 0.306896524978823
97 29.7725230460113 0.306933227278467
98 30.0756629003650 0.306894519391480
99 30.3874189205198 0.306943625459796
100 30.6960428172806 0.306960428172806
The values appear to grow more or less as quickly as  0.3070  times the
number of steps.
1 0.000000000000000 0.000000000000000
2 0.000000000000000 0.000000000000000
3 0.000000000000000 0.000000000000000
4 1.17741002251547 0.294352505628869
5 1.48230380736751 0.296460761473502
6 1.81544398591759 0.302573997652931
7 2.14125371655733 0.305893388079618
8 2.42783912858016 0.303479891072519
9 2.68210473665648 0.298011637406275
10 2.99786537734135 0.299786537734135
11 3.36596368223241 0.305996698384764
12 3.67427259871219 0.306189383226016
13 3.96948614862678 0.305345088355906
14 4.27984795441094 0.305703425315067
15 4.58695582107769 0.305797054738513
16 4.86639860828394 0.304149913017746
17 5.19926666065002 0.305839215332354
18 5.52317636041921 0.306843131134401
19 5.82717389263560 0.306693362770295
20 6.11700469660172 0.305850234830086
21 6.41531254757732 0.305491073694158
22 6.74159905810135 0.306436320822789
23 7.03312615848499 0.305788093847173
24 7.36054263309730 0.306689276379054
25 7.67401065554653 0.306960426221861
26 7.97516709696273 0.306737196037028
27 8.26535791178422 0.306124367103119
28 8.54661573284228 0.305236276172939
29 8.89494856293102 0.306722364239001
30 9.19991646206683 0.306663882068894
31 9.51079561831533 0.306799858655333
32 9.82123233984048 0.306913510620015
33 10.1230491983530 0.306759066616758
34 10.4156886935877 0.306343785105521
35 10.7227946157636 0.306365560450389
36 11.0472566788736 0.306868241079822
37 11.3544699818635 0.306877567077391
38 11.6574791729444 0.306775767709063
39 11.9654185183096 0.306805603033579
40 12.2719037008736 0.306797592521840
41 12.5678566323561 0.306533088594051
42 12.8844009679590 0.306771451618071
43 13.1983617253231 0.306938644774955
44 13.5040957050341 0.306911266023502
45 13.8035143012390 0.306744762249755
46 14.1065433194617 0.306663985205688
47 14.4217252116525 0.306845217269202
48 14.7210982466786 0.306689546805805
49 15.0378186445131 0.306894258051289
50 15.3480213436956 0.306960426873912
51 15.6520772011161 0.306903474531687
52 15.9503381240622 0.306737271616581
53 16.2440712557192 0.306491910485269
54 16.5721121054460 0.306890964915667
55 16.8778102522147 0.306869277312994
56 17.1870732127928 0.306912021657015
57 17.4959731944123 0.306946898147584
58 17.7999669107201 0.306895981219312
59 18.0986322749302 0.306756479236105
60 18.4051668224679 0.306752780374465
61 18.7225799201786 0.306927539675058
62 19.0296751866678 0.306930244946254
63 19.3343663895066 0.306894704595342
64 19.6419491293394 0.306905455145929
65 19.9484352427306 0.306899003734317
66 20.2484873782781 0.306795263307243
67 20.5612249689937 0.306883954761100
68 20.8726842185895 0.306951238508669
69 21.1789078658196 0.306940693707530
70 21.4810898576056 0.306872712251509
71 21.7856283763469 0.306839836286577
72 22.0976050329308 0.306911181012928
73 22.3995002522791 0.306842469209302
74 22.7128862914259 0.306930895830080
75 23.0220320643171 0.306960427524228
76 23.3270806129920 0.306935271223579
77 23.6281914890649 0.306859629728116
78 23.9264631443001 0.306749527491026
79 24.2472815835689 0.306927614981885
80 24.5532741185037 0.306915926481296
81 24.8619506926407 0.306937662872107
82 25.1702679614597 0.306954487334875
83 25.4751347927389 0.306929334852276
84 25.7762573493646 0.306860206540055
85 26.0826133365776 0.306854274547971
86 26.3971412985040 0.306943503470977
87 26.7041930134459 0.306944747280988
88 27.0096191664443 0.306927490527776
89 27.3170620041596 0.306933280945614
90 27.6235679810017 0.306928533122241
91 27.9254811640436 0.306873419385094
92 28.2365175589096 0.306918669118582
93 28.5468397749223 0.306955266397014
94 28.8532938583025 0.306949934662793
95 29.1567897372642 0.306913576181729
96 29.4620663979670 0.306896524978823
97 29.7725230460113 0.306933227278467
98 30.0756629003650 0.306894519391480
99 30.3874189205198 0.306943625459796
100 30.6960428172806 0.306960428172806
The values appear to grow more or less as quickly as  0.3070  times the number of steps.