## Sunday, 24 May 2020

### rational conics

I’m currently reading Elliptic Tales, some light relief from lockdown.  On reading the preface alone, I discovered something I hadn’t known before.  This might be quite well-know to people with a “traditonal” maths background, but I did “modern maths” at school: lots of cool set and group theory, very little classical geometry.

The discussion in the book is just about circles, but a little googling helped me discover this is a result that applies more broadly.

Consider the general quadratic equation of two variables:

$a x^2 + b x y + c y^2 + d x + e y + f = 0$

where not all of the coefficients of the quadratic terms, $a,b,c$,  are zero.  Depending on the coefficent values, this gives a circle, ellipse, parabola, or hyperbola, that is, a conic section.

Let’s now consider the restricted case where all the coefficients are rational numbers.  A rational solution to this equation is a solution $(x,y)$ where both $x$ and $y$ are rational numbers.

Now comes the interesting bit.  Take a straight line with rational slope, $y = q x + r$, where $q$ is rational, that cuts the quadratic curve at two points.  Then either both points are rational solutions, or neither is.

The book proves this for the case of a circle, and then shows how to use the result to find all the rational points on the unit circle, $x^2+y^2=1$.  You need one point that you know is rational, so let’s chose $(-1,0)$.  Then draw a straight line with rational slope that crosses the $y$ axis at $q$; that is, $q$ is rational.  This line has equation $y=q(x+1)$.  Then solve for the other point where the line crosses the circle to get a rational solution:

It is clear from the form of the solution that if $q$ is rational, so is the point $(x_q,y_q)$.  Additionally, there are no rational solutions that correspond to an irrational value of $q$, so we can use $q$ to parameterise all the rational solutions.

Notice also that if we scale up the yellow right-angled triangle, multiplying it by a suitable integer $n$, so that both  $n x_q$ and $n y_q$ are integers, the three sides form a Pythagorean triple.

These points and triples can be generated very easily, just by scanning through values of $q$ and printing out the unique triples.  And Python’s fraction module makes this particularly straightforward (with a bit of fiddling to print in a fixed width format to make things line up neatly; yes, I’m a bit picky about things like this):
from fractions import Fraction as frac

found = set()
for denom in range(1,15):
for num in range(1,denom):
q = frac(num,denom)
xq = (1-q*q)/(1+q*q)
yq = 2*q/(1+q*q)

n = xq.denominator
triple = sorted([int(xq*n), int(yq*n), n])

if triple[0] not in found:
print( '{0:<7}  ({1:^7}, {2:^7})  {3}'.format(str(q),str(xq),str(yq),triple) )

This gives the output:
1/2      (  3/5  ,   4/5  )  [3, 4, 5]
2/3      ( 5/13  ,  12/13 )  [5, 12, 13]
1/4      ( 15/17 ,  8/17  )  [8, 15, 17]
3/4      ( 7/25  ,  24/25 )  [7, 24, 25]
2/5      ( 21/29 ,  20/29 )  [20, 21, 29]
4/5      ( 9/41  ,  40/41 )  [9, 40, 41]
1/6      ( 35/37 ,  12/37 )  [12, 35, 37]
5/6      ( 11/61 ,  60/61 )  [11, 60, 61]
2/7      ( 45/53 ,  28/53 )  [28, 45, 53]
4/7      ( 33/65 ,  56/65 )  [33, 56, 65]
6/7      ( 13/85 ,  84/85 )  [13, 84, 85]
1/8      ( 63/65 ,  16/65 )  [16, 63, 65]
3/8      ( 55/73 ,  48/73 )  [48, 55, 73]
5/8      ( 39/89 ,  80/89 )  [39, 80, 89]
7/8      (15/113 , 112/113)  [15, 112, 113]
2/9      ( 77/85 ,  36/85 )  [36, 77, 85]
4/9      ( 65/97 ,  72/97 )  [65, 72, 97]
8/9      (17/145 , 144/145)  [17, 144, 145]
3/10     (91/109 , 60/109 )  [60, 91, 109]
7/10     (51/149 , 140/149)  [51, 140, 149]
9/10     (19/181 , 180/181)  [19, 180, 181]
2/11     (117/125, 44/125 )  [44, 117, 125]
4/11     (105/137, 88/137 )  [88, 105, 137]
6/11     (85/157 , 132/157)  [85, 132, 157]
8/11     (57/185 , 176/185)  [57, 176, 185]
10/11    (21/221 , 220/221)  [21, 220, 221]
1/12     (143/145, 24/145 )  [24, 143, 145]
5/12     (119/169, 120/169)  [119, 120, 169]
7/12     (95/193 , 168/193)  [95, 168, 193]
11/12    (23/265 , 264/265)  [23, 264, 265]
2/13     (165/173, 52/173 )  [52, 165, 173]
4/13     (153/185, 104/185)  [104, 153, 185]
6/13     (133/205, 156/205)  [133, 156, 205]
8/13     (105/233, 208/233)  [105, 208, 233]
10/13    (69/269 , 260/269)  [69, 260, 269]
12/13    (25/313 , 312/313)  [25, 312, 313]
3/14     (187/205, 84/205 )  [84, 187, 205]
5/14     (171/221, 140/221)  [140, 171, 221]
9/14     (115/277, 252/277)  [115, 252, 277]
11/14    (75/317 , 308/317)  [75, 308, 317]
13/14    (27/365 , 364/365)  [27, 364, 365]

and larger values are readily calculated, such as:
500/1001  (752001/1252001, 1001000/1252001)  [752001, 1001000, 1252001]


So I’ve only read the Preface so far, and yet I’ve already learned some interesting stuff, and had an excuse to play with Python.  Let’s hope the rest is as good (but I suspect it will rapidly get harder…)