Bachelor of Ecole Polytechnique
Algorithms for Discrete Mathematics, year 2, semester 1
Arithmetic 2: Modulos and Fermat
Table of contents
Arithmetic of square root and continued fractions Arithmetic of modulos
The little Fermat theorem
(Bonus) The Goldbach conjecture
Arithmetic with matrices
The aim of this Section is to use linear algebra and python to compute exact expressions in Arithmetic.
# execute this part to modify the css style from IPython.core.display import HTML def css_styling():
styles = open("./style/custom2.css").read() return HTML(styles)
css_styling()
## loading python libraries
# necessary to display plots inline:
%matplotlib inline
# load the libraries
import matplotlib.pyplot as plt # 2D plotting library
import numpy as np # package for scientific computing
from math import * # package for mathematics (pi, arctan, sqrt, factorial ...)
Do it yourself.(Theory)
Prove by induction that there exist integers such that for every 1.
Find a matrix such that 2.
,
a
nb
nn ≥ 1
(1 + √ ) 2 ⎯⎯
n= a
n+ b
n√ 2 ⎯⎯ .
2 × 2 A
( a
n+1) = A × ( ) . b
n+1a
nb
nAnswers.
For this is true with . Assume this holds for some .
Finally, one can write where
which are easily proved to be integers by induction.
1.
By the above computation we have
which can be written as:
By induction this implies that 2.
n = 1 a
1= b
1= 1 n ≥ 1
(1 + 2 √ ) ⎯⎯
n+1= (1 + √ 2 ⎯⎯ ) × (1 + √ ) 2 ⎯⎯
n= (1 + √ 2 ⎯⎯ ) × ( + a
nb
n√ 2 ⎯⎯ )
= a
n+ b
n√ 2 ⎯⎯ + a
n√ 2 ⎯⎯ + 2 b
n= ( + 2 ) + ( + ) a
nb
na
nb
n√ 2 ⎯⎯ . (1 + √ ) 2 ⎯⎯
n+1= a
n+1+ b
n+1√ 2 ⎯⎯ ,
= + 2 , = + ,
a
n+1a
nb
nb
n+1a
nb
n{ a
n+1b
n+1= a
n+ 2 , b
n= a
n+ , b
n( a
n+1) = ( ) × ( ) . b
n+11 1 2
1
a
nb
n( ) a
n= × ( ) = × ( ) . b
n( 1 )
1 2 1
n−1
a
1b
1( 1 ) 1
2 1
n−1
1
1
Do it yourself. Using the powers of matrix , write a small script which returns . (Recall that a matrix can be de�ned by np.matrix([[a,b],[c,d]]) .) Your script should return something like
(1+Root(2))^100 is 5608832401712713489 + 630483757982286570 8 * SquareRoot(2)
A a
n, b
n2 × 2
Do it yourself. It can be proved that
for some constants .
Estimate numerically with a plot. Can you guess the exact value?
1.
Estimate numerically.
2.
c a
n n→+∞∼ R
nc , R
R c
Answers.
With the script below we plot , which should converge to . We obtain approximately . We can guess (?) that
1.
We then plot , which seems to converge to . 2.
n ↦ a
1/nnR
2.3803 R = 1 + √ 2 ⎯⎯ ≈ 2.414 n ↦ /(1 + a
n√ ) 2 ⎯⎯
n1/2
(1+Root(2))^100 is 5608832401712713489 + 6304837579822865708 * SquareRo ot(2)
Final value: 0.5 n=100
MatrixA=np.matrix([[1,2],[1,1]])
PowerofMatrix=(MatrixA**(n-1))*np.matrix([[1],[1]]) a=np.asscalar(PowerofMatrix[0])
b=np.asscalar(PowerofMatrix[1])
print('(1+Root(2))^'+str(n)+' is '+str(a)+' + '+str(b)+' * SquareRoot(2)')
def Coefficient_a(n):
MatrixA=np.matrix([[1,2],[1,1]])
PowerofMatrix=(MatrixA**(n-1))*np.matrix([[1],[1]]) return np.asscalar(PowerofMatrix[0])
N=50# Estimation of R:
RenormalizedValues=[Coefficient_a(n)**(1/(n+0.0)) for n in range(1,N)]
print('Final value: ' +str(RenormalizedValues[-1]) )
# Estimation of c:
#RenormalizedValues=[Coefficient_a(n)/((1+np.sqrt(2))**n) for n in range(1,N)]
#plt.plot(RenormalizedValues) plt.show()
print('Final value: '+str(RenormalizedValues[-1]))
Do it yourself.
We set
(Theory) Let us write as an integer ratio (for example , you can check ). Find a matrix such that
(Hint: Find a simple relation between and .) 1.
(Application) Compute the exact value (as a fraction) of 2.
(Side question) Compute a numerical evaluation of . Does it look familiar?
3.
= , = , = , = , …
u
11
1 + 1 u
21
1 +
1+11u
31 1 +
1+111+1
u
41
1 +
1+ 11 1+ 11+1u
nu
n= / a
nb
na
1= 1, b
1= 2
= 3, = 5
a
3b
32 × 2 B
( a
n+1) = B × ( ) . b
n+1a
nb
nu
n+1u
nr = 1 .
1 +
1+ 111+ 1
1+ 1
1+ 1
1+ 1
1+ 1
1+ 1 1+ 11+1
1 + r
Answers.
We have that
Therefore we obtain
i.e.
1.
We have that
See the script below for the answer: . 2.
According to the script below, is surprisingly close to the golden ratio . This is no coincidence, it can be proved that .
3.
= .
u
n+11 1 + u
n= = .
a
n+1b
n+11 1 +
abnnb
n+ b
na
n( a
n+1) = ( ) × ( ) . b
n+10 1
1 1
a
nb
nr = u
10= ( 0 ) ( ) = ( ) . 1 1
1
9
u
1b
1( 0 ) 1 1
1
9
1 r = 89/144 2
1 + r ϕ = (1 + √ 5 ⎯⎯ )/2 ≈ 1.61803398875...
lim u
n= ϕ
Arithmetic of modulos
Do it yourself. Write a script which computes . (Explain in the cell below the successive steps.)
38911
21025413(mod 188)
Answers. The above script shows that . Therefore the �rst simpli�cation is
Now, we observe that the small script gives So �nally
38911 ≡ 183 (mod 188)
≡ (mod 188).
38911
21025413183
21025413≡ 1 (mod 188).
183
46= = ( × ≡ 1 × (mod 188) = 7.
183
21025413183
457074×46+9183
46)
457074183
9183
9--- Question 2:
r =89 / 144 --- Question 3:
1+r = 1.6180555555555556
# Script for Question 2.
MatrixB=np.matrix([[0,1],[1,1]])
PowerofMatrix=(MatrixB**(9))*np.matrix([[1],[2]]) a=np.asscalar(PowerofMatrix[0])
b=np.asscalar(PowerofMatrix[1]) print('---')
print('Question 2:')
print('r =' +str(a)+' / '+str(b))
# Script for Question 3.
print('---') print('Question 3:')
print('1+r = ' +str(1+(a+0.0)/b))
# Too big, the kernel explodes!
#print((38911**21025413)%188) k=38911%188
print('38911 = '+str(k)+ ' mod(188) =:k') FoundAPeriod=False
i=0while FoundAPeriod == False:
i=i+1
remainder = (k**i)%188
print('for i='+str(i)+' we have k**i mod(188) = '+str(remainder)) if remainder == 1:
FoundAPeriod = True
print('We have that 21025413%'+str(i)+' = '+str(21025413%i))
print('The final answer is '+str(k)+'**'+str(21025413%i)+' (mod 188) ='+str((183**9)%
The little Fermat theorem
The "little" Fermat Theorem states the following:
Theorem
Let be a prime number. For every integer , we have
(In the sequel we will use the above formulation rather than "for every , we have ".)
p 1 ≤ a < p
≡ 1(mod p ).
a
p−1a≥ 0 ap ≡a(modp)
Do it yourself. Write a script which checks that the little Fermat Theorem is true for
p = 17
.for a = 1, a^{p-1} mod p =1 for a = 2, a^{p-1} mod p =1 for a = 3, a^{p-1} mod p =1 for a = 4, a^{p-1} mod p =1 for a = 5, a^{p-1} mod p =1 for a = 6, a^{p-1} mod p =1 for a = 7, a^{p-1} mod p =1 for a = 8, a^{p-1} mod p =1 for a = 9, a^{p-1} mod p =1 for a = 10, a^{p-1} mod p =1 for a = 11, a^{p-1} mod p =1 for a = 12, a^{p-1} mod p =1 for a = 13, a^{p-1} mod p =1 for a = 14, a^{p-1} mod p =1 for a = 15, a^{p-1} mod p =1 for a = 16, a^{p-1} mod p =1 Fermat theorem is true for n = 17 p=17
Check=True
for a in range(1,p):
Value= a**(p-1)%p
print('for a = '+str(a)+', a^{p-1} mod p ='+str(Value)) if Value != 1:
Check=False if Check==True:
print('Fermat theorem is true for n = '+str(p)) else:
print('Fermat theorem is not true for n = '+str(p))
We say that is composite if is not prime. The contraposition of the little Fermat Theorem is very useful: it says that
In this case, we say that is a Fermat witness for (the non-primeness of) . For example, you can check that
(and of course is composite). Therefore is a Fermat witness for , and this is a (somehow convoluted) proof of the fact that is composite.
n n
( there exists a < p such that a
p−1≢ 1 (mod n ) ) ⇒ p is composite.
a p
= 16384 ≡ 4 (mod 15) ≢ 1(mod 15) 2
15−115 a = 2 p = 15
15
Do it yourself.
Check that for every composite then is a Fermat witness for . The output should look like
n = 2 is prime n = 3 is prime
n = 4 is composite and 2 is a Fermat witness n = 5 is prime
n = 6 is composite and 2 is a Fermat witness ...
1.
Find the smallest composite such that is not a Fermat witness for . 2.
Same question with . 3.
n ≤ 60 a = 2 n
n a = 2 n
a = 3
To save you time we have copy/pasted the function IsPrime() from Notebook 1:
True False
def IsPrime(n):
# input: integer n
# output: True or False depending on whether n is prime or not if n==1:
return False if n==2:
return True elif n%2==0:
return False factor=3
while factor**2 < n+1:
if n%factor == 0:
return False factor=factor+2 return True
# Tests
print(IsPrime(2)) print(IsPrime(108))
Do it yourself. Find the smallest Fermat witness which proves that
1105
is not prime.---Question 1--- n = 2 is prime
n = 3 is prime
n = 4 is composite and 2 is a Fermat witness n = 5 is prime
n = 6 is composite and 2 is a Fermat witness n = 7 is prime
n = 8 is composite and 2 is a Fermat witness n = 9 is composite and 2 is a Fermat witness n = 10 is composite and 2 is a Fermat witness n = 11 is prime
n = 12 is composite and 2 is a Fermat witness n = 13 is prime
n = 14 is composite and 2 is a Fermat witness n = 15 is composite and 2 is a Fermat witness n = 16 is composite and 2 is a Fermat witness n = 17 is prime
n = 18 is composite and 2 is a Fermat witness n = 19 is prime
n = 20 is composite and 2 is a Fermat witness n = 21 is composite and 2 is a Fermat witness n = 22 is composite and 2 is a Fermat witness n = 23 is prime
n = 24 is composite and 2 is a Fermat witness n = 25 is composite and 2 is a Fermat witness n = 26 is composite and 2 is a Fermat witness n = 27 is composite and 2 is a Fermat witness n = 28 is composite and 2 is a Fermat witness n = 29 is prime
n = 30 is composite and 2 is a Fermat witness ---Questions 2-3---
n = 341 is composite and a = 2 is NOT a Fermat witness n = 91 is composite and a = 3 is NOT a Fermat witness
# Question 1
print('---Question 1---') for n in range(2,31):
if not IsPrime(n):
if (2**(n-1)-1)%n!=0:
print('n = '+str(n)+' is composite and 2 is a Fermat witness') else:
print('n = '+str(n)+' is composite and 2 is NOT a Fermat witness') else:
print('n = '+str(n)+' is prime')
# Question 2 print('')
print('---Questions 2-3---') for a in [2,3]:
Check=True n=a+1
while Check==True:
if IsPrime(n)==False:
if (a**(n-1)-1)%n==0:
print('n = '+str(n)+' is composite and a = '+str(a)+' is NOT a Fermat witness' Check=False
n=n+1 print('')
Fermat prime numbers
A Fermat number is an integer of the form for some . First Fermat
numbers are given by
F
n= 2
2n+ 1 n ≥ 0
= + 1 = 3, = + 1 = 5, = + 1 = 17, , = + 1 = 257.
F
02
1F
12
2F
22
4F
32
8Do it yourself. Fermat conjectured that every Fermat number is prime. Can you test his conjecture up to
n = 8
?(Bonus) The Goldbach conjecture
Goldbach's conjecture is one of the most famous unsolved problems in number theory. It states that
Every even integer can be written as the sum of two primes.
We will try to check the conjecture.
≥ 2
p=1105 a=2Test=False
while a<p and Test==False:
if (a**(p-1)-1)%p!=0:
Test=True a=a+1
print('a = '+str(a-1)+' is the smallest Fermat witness of p = '+str(p))
def Fermat(n):
return 2**(2**n)+1
# With my code it works only up to n=6 !!!
for n in range(7):
F=Fermat(n) if IsPrime(F):
print('For n = '+str(n)+', F_n = '+str(F)+' => prime') else:
print('For n = '+str(n)+', F_n = '+str(F)+' => not prime')
Do it yourself. Write a script which checks the conjecture for every (and returns a decomposition for every ).
For you should get something like
For n = 60, we have 60 = 7 + 53, Goldbach is true For n = 62, we have 62 = 3 + 59, Goldbach is true For n = 64, we have 64 = 3 + 61, Goldbach is true For n = 66, we have 66 = 5 + 61, Goldbach is true For n = 68, we have 68 = 7 + 61, Goldbach is true For n = 70, we have 70 = 3 + 67, Goldbach is true
M ≤ n ≤ N n
M = 60, N = 70
For n = 1100, we have 1100 = 3 + 1097, Goldbach is true For n = 1102, we have 1102 = 5 + 1097, Goldbach is true For n = 1104, we have 1104 = 7 + 1097, Goldbach is true For n = 1106, we have 1106 = 3 + 1103, Goldbach is true For n = 1108, we have 1108 = 5 + 1103, Goldbach is true For n = 1110, we have 1110 = 7 + 1103, Goldbach is true For n = 1112, we have 1112 = 3 + 1109, Goldbach is true For n = 1114, we have 1114 = 5 + 1109, Goldbach is true For n = 1116, we have 1116 = 7 + 1109, Goldbach is true For n = 1118, we have 1118 = 31 + 1087, Goldbach is true For n = 1120, we have 1120 = 3 + 1117, Goldbach is true For n = 1122, we have 1122 = 5 + 1117, Goldbach is true For n = 1124, we have 1124 = 7 + 1117, Goldbach is true For n = 1126, we have 1126 = 3 + 1123, Goldbach is true For n = 1128, we have 1128 = 5 + 1123, Goldbach is true For n = 1130, we have 1130 = 7 + 1123, Goldbach is true For n = 1132, we have 1132 = 3 + 1129, Goldbach is true For n = 1134, we have 1134 = 5 + 1129, Goldbach is true For n = 1136, we have 1136 = 7 + 1129, Goldbach is true For n = 1138, we have 1138 = 29 + 1109, Goldbach is true def IsPrime(n):
# input: integer n
# output: True or False depending on whether n is prime or not if n==1:
return False if n==2:
return True elif n%2==0:
return False factor=3
while factor**2 < n+1:
if n%factor == 0:
return False factor=factor+2 return True
M=1100 N=1140
for n in range(M,N,2): # we test the conjecture for even integers GoldbachTrueFor_n = False # so far Goldbach is False
p=2
while GoldbachTrueFor_n == False and p <= n:
if IsPrime(p) and IsPrime(n-p):
print('For n = '+str(n)+', we have '+str(n)+' = '+str(p)+' + '+str(n-p)+
GoldbachTrueFor_n = True # We have an example: Goldbach holds p = p+1