Lab 24: Lucas Sequences¶
Throughout this lab, our matrices will be sympy
matrices.
If \(P\) and \(Q\) are integers, the Lucas sequence \(U_n(P,Q)\) is defined as follows:
and for \(n>1\),
Notice that when \(P=1\) and \(Q=-1\), we have that \(U_n(1,-1)\) is the Fibonacci sequence. The Lucas numbers can be computed efficiently using matrix multiplication. The recursive definition of \(U_n(P,Q)\) means that
Starting with \(U_0(P,Q)=0\), \(U_1(P,Q)=1\), and iterating this formula, we find
Task 1¶
Write a function LucasU_pow(P,Q,n)
that calculates the value U_n(P,Q)
using the matrix powers method described above.
>>> LucasU_pow(1,-1,8)
21
>>> LucasU_pow(1,-1,167)
35600075545958458963222876581316753
>>> LucasU_pow(3,4,8)
-93
>>> LucasU_pow(2,-5,50)
157629418574481317244196082
Eigenvalues¶
We can also give an exact formula for \(U_n(P,Q)\) using the eigenvalues of the matrix, as long as \(4Q \neq P^2.\) In this case, the matrix will have two distinct eigenvalues \(\lambda_1\) and \(\lambda_2\). Suppose \(v_1\) and \(v_2\) are eigenvectors for these two eigenvalues. Then \(B = \{v_1, v_2\}\) is a basis for \(\mathbb R^2\). If
are the coordinates of
with respect to the basis \(B\), then
and so
Task 2¶
Write a function LucasU_eig(P,Q,n)
that calculates the value \(U_n(P,Q)\) using the eigenvalue method described above. You will need to think carefully about how to calculate the coordinates
Since you are using sympy
you will need to convert to floating point numbers to get a decimal expansion rather than a symbolic expression.
Also, Python doesn’t know how to convert complex numbers into floats; at the end of all the calculations, you may have a number of the form a + 0i
if some eigenvectors were imaginary. This can be solved by, instead of calling float(result)
, calling float(sp.re(result))
, since sp.re()
eliminates complex numbers in the output, allowing float()
to do its job properly.
>>> LucasU_eig(1,-1,8)
21.0
>>> LucasU_eig(1,-1,167)
3.5600075545958458e+34
>>> LucasU_eig(3,4,8)
-93.0
>>> LucasU_eig(2,-5,50)
1.5762941857448133e+26
Challenge¶
You can test if a number is probably prime using a Lucas sequence.
For simplicity, we’ll stick to the case P=1
and Q=-1
.
If m
is a positive integer not divisible by 5
, let
If m
is prime then
If m
is not prime, this will usually fail, so if a number passes this test we say it is probably prime.
Write a function Lucas_test
to implement this test to see if a number is probably prime.
In order to make this test effective for large numbers, you will need to be able to compute large powers of the matrix,
reducing modulo m
at each step.
How can you do this effectively?