The Brouncker algorithm for the continued fractions of a root of a quadratic.

>    with(linalg):

>   

 Basic calculations and functions.

To start, we create a matrix from   x^2-7*y^2

>    A:=matrix(2,4,[1,0,1,0,0,1,0,-7]);

>   

A := matrix([[1, 0, 1, 0], [0, 1, 0, -7]])

The function "fun" produces a polynomial in x,y from a 2 x 2 matrix. We need its values to calculate  steps.

>   

>    fun:=m-> unapply(m[1,3]*x^2+2*m[1,4]*x*y+m[2,4]*y^2,x,y);

fun := m -> unapply(x^2*m[1,3]+2*x*y*m[1,4]+y^2*m[2,4],x,y)

>    fun(A)(x,y);fun(A)(3,1);

x^2-7*y^2

2

The function ch(m,t,n) changes matrix m as follows:

If n=1 then it add t times row 1 to row 2.

If n=2 it adds t times row 2 to row 1.

Then it makes  a symmetric matrix operation on the last two columns.

>    ch:=proc(m,t,n) local tmp:
tmp:=copy(m); if n=1 then  tmp:=addrow(tmp,1,2,t); tmp:=addcol(tmp,3,4,t);
elif n=2 then  tmp:=addrow(tmp,2,1,t);tmp:=addcol(tmp,4,3,t);fi;op(tmp);end:

>   

Case of sqrt(7)

We start work on x^2-7*y^2  .

We shall record the t-values as we proceed .

>    A:=matrix(2,4,[1,0,1,0,0,1,0,-7]);

A := matrix([[1, 0, 1, 0], [0, 1, 0, -7]])

We check the function at (1,1);

If it is negative,  then we try values at (t,1) and stop just before the values change sign.

>    fun(A)(1,1); fun(A)(2,1);fun(A)(3,1);

-6

-3

2

So set t=2 and n=1(because the value at (1,1) was less than 1.)

>    tvals:=[2];

tvals := [2]

>    A1:=ch(A,2,1);

A1 := matrix([[1, 0, 1, 2], [2, 1, 2, -3]])

Repeat with new matrix. Here, the value at (1,1) is bigger than 1 , so we try (1,t), until sign changes.

>    fun(A1)(1,1);fun(A1)(1,2);

2

-3

So we set t=1 and n=2 (because the value at (1,1) was bigger  than 1.)

>    tvals:=[op(tvals),1];

tvals := [2, 1]

>    A2:=ch(A1,1,2);

A2 := matrix([[3, 1, 2, -1], [2, 1, -1, -3]])

Repeat! Again, we get t=1, n=1.

>    fun(A2)(1,1);fun(A2)(2,1);

-3

1

>    tvals:=[op(tvals),1];

tvals := [2, 1, 1]

>    A3:=ch(A2,1,1);

A3 := matrix([[3, 1, 2, 1], [5, 2, 1, -3]])

>    fun(A3)(1,1);

1

This is a special case. When the function evalutes to 1, then set t=1 and reverse the order of row operations (i.e. change n from 1 to 2 or 2 to 1.

>    tvals:=[op(tvals),1];

tvals := [2, 1, 1, 1]

>    A4:=ch(A3,1,2);

A4 := matrix([[8, 3, 1, -2], [5, 2, -2, -3]])

>    fun(A4)(1,1);fun(A4)(2,1);fun(A4)(3,1);fun(A4)(4,1);fun(A4)(5,1);

-6

-7

-6

-3

2

Now we get t=4, n=1.

>    tvals:=[op(tvals),4];

tvals := [2, 1, 1, 1, 4]

>    A5:=ch(A4,4,1);

A5 := matrix([[8, 3, 1, 2], [37, 14, 2, -3]])

>    seq(cat(A,i)=op(cat(A,i)),i=1..5);

A1 = matrix([[1, 0, 1, 2], [2, 1, 2, -3]]), A2 = matrix([[3, 1, 2, -1], [2, 1, -1, -3]]), A3 = matrix([[3, 1, 2, 1], [5, 2, 1, -3]]), A4 = matrix([[8, 3, 1, -2], [5, 2, -2, -3]]), A5 = matrix([[8, 3, 1...

Note that A1 and A4 have a  repeat of the second part .  So, now the pattern repeats!

>    convert(sqrt(7), confrac,10,'ans7');

[2, 1, 1, 1, 4, 1, 1, 1, 4, 1]

>    ans7;

[2, 3, 5/2, 8/3, 37/14, 45/17, 82/31, 127/48, 590/223, 717/271]

>    evalf(ans7);

[2., 3., 2.500000000, 2.666666667, 2.642857143, 2.647058824, 2.645161290, 2.645833333, 2.645739910, 2.645756458]

>    seq(evalf[20](sqrt(7)-ans7[i]),i=1..nops(ans7));

.6457513110645905905, -.3542486889354094095, .1457513110645905905, -.209153556020760762e-1, .28941682074477334e-2, -.13075124648211742e-2, .5900207420099453e-3, -.820222687427428e-4, .114007506892452e-...
.6457513110645905905, -.3542486889354094095, .1457513110645905905, -.209153556020760762e-1, .28941682074477334e-2, -.13075124648211742e-2, .5900207420099453e-3, -.820222687427428e-4, .114007506892452e-...

>   

>   

>   

>   

>   

>   

Case of sqrt(12)

We set D=12. This should be non square.

Starting matrix

>    A:=matrix(2,4,[1,0,1,0,0,1,0,-12]);tvals:=[];

A := matrix([[1, 0, 1, 0], [0, 1, 0, -12]])

tvals := []

Check the value of fun at (1,1).

>    fun(A)(x,y);fun(A)(1,1);

x^2-12*y^2

-11

For a negative value (or < 1), we increase the first coordinate until sign changes. Add the tvalue just before the change to the list.

>    seq([t,fun(A)(t,1)],t=1..5);

[1, -11], [2, -8], [3, -3], [4, 4], [5, 13]

Thus 3 is the turning point.

>    tvals:=[op(tvals),3];

tvals := [3]

ch does the necessary row/col operations.

>    A1:=ch(A,3,1);

A1 := matrix([[1, 0, 1, 3], [3, 1, 3, -3]])

>    fun(A1)(1,1);

4

Since the value is bigger than 1, we increase the second coordinate.

>    seq([t,fun(A1)(1,t)],t=1..5);

[1, 4], [2, 1], [3, -8], [4, -23], [5, -44]

>    tvals:=[op(tvals),2];A2:=ch(A1,2,2);

tvals := [3, 2]

A2 := matrix([[7, 2, 1, -3], [3, 1, -3, -3]])

>    fun(A2)(1,1);

-8

>    seq([t,fun(A2)(t,1)],t=1..10);

[1, -8], [2, -11], [3, -12], [4, -11], [5, -8], [6, -3], [7, 4], [8, 13], [9, 24], [10, 37]

>    tvals:=[op(tvals),6];A3:=ch(A2,6,1);

tvals := [3, 2, 6]

A3 := matrix([[7, 2, 1, 3], [45, 13, 3, -3]])

>    fun(A3)(1,1);

4

>    seq([t,fun(A3)(1,t)],t=1..5);

[1, 4], [2, 1], [3, -8], [4, -23], [5, -44]

>    tvals:=[op(tvals),2];

tvals := [3, 2, 6, 2]

>    A4:=ch(A3,2,2);

A4 := matrix([[97, 28, 1, -3], [45, 13, -3, -3]])

>   

13

>    seq(cat(A,i)=op(cat(A,i)),i=1..4);

A1 = matrix([[1, 0, 1, 3], [3, 1, 3, -3]]), A2 = matrix([[7, 2, 1, -3], [3, 1, -3, -3]]), A3 = matrix([[7, 2, 1, 3], [45, 13, 3, -3]]), A4 = matrix([[97, 28, 1, -3], [45, 13, -3, -3]])

>    tvals;

[3, 2, 6, 2]

Note that A4 and A2 share the same RHS.  So the sequence [2,6] will repeat!

Doublecheck using Maple directly!

>    unassign('ans12');convert(sqrt(12),confrac,12,ans12);# calculates 12 "a"s.

[3, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2]

>    ans12;# successive continued fractions.

[3, 7/2, 45/13, 97/28, 627/181, 1351/390, 8733/2521, 18817/5432, 121635/35113, 262087/75658, 1694157/489061, 3650401/1053780]

>    evalf(%);#evaluations.

[3., 3.500000000, 3.461538462, 3.464285714, 3.464088398, 3.464102564, 3.464101547, 3.464101620, 3.464101615, 3.464101615, 3.464101615, 3.464101615]
[3., 3.500000000, 3.461538462, 3.464285714, 3.464088398, 3.464102564, 3.464101547, 3.464101620, 3.464101615, 3.464101615, 3.464101615, 3.464101615]

>    evalf[20](sqrt(12));

3.4641016151377545870

>    seq(evalf[20](sqrt(12)-ans12[i]),i=1..12);

.4641016151377545870, -.358983848622454130e-1, .25631535992930485e-2, -.1840991479596987e-3, .132173476993384e-4, -.9489648095156e-6, .681325979031e-7, -.48917004940e-8, .3512082936e-9, -.252156210e-10...
.4641016151377545870, -.358983848622454130e-1, .25631535992930485e-2, -.1840991479596987e-3, .132173476993384e-4, -.9489648095156e-6, .681325979031e-7, -.48917004940e-8, .3512082936e-9, -.252156210e-10...

>