« Mathématiques avec Python et Ruby/Suites en Ruby » : différence entre les versions

Un livre de Wikilivres.
Contenu supprimé Contenu ajouté
m Bot: Mise à jour des codes texvc par des équivalentes LaTeX (documentation)
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
 
Ligne 9 : Ligne 9 :
Une suite est une fonction de <math>\N</math> dans <math>\R</math> (ou <math>\Complex</math>...). On peut donc facilement calculer les premiers termes de celle-ci en utilisant la méthode ''collect'' d'une liste d'entiers (approximation finie de <math>\N</math>). Par exemple pour vérifier que la suite <math>u_n=\frac{1}{n}</math> tend vers 0, on peut essayer
Une suite est une fonction de <math>\N</math> dans <math>\R</math> (ou <math>\Complex</math>...). On peut donc facilement calculer les premiers termes de celle-ci en utilisant la méthode ''collect'' d'une liste d'entiers (approximation finie de <math>\N</math>). Par exemple pour vérifier que la suite <math>u_n=\frac{1}{n}</math> tend vers 0, on peut essayer


<source lang="ruby">
<syntaxhighlight lang="ruby">
(1..50).collect{|n| puts(1/n.to_f)}
(1..50).collect{|n| puts(1/n.to_f)}
</syntaxhighlight>
</source>


==Suites récurrentes==
==Suites récurrentes==
Ligne 21 : Ligne 21 :
La [[w:Suite logistique|suite logistique]] <math>u_{n+1}=4u_n\left(1-u_n\right)</math> est [[w:Théorie du chaos|chaotique]] sur ''[0;1]''. Pour le vérifier, on peut faire
La [[w:Suite logistique|suite logistique]] <math>u_{n+1}=4u_n\left(1-u_n\right)</math> est [[w:Théorie du chaos|chaotique]] sur ''[0;1]''. Pour le vérifier, on peut faire


<source lang="ruby">
<syntaxhighlight lang="ruby">
u=0.1
u=0.1
50.times do
50.times do
Ligne 27 : Ligne 27 :
puts(u)
puts(u)
end
end
</syntaxhighlight>
</source>


En constatant que <math>u_0=0,1=\frac{1}{10}\in \Q</math>, on peut vérifier que, quoique chaotique, cette suite est formée de fractions:
En constatant que <math>u_0=0,1=\frac{1}{10}\in \Q</math>, on peut vérifier que, quoique chaotique, cette suite est formée de fractions:


<source lang="ruby">
<syntaxhighlight lang="ruby">
require 'mathn'
require 'mathn'
u=1/10
u=1/10
Ligne 38 : Ligne 38 :
puts(u)
puts(u)
end
end
</syntaxhighlight>
</source>


Quoique chaotique, cette suite ne fait pas un bon générateur pseudo-aléatoire, parce que les nombres proches de 0 et 1 sont trop souvent visités. Pour le vérifier graphiquement, on peut dessiner un histogramme des 4000 premières valeurs de la suite, avec l'algorithme suivant:
Quoique chaotique, cette suite ne fait pas un bon générateur pseudo-aléatoire, parce que les nombres proches de 0 et 1 sont trop souvent visités. Pour le vérifier graphiquement, on peut dessiner un histogramme des 4000 premières valeurs de la suite, avec l'algorithme suivant:
Ligne 47 : Ligne 47 :
Le tout est fait en écrivant les instructions dans le langage [[w:Scalable Vector Graphics|svg]], engendrées par ''Ruby'', dans un fichier ''HistogramRuby1.svg'' visible ci-dessous. Voici le script au complet:
Le tout est fait en écrivant les instructions dans le langage [[w:Scalable Vector Graphics|svg]], engendrées par ''Ruby'', dans un fichier ''HistogramRuby1.svg'' visible ci-dessous. Voici le script au complet:


<source lang="ruby">
<syntaxhighlight lang="ruby">
figure=File.open("HistogramRuby1.svg","w")
figure=File.open("HistogramRuby1.svg","w")
figure.puts('<?xml version="1.0" encoding="utf-8"?>')
figure.puts('<?xml version="1.0" encoding="utf-8"?>')
Ligne 66 : Ligne 66 :
figure.puts('</svg>')
figure.puts('</svg>')
figure.close
figure.close
</source>
</syntaxhighlight>


Et voici le fichier produit par le script:
Et voici le fichier produit par le script:
Ligne 83 : Ligne 83 :
Par exemple, si on place 2000 € avec des intérêts (simples) correspondant à 3 % du capital de départ, soit 60 €, on peut calculer les valeurs successives du capital pendant 20 ans avec
Par exemple, si on place 2000 € avec des intérêts (simples) correspondant à 3 % du capital de départ, soit 60 €, on peut calculer les valeurs successives du capital pendant 20 ans avec


<source lang="ruby">
<syntaxhighlight lang="ruby">
capital=2000.00
capital=2000.00
interet=capital*3/100.0
interet=capital*3/100.0
Ligne 90 : Ligne 90 :
puts(capital)
puts(capital)
end
end
</syntaxhighlight>
</source>


====Suites géométriques====
====Suites géométriques====
Ligne 98 : Ligne 98 :
Si on place 2000 € à intérêts composés au taux de 2 % par an, l'affichage des valeurs successives du capital (arrondies à l'eurocent près) peut se faire avec
Si on place 2000 € à intérêts composés au taux de 2 % par an, l'affichage des valeurs successives du capital (arrondies à l'eurocent près) peut se faire avec


<source lang="ruby">
<syntaxhighlight lang="ruby">
capital=2000.00
capital=2000.00
20.times do
20.times do
Ligne 104 : Ligne 104 :
puts(capital.round(2))
puts(capital.round(2))
end
end
</syntaxhighlight>
</source>


Sachant que chaque humain a deux parents et que chacun d'entre eux a aussi deux parents, etc. on peut dire que le nombre d'ancêtres à la génération ''n'' est géométrique de raison 2. Le nombre total d'ancêtres jusqu'à la génération ''n'' s'obtient par
Sachant que chaque humain a deux parents et que chacun d'entre eux a aussi deux parents, etc. on peut dire que le nombre d'ancêtres à la génération ''n'' est géométrique de raison 2. Le nombre total d'ancêtres jusqu'à la génération ''n'' s'obtient par


<source lang="ruby">
<syntaxhighlight lang="ruby">
(0..20).inject{|ancetres,generation| ancetres+=2**generation}
(0..20).inject{|ancetres,generation| ancetres+=2**generation}


puts(ancetres)
puts(ancetres)
puts(2**21)
puts(2**21)
</syntaxhighlight>
</source>


On a presque autant d'ancêtres à la génération 21 qu'à toutes les générations précédentes cumulées!
On a presque autant d'ancêtres à la génération 21 qu'à toutes les générations précédentes cumulées!
Ligne 119 : Ligne 119 :
Ce qui donne envie de vérifier si c'est pareil pour toutes les générations ou si c'est une spécificité de la génération 21:
Ce qui donne envie de vérifier si c'est pareil pour toutes les générations ou si c'est une spécificité de la génération 21:


<source lang="ruby">
<syntaxhighlight lang="ruby">
genealogie=[1]*20
genealogie=[1]*20
(1..20).collect{|i| genealogie[i]=(0..i).inject{|a,g| a+=2**g }}
(1..20).collect{|i| genealogie[i]=(0..i).inject{|a,g| a+=2**g }}
Ligne 126 : Ligne 126 :
test=(1..20).reject{|i| generations[i]==genealogie[i-1]+2}
test=(1..20).reject{|i| generations[i]==genealogie[i-1]+2}
puts(test.size)
puts(test.size)
</syntaxhighlight>
</source>


On crée une liste des ancêtres jusqu'à la génération ''n'' comprise (''genealogie'') et une liste (''generations'') des nombres d'ancêtres à la génération ''n'' seulement. La lise ''test'' est constituée des entiers ''n'' pour lesquels le nombre d'ancêtres à la génération ''n'' n'est '''pas''' égal au total d'ancêtres jusqu'à la génération ''n-1'' augmenté de 2 (avec ''reject'', on a enlevé les positifs). La longueur de ce ''test'' est très petite !
On crée une liste des ancêtres jusqu'à la génération ''n'' comprise (''genealogie'') et une liste (''generations'') des nombres d'ancêtres à la génération ''n'' seulement. La lise ''test'' est constituée des entiers ''n'' pour lesquels le nombre d'ancêtres à la génération ''n'' n'est '''pas''' égal au total d'ancêtres jusqu'à la génération ''n-1'' augmenté de 2 (avec ''reject'', on a enlevé les positifs). La longueur de ce ''test'' est très petite !
Ligne 140 : Ligne 140 :
La récurrence de la [[w:Suite de Fibonacci|suite de Fibonacci]] est double, avec <math>u_{n+1}=u_n+u_{n-1}</math>. Son calcul pose donc un problème algorithmique, puisqu'il faut trois variables (les deux termes à calculer et une variable ''tampon'' pour stocker temporairement l'un des deux termes, afin qu'il ne soit pas écrasé par la somme). Ce problème n'existe pas en ''Ruby'' qui permet les affectations simultanées:
La récurrence de la [[w:Suite de Fibonacci|suite de Fibonacci]] est double, avec <math>u_{n+1}=u_n+u_{n-1}</math>. Son calcul pose donc un problème algorithmique, puisqu'il faut trois variables (les deux termes à calculer et une variable ''tampon'' pour stocker temporairement l'un des deux termes, afin qu'il ne soit pas écrasé par la somme). Ce problème n'existe pas en ''Ruby'' qui permet les affectations simultanées:


<source lang="ruby">
<syntaxhighlight lang="ruby">
a=1
a=1
b=1
b=1
Ligne 147 : Ligne 147 :
puts(b)
puts(b)
end
end
</syntaxhighlight>
</source>


On peut aussi le faire de manière plus ''Ruby'':
On peut aussi le faire de manière plus ''Ruby'':


<source lang="ruby">
<syntaxhighlight lang="ruby">
a=1
a=1
b=1
b=1
Ligne 158 : Ligne 158 :
puts(b)
puts(b)
}
}
</syntaxhighlight>
</source>


===Nombre d'Or===
===Nombre d'Or===
Ligne 164 : Ligne 164 :
Pour étudier le quotient de deux termes successifs de la suite:
Pour étudier le quotient de deux termes successifs de la suite:


<source lang="ruby">
<syntaxhighlight lang="ruby">
a,b=1,1
a,b=1,1
(1..20).collect{
(1..20).collect{
Ligne 172 : Ligne 172 :


puts((5**0.5+1)/2)
puts((5**0.5+1)/2)
</syntaxhighlight>
</source>


Mais en fait, les nombres de Fibonacci étant entiers, leurs quotients sont des fractions, et cette variante le montre:
Mais en fait, les nombres de Fibonacci étant entiers, leurs quotients sont des fractions, et cette variante le montre:


<source lang="ruby">
<syntaxhighlight lang="ruby">
require 'mathn'
require 'mathn'


Ligne 184 : Ligne 184 :
puts(b/a)
puts(b/a)
}
}
</syntaxhighlight>
</source>


On a donc une suite d'approximations rationnelles du [[w:Nombre d'or|nombre d'Or]].
On a donc une suite d'approximations rationnelles du [[w:Nombre d'or|nombre d'Or]].
Ligne 192 : Ligne 192 :
Algorithmiquement, la [[w:Conjecture de Syracuse|suite de Collatz]] est intéressante parce que son calcul est basé sur un test de parité, et qu'elle utilise une boucle à condition de sortie:
Algorithmiquement, la [[w:Conjecture de Syracuse|suite de Collatz]] est intéressante parce que son calcul est basé sur un test de parité, et qu'elle utilise une boucle à condition de sortie:


<source lang="ruby">
<syntaxhighlight lang="ruby">
def Collatz(x)
def Collatz(x)
if x%2==0
if x%2==0
Ligne 207 : Ligne 207 :
end
end


</syntaxhighlight>
</source>


==Multiples communs==
==Multiples communs==
Ligne 213 : Ligne 213 :
La suite des multiples de 5 et la suite des multiples de 7 sont arithmétiques de raisons respectives 5 et 7. On peut les construire en choisissant les nombres entiers qui sont divisibles respectivement par 5 et par 7:
La suite des multiples de 5 et la suite des multiples de 7 sont arithmétiques de raisons respectives 5 et 7. On peut les construire en choisissant les nombres entiers qui sont divisibles respectivement par 5 et par 7:


<source lang="ruby">
<syntaxhighlight lang="ruby">
a5=(1..1000).select{|n| n%5==0}
a5=(1..1000).select{|n| n%5==0}
a7=(1..1000).select{|n| n%7==0}
a7=(1..1000).select{|n| n%7==0}
puts(a5&a7)
puts(a5&a7)
</syntaxhighlight>
</source>


Les multiples communs à 5 et 7 sont les multiples de 35, qui est le [[w:ppcm|ppcm]] de 5 et 7. Cette construction est à l'origine de la théorie des [[w:Idéal|idéaux]] par [[w:Ernst Kummer|Kummer]].
Les multiples communs à 5 et 7 sont les multiples de 35, qui est le [[w:ppcm|ppcm]] de 5 et 7. Cette construction est à l'origine de la théorie des [[w:Idéal|idéaux]] par [[w:Ernst Kummer|Kummer]].
Ligne 229 : Ligne 229 :
La suite définie par <math>u_n=\frac{1}{2}+\frac{1}{6}+\frac{1}{12}+\frac{1}{20}+...=\frac{1}{1\times 2}+\frac{1}{2 \times 3}+\frac{1}{3\times 4}+\frac{1}{4 \times 5}+...+\frac{1}{n(n+1)}=\sum_{k=1}^n \frac{1}{k(k+1)}</math> tend vers 1, il est relativement aisé de le démontrer, et encore plus facile de le vérifier avec ''Ruby'':
La suite définie par <math>u_n=\frac{1}{2}+\frac{1}{6}+\frac{1}{12}+\frac{1}{20}+...=\frac{1}{1\times 2}+\frac{1}{2 \times 3}+\frac{1}{3\times 4}+\frac{1}{4 \times 5}+...+\frac{1}{n(n+1)}=\sum_{k=1}^n \frac{1}{k(k+1)}</math> tend vers 1, il est relativement aisé de le démontrer, et encore plus facile de le vérifier avec ''Ruby'':


<source lang="ruby">
<syntaxhighlight lang="ruby">
suite=(1..50).collect{|n|
suite=(1..50).collect{|n|
(1..n).inject(0){|somme,k|
(1..n).inject(0){|somme,k|
Ligne 237 : Ligne 237 :


puts(suite)
puts(suite)
</syntaxhighlight>
</source>


Cette suite est une suite de rationnels:
Cette suite est une suite de rationnels:


<source lang="ruby">
<syntaxhighlight lang="ruby">
require 'mathn'
require 'mathn'


Ligne 251 : Ligne 251 :


puts(suite)
puts(suite)
</syntaxhighlight>
</source>


Cette variante suggère d'ailleurs une démonstration de la convergence, grâce à l'émission d'une conjecture sur le terme général de la suite...
Cette variante suggère d'ailleurs une démonstration de la convergence, grâce à l'émission d'une conjecture sur le terme général de la suite...
Ligne 259 : Ligne 259 :
La suite <math>u_n=\frac{n}{n^2+1}+\frac{n}{n^2+2}+\frac{n}{n^2+3}+\frac{n}{n^2+4}+...+\frac{n}{n^2+n}=\sum_{k=1}^n \frac{n}{n^2+k}</math> converge aussi, bien que ce ne soit pas évident en voyant son expression algébrique.
La suite <math>u_n=\frac{n}{n^2+1}+\frac{n}{n^2+2}+\frac{n}{n^2+3}+\frac{n}{n^2+4}+...+\frac{n}{n^2+n}=\sum_{k=1}^n \frac{n}{n^2+k}</math> converge aussi, bien que ce ne soit pas évident en voyant son expression algébrique.


<source lang="ruby">
<syntaxhighlight lang="ruby">
suite=(1..20).collect{|n|
suite=(1..20).collect{|n|
(1..n).inject(0){|somme,k|
(1..n).inject(0){|somme,k|
Ligne 267 : Ligne 267 :


puts(suite)
puts(suite)
</syntaxhighlight>
</source>


Là encore, la suite est rationnelle:
Là encore, la suite est rationnelle:


<source lang="ruby">
<syntaxhighlight lang="ruby">
require 'mathn'
require 'mathn'


Ligne 281 : Ligne 281 :


puts(suite)
puts(suite)
</syntaxhighlight>
</source>




<source lang="ruby">
<syntaxhighlight lang="ruby">


</syntaxhighlight>
</source>


==Constante d'Euler==
==Constante d'Euler==
Ligne 292 : Ligne 292 :
On peut la calculer (et vérifier la lenteur de la convergence) avec
On peut la calculer (et vérifier la lenteur de la convergence) avec


<source lang="ruby">
<syntaxhighlight lang="ruby">
suite=(1..50).collect{|n|
suite=(1..50).collect{|n|
(1..n).inject(0){|s,k| s+=1.0/k}-Math.log(n)
(1..n).inject(0){|s,k| s+=1.0/k}-Math.log(n)
Ligne 298 : Ligne 298 :


puts(suite)
puts(suite)
</syntaxhighlight>
</source>


=Applications=
=Applications=
Ligne 306 : Ligne 306 :
Pour calculer <math>\sqrt{5}</math> avec la [[w:Méthode de Héron|méthode de Heron]], on utilise la suite itérée <math>u_{n+1}=\frac{u_n+\frac{5}{u_n}}{2}</math>:
Pour calculer <math>\sqrt{5}</math> avec la [[w:Méthode de Héron|méthode de Heron]], on utilise la suite itérée <math>u_{n+1}=\frac{u_n+\frac{5}{u_n}}{2}</math>:


<source lang="ruby">
<syntaxhighlight lang="ruby">
u=1.0
u=1.0
50.times do
50.times do
Ligne 312 : Ligne 312 :
puts(u)
puts(u)
end
end
</syntaxhighlight>
</source>


Mais encore une fois, cette suite qui converge vers <math>\sqrt{5}</math> est formée de fractions. On a donc une suite d'approximations rationnelles de <math>\sqrt{5}</math>:
Mais encore une fois, cette suite qui converge vers <math>\sqrt{5}</math> est formée de fractions. On a donc une suite d'approximations rationnelles de <math>\sqrt{5}</math>:


<source lang="ruby">
<syntaxhighlight lang="ruby">
require 'mathn'
require 'mathn'


Ligne 324 : Ligne 324 :
puts(u)
puts(u)
end
end
</syntaxhighlight>
</source>


On en déduit des approximations rationnelles du nombre d'Or <math>\frac{\sqrt{5}+1}{2}</math>:
On en déduit des approximations rationnelles du nombre d'Or <math>\frac{\sqrt{5}+1}{2}</math>:


<source lang="ruby">
<syntaxhighlight lang="ruby">
require 'mathn'
require 'mathn'


Ligne 336 : Ligne 336 :
puts((u+1)/2)
puts((u+1)/2)
end
end
</syntaxhighlight>
</source>


En comparant avec les quotients de nombres de Fibonacci successifs, on voit que la méthode de Heron converge beaucoup plus vite. Cette convergence peut se montrer en représentant graphiquement la suite, ce qu'on peut faire en plaçant des points dans un fichier ''svg'':
En comparant avec les quotients de nombres de Fibonacci successifs, on voit que la méthode de Heron converge beaucoup plus vite. Cette convergence peut se montrer en représentant graphiquement la suite, ce qu'on peut faire en plaçant des points dans un fichier ''svg'':


<source lang="ruby">
<syntaxhighlight lang="ruby">
figure=File.open("SuiteRuby01.svg","w")
figure=File.open("SuiteRuby01.svg","w")
figure.puts('<?xml version="1.0" encoding="utf-8"?>')
figure.puts('<?xml version="1.0" encoding="utf-8"?>')
Ligne 362 : Ligne 362 :
figure.puts('</svg>')
figure.puts('</svg>')
figure.close
figure.close
</source>
</syntaxhighlight>


Le fichier produit par ce script s'appelle ''SuiteRuby01.svg''. Le voici:
Le fichier produit par ce script s'appelle ''SuiteRuby01.svg''. Le voici:
Ligne 370 : Ligne 370 :
==Formule de l'arc tangente==
==Formule de l'arc tangente==


<source lang="ruby">
<syntaxhighlight lang="ruby">
p=(1..100).collect{|n|
p=(1..100).collect{|n|
4*(0..n).inject(0){|s,k|
4*(0..n).inject(0){|s,k|
Ligne 378 : Ligne 378 :


puts(p)
puts(p)
</syntaxhighlight>
</source>


Comme on le voit, la suite converge très lentement.
Comme on le voit, la suite converge très lentement.
Ligne 384 : Ligne 384 :
Encore une fois, les termes de la suite sont rationnels, ce qui donne une suite de fractions approchant <math>\pi</math>:
Encore une fois, les termes de la suite sont rationnels, ce qui donne une suite de fractions approchant <math>\pi</math>:


<source lang="ruby">
<syntaxhighlight lang="ruby">
require 'mathn'
require 'mathn'


Ligne 394 : Ligne 394 :


puts(p)
puts(p)
</syntaxhighlight>
</source>

Version actuelle du 16 avril 2020 à 09:27

Une suite de nombres (éventuellement complexes) ne peut se représenter en machine parce qu'elle comprend une infinité de termes. Alors on n'en représente qu'une partie sous forme de liste de nombres. Et Ruby manipule très bien ce genre d'objets.

Définition de suites[modifier | modifier le wikicode]

Par fonction[modifier | modifier le wikicode]

Une suite est une fonction de dans (ou ...). On peut donc facilement calculer les premiers termes de celle-ci en utilisant la méthode collect d'une liste d'entiers (approximation finie de ). Par exemple pour vérifier que la suite tend vers 0, on peut essayer

(1..50).collect{|n| puts(1/n.to_f)}

Suites récurrentes[modifier | modifier le wikicode]

Pour une suite récurrente, chaque terme est défini à partir du précédent.

Suite logistique[modifier | modifier le wikicode]

La suite logistique est chaotique sur [0;1]. Pour le vérifier, on peut faire

u=0.1
50.times do
    u=4*u*(1-u)
    puts(u)
end

En constatant que , on peut vérifier que, quoique chaotique, cette suite est formée de fractions:

require 'mathn'
u=1/10
10.times do
    u=4*u*(1-u)
    puts(u)
end

Quoique chaotique, cette suite ne fait pas un bon générateur pseudo-aléatoire, parce que les nombres proches de 0 et 1 sont trop souvent visités. Pour le vérifier graphiquement, on peut dessiner un histogramme des 4000 premières valeurs de la suite, avec l'algorithme suivant:

  1. On fait comme ci-dessus, mais au lieu d'afficher u, on incrémente l'entrée d'un tableau des effectifs indexée par sa troncature. C'est ce tableau qui va être représenté graphiquement.
  2. Ensuite, on représente chaque effectif par un rectangle de largeur 4 pixels et de hauteur l'effectif correspondant. Les rectangles sont bleus, remplis de vert.

Le tout est fait en écrivant les instructions dans le langage svg, engendrées par Ruby, dans un fichier HistogramRuby1.svg visible ci-dessous. Voici le script au complet:

figure=File.open("HistogramRuby1.svg","w")
figure.puts('<?xml version="1.0" encoding="utf-8"?>')
figure.puts('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"')
figure.puts('"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">')
figure.puts('<svg xmlns="http://www.w3.org/2000/svg" width="500" height="360">')

effectifs=[0]*100
u=0.1

4000.times do
    u=4*u*(1-u)
    effectifs[(100*u).to_i]+=1
end

(0..99).collect{|n| figure.puts('<rect x="'+(4*n+50).to_s+'" y="'+(320-effectifs[n]).to_s+'" width="4" height="'+effectifs[n].to_s+'" fill="green" stroke="blue" stroke-width="1" />')}

figure.puts('</svg>')
figure.close

Et voici le fichier produit par le script:


Suites arithmétiques et géométriques[modifier | modifier le wikicode]

Les suites arithmétiques et géométriques sont aussi des suites récurrentes.

Suites arithmétiques[modifier | modifier le wikicode]

Une suite est arithmétique de raison r si . Cette définition est récurrente.

Par exemple, si on place 2000 € avec des intérêts (simples) correspondant à 3 % du capital de départ, soit 60 €, on peut calculer les valeurs successives du capital pendant 20 ans avec

capital=2000.00
interet=capital*3/100.0
20.times do
    capital+=interet
    puts(capital)
end

Suites géométriques[modifier | modifier le wikicode]

Une suite est géométrique de raison r si . Les suites géométriques sont donc aussi récurrentes.

Si on place 2000 € à intérêts composés au taux de 2 % par an, l'affichage des valeurs successives du capital (arrondies à l'eurocent près) peut se faire avec

capital=2000.00
20.times do
    capital*=1.02
    puts(capital.round(2))
end

Sachant que chaque humain a deux parents et que chacun d'entre eux a aussi deux parents, etc. on peut dire que le nombre d'ancêtres à la génération n est géométrique de raison 2. Le nombre total d'ancêtres jusqu'à la génération n s'obtient par

(0..20).inject{|ancetres,generation| ancetres+=2**generation}

puts(ancetres)
puts(2**21)

On a presque autant d'ancêtres à la génération 21 qu'à toutes les générations précédentes cumulées!

Ce qui donne envie de vérifier si c'est pareil pour toutes les générations ou si c'est une spécificité de la génération 21:

genealogie=[1]*20
(1..20).collect{|i| genealogie[i]=(0..i).inject{|a,g| a+=2**g }}
generations=[1]*20
(1..20).collect{|i| generations[i]=2**i}
test=(1..20).reject{|i| generations[i]==genealogie[i-1]+2}
puts(test.size)

On crée une liste des ancêtres jusqu'à la génération n comprise (genealogie) et une liste (generations) des nombres d'ancêtres à la génération n seulement. La lise test est constituée des entiers n pour lesquels le nombre d'ancêtres à la génération n n'est pas égal au total d'ancêtres jusqu'à la génération n-1 augmenté de 2 (avec reject, on a enlevé les positifs). La longueur de ce test est très petite !

Sous Ruby on peut aussi calculer des suites géométriques de raison complexe. La somme des termes est alors particulièrement intéressante à étudier (par exemple si la raison vaut i).

Suites d'entiers[modifier | modifier le wikicode]

Suite de Fibonacci[modifier | modifier le wikicode]

Calcul des termes[modifier | modifier le wikicode]

La récurrence de la suite de Fibonacci est double, avec . Son calcul pose donc un problème algorithmique, puisqu'il faut trois variables (les deux termes à calculer et une variable tampon pour stocker temporairement l'un des deux termes, afin qu'il ne soit pas écrasé par la somme). Ce problème n'existe pas en Ruby qui permet les affectations simultanées:

a=1
b=1
for n in 1..20 do
    a,b=b,a+b
    puts(b)
end

On peut aussi le faire de manière plus Ruby:

a=1
b=1
(1..20).collect{
    a,b=b,a+b
    puts(b)
}

Nombre d'Or[modifier | modifier le wikicode]

Pour étudier le quotient de deux termes successifs de la suite:

a,b=1,1
(1..20).collect{
    a,b=b,a+b
    puts(b.to_f/a.to_f)
}

puts((5**0.5+1)/2)

Mais en fait, les nombres de Fibonacci étant entiers, leurs quotients sont des fractions, et cette variante le montre:

require 'mathn'

a,b=1,1
(1..20).collect{
    a,b=b,a+b
    puts(b/a)
}

On a donc une suite d'approximations rationnelles du nombre d'Or.

Suite de Collatz[modifier | modifier le wikicode]

Algorithmiquement, la suite de Collatz est intéressante parce que son calcul est basé sur un test de parité, et qu'elle utilise une boucle à condition de sortie:

def Collatz(x)
    if x%2==0
        return x/2
    else
        return 3*x+1
    end
end

u=65
while(u>1) do
    u=Collatz(u)
    puts(u)
end

Multiples communs[modifier | modifier le wikicode]

La suite des multiples de 5 et la suite des multiples de 7 sont arithmétiques de raisons respectives 5 et 7. On peut les construire en choisissant les nombres entiers qui sont divisibles respectivement par 5 et par 7:

a5=(1..1000).select{|n| n%5==0}
a7=(1..1000).select{|n| n%7==0}
puts(a5&a7)

Les multiples communs à 5 et 7 sont les multiples de 35, qui est le ppcm de 5 et 7. Cette construction est à l'origine de la théorie des idéaux par Kummer.

Suites et séries[modifier | modifier le wikicode]

Une série est une suite dont le terme général est défini par une somme.

Premier exemple[modifier | modifier le wikicode]

La suite définie par tend vers 1, il est relativement aisé de le démontrer, et encore plus facile de le vérifier avec Ruby:

suite=(1..50).collect{|n|
    (1..n).inject(0){|somme,k|
        somme+=1.0/(k*k.succ)
    }
}

puts(suite)

Cette suite est une suite de rationnels:

require 'mathn'

suite=(1..20).collect{|n|
    (1..n).inject(0){|somme,k|
        somme+=1/(k*k.succ)
    }
}

puts(suite)

Cette variante suggère d'ailleurs une démonstration de la convergence, grâce à l'émission d'une conjecture sur le terme général de la suite...

Deuxième exemple[modifier | modifier le wikicode]

La suite converge aussi, bien que ce ne soit pas évident en voyant son expression algébrique.

suite=(1..20).collect{|n|
    (1..n).inject(0){|somme,k|
        somme+=n.to_f/(n**2+k)
    }
}

puts(suite)

Là encore, la suite est rationnelle:

require 'mathn'

suite=(1..20).collect{|n|
    (1..n).inject(0){|somme,k|
        somme+=n/(n**2+k)
    }
}

puts(suite)


Constante d'Euler[modifier | modifier le wikicode]

On peut la calculer (et vérifier la lenteur de la convergence) avec

suite=(1..50).collect{|n|
    (1..n).inject(0){|s,k| s+=1.0/k}-Math.log(n)
}

puts(suite)

Applications[modifier | modifier le wikicode]

Méthode de Heron[modifier | modifier le wikicode]

Pour calculer avec la méthode de Heron, on utilise la suite itérée :

u=1.0
50.times do
    u=(u+5.0/u)/2.0
    puts(u)
end

Mais encore une fois, cette suite qui converge vers est formée de fractions. On a donc une suite d'approximations rationnelles de :

require 'mathn'

u=1
50.times do
    u=(u+5/u)/2
    puts(u)
end

On en déduit des approximations rationnelles du nombre d'Or :

require 'mathn'

u=1
10.times do
    u=(u+5/u)/2
    puts((u+1)/2)
end

En comparant avec les quotients de nombres de Fibonacci successifs, on voit que la méthode de Heron converge beaucoup plus vite. Cette convergence peut se montrer en représentant graphiquement la suite, ce qu'on peut faire en plaçant des points dans un fichier svg:

figure=File.open("SuiteRuby01.svg","w")
figure.puts('<?xml version="1.0" encoding="utf-8"?>')
figure.puts('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"')
figure.puts('"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">')
figure.puts('<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480">')

figure.puts('<line x1="20.0" y1="460.0" x2="540.0" y2="460.0" style="stroke:rgb(0,0,64);stroke-width:1"/>')
((0..400).select {|x| x%10==0}).collect { |x| figure.print('<text x="'+(x+20).to_s+'" y="475.0" style="font-size:6;fill:rgb(0,0,64);font-weight:normal">'+(x/10).to_s+'</text>\n'+'<line x1="'+(x+20).to_s+'" y1="455" x2="'+(x+20).to_s+'" y2="465" style="stroke:rgb(0,0,64);stroke-width:1"/>\n')}
figure.puts('<line x1="20.0" y1="460.0" x2="20.0" y2="60.0" style="stroke:rgb(0,40,0);stroke-width:1"/>')
((0..300).select {|x| x%10==0}).collect { |x| figure.print('<text x="0" y="'+(460-x).to_s+'" style="font-size:6;fill:rgb(0,40,0);font-weight:normal">'+(x/100.0).to_s+'</text>\n'+'<line x1="18" y1="'+(460-x).to_s+'" x2="22" y2="'+(460-x).to_s+'" style="stroke:rgb(0,40,0);stroke-width:1"/>\n')}

u=1.0
n=0
40.times do
    n+=1
    u=(u+5.0/u)/2.0
    figure.puts('<circle cx="'+(20+10*n).to_s+'" cy="'+(460-100*u).to_s+'" r="2" fill="white" stroke="red" stroke-width="1" />')
end

figure.puts('</svg>')
figure.close

Le fichier produit par ce script s'appelle SuiteRuby01.svg. Le voici:

Formule de l'arc tangente[modifier | modifier le wikicode]

p=(1..100).collect{|n|
    4*(0..n).inject(0){|s,k|
        s+=(-1)**k/(2*k+1.0)
    }
}

puts(p)

Comme on le voit, la suite converge très lentement.

Encore une fois, les termes de la suite sont rationnels, ce qui donne une suite de fractions approchant :

require 'mathn'

p=(1..10).collect{|n|
    4*(0..n).inject(0){|s,k|
        s+=(-1)**k/(2*k+1)
    }
}

puts(p)