« Mathématiques avec Python et Ruby/Suites en Ruby » : différence entre les versions
Ligne 72 : | Ligne 72 : | ||
===Suites arithmétiques et géométriques=== |
===Suites arithmétiques et géométriques=== |
||
Les suites arithmétiques et géométriques sont aussi des suites récurrentes |
|||
====Suites arithmétiques==== |
====Suites arithmétiques==== |
||
Une suite est arithmétique de raison ''r'' si <math>\forall n, u_{n+1}=u_n +r</math>. 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 |
|||
<source lang="ruby"> |
|||
capital=2000.00 |
|||
interet=capital*3/100.0 |
|||
20.times do |
|||
capital+=interet |
|||
puts(capital) |
|||
end |
|||
</source> |
|||
====Suites géométriques==== |
====Suites géométriques==== |
||
Une suite est géométrique de raison ''r'' si <math>\forall n, u_{n+1}=u_n \times r</math>. 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 |
|||
<source lang="ruby"> |
|||
capital=2000.00 |
|||
20.times do |
|||
capital*=1.02 |
|||
puts(capital.round(2)) |
|||
end |
|||
</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 |
|||
<source lang="ruby"> |
|||
(0..20).inject{|ancetres,generation| ancetres+=2**generation} |
|||
puts(ancetres) |
|||
puts(2**21) |
|||
</source> |
|||
On a presque autant d'ancêtres à la génération 21 qu'à toutes les génération 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: |
|||
<source lang="ruby"> |
|||
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) |
|||
</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 longueurs de ce ''test'' est très petite ! |
|||
===Suite de Fibonacci=== |
===Suite de Fibonacci=== |
Version du 21 décembre 2010 à 17:47
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
Par fonction
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
Pour une suite récurrente, chaque terme est défini à partir du précédent.
Suite logistique
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:
- 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.
- 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
Les suites arithmétiques et géométriques sont aussi des suites récurrentes
Suites arithmétiques
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
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ération 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 longueurs de ce test est très petite !