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

Contenu supprimé Contenu ajouté
Aucun résumé des modifications
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
 
Ligne 7 :
Dans toute la suite, on va profiter de la gestion des fractions offerte par ''cmath'', avec
 
<sourcesyntaxhighlight lang="ruby">
require 'cmath'
</syntaxhighlight>
</source>
 
==Quaternions==
Ligne 19 :
La définition d'un quaternion se fait dans une [[w:Classe (informatique)|classe]] nommée ''Quaternion'':
 
<sourcesyntaxhighlight lang="ruby">
class Quaternion
 
end
</syntaxhighlight>
</source>
 
La première [[w:Méthode (informatique)|méthode]], l'[[w:Instance (programmation)|initialisation]], crée donc deux variables ''a'' et ''b'' (qui seront des complexes, mais Ruby ne le sait pas encore):
Ligne 29 :
=====Initialisation=====
 
<sourcesyntaxhighlight lang="ruby">
def initialize(a,b)
@a,@b = a,b
end
</syntaxhighlight>
</source>
 
Les nombres complexes ''a'' et ''b'' seront des [[w:Attribut (informatique)|propriétés]] du quaternion:
Ligne 40 :
=====Propriétés a et b=====
 
<sourcesyntaxhighlight lang="ruby">
def a
@a
Ligne 48 :
@b
end
</syntaxhighlight>
</source>
 
Désormais on accède aux deux complexes ''a'' et ''b'' d'un quaternion ''q'' par ''q.a'' et ''q.b''.
Ligne 56 :
Pour afficher un quaternion ''q'' avec ''puts(q)'', il est nécessaire de redéfinir (une sorte de '''surcharge''') sa méthode de conversion en chaîne de caractères (''string''):
 
<sourcesyntaxhighlight lang="ruby">
def to_s
'('+a.real.to_s+')+('+a.imag.to_s+')i+('+b.real.to_s+')j+('+b.imag.to_s+')k'
end
</syntaxhighlight>
</source>
 
La notation des points se lit de droite à gauche, par exemple ''a.real'' veut dire ''la partie réelle de a'' et ''q.a.real'', ''la partie réelle du a de q''.
Ligne 72 :
Le module d'un quaternion est un réel:
 
<sourcesyntaxhighlight lang="ruby">
def abs
Math.hypot(@a.abs,@b.abs)
end
</syntaxhighlight>
</source>
 
 
Ligne 83 :
Le conjugué d'un quaternion est un quaternion de même module que celui-ci:
 
<sourcesyntaxhighlight lang="ruby">
def conj
Quaternion.new(@a.conj,-@b)
end
</syntaxhighlight>
</source>
 
===Opérations===
Ligne 95 :
Pour additionner deux quaternions, on additionne leurs ''a'' respectifs, et leurs ''b'' respectifs, et on crée un nouveau quaternion à partir des deux nombres complexes obtenus:
 
<sourcesyntaxhighlight lang="ruby">
def +(q)
Quaternion.new(@a+q.a,@b+q.b)
end
</syntaxhighlight>
</source>
 
Pour calculer et afficher la somme des quaternions ''p'' et ''q'', il suffit alors d'entrer ''puts(p+q)''.
Ligne 107 :
La soustraction des quaternions relève d'un principe analogue:
 
<sourcesyntaxhighlight lang="ruby">
def -(q)
Quaternion.new(@a-q.a,@b-q.b)
end
</syntaxhighlight>
</source>
 
====Multiplication====
Ligne 117 :
Le [[w:Quaternion#Multiplication_de_Hamilton|produit]] de deux quaternions est plus difficile à définir:
 
<sourcesyntaxhighlight lang="ruby">
def *(q)
Quaternion.new(@a*q.a-@b*q.b.conj,@a*q.b+@b*q.a.conj)
end
</syntaxhighlight>
</source>
 
La multiplication des quaternions n'est pas commutative, comme le montre l'exemple suivant:
 
<sourcesyntaxhighlight lang="ruby">
p=Quaternion.new(Complex(2,1),Complex(3,4))
q=Quaternion.new(Complex(2,5),Complex(-3,-5))
puts(p*q)
puts(q*p)
</syntaxhighlight>
</source>
 
====Division====
Ligne 136 :
Pour diviser un quaternion par un autre, on peut faire ainsi:
 
<sourcesyntaxhighlight lang="ruby">
def /(q)
d=q.abs**2
Quaternion.new((@a*q.a.conj+@b*q.b.conj)/d,(-@a*q.b+@b*q.a)/d)
end
</syntaxhighlight>
</source>
 
Comme ils ont le même module, le quotient d'un quaternion par son conjugué est égal à 1:
 
<sourcesyntaxhighlight lang="ruby">
p=Quaternion.new(Complex(2,1),Complex(3,4))
 
puts((p/p.conj).abs)
</syntaxhighlight>
</source>
 
Cet exemple révèle que <math>\left(-\frac{22}{30}\right)^2+\left(\frac{4}{30}\right)^2 +\left(\frac{12}{30}\right)^2+\left(\frac{16}{30}\right)^2=1</math>, c'est-à-dire que <math>22^2+4^2+12^2+16^2=484+16+144+256=900=30^2</math>, qui est une décomposition de <math>30^2</math> comme [[w:Théorème_des_quatre_carrés_de_Lagrange|somme de 4 carrés]].
Ligne 157 :
La classe Quaternion de Ruby tient en entier dans un fichier plutôt léger, au vu de ses possibilités:
 
<sourcesyntaxhighlight lang="ruby">
require 'cmath'
 
Ligne 204 :
 
end
</syntaxhighlight>
</source>
 
Si on enregistre ce fichier sous le nom ''quaternions.rb'', il suffit d'insérer '' require 'quaternions' '' pour être en mesure d'effectuer des calculs sur les quaternions.
Ligne 219 :
Comme pour les quaternions, on décrit l'objet ''octonion'' dans une classe ''Octonion'':
 
<sourcesyntaxhighlight lang="ruby">
class Octonion
 
Ligne 233 :
@b
end
</syntaxhighlight>
</source>
 
Au passage on définit les propriétés ''a'' et ''b'' de l'octonion comme celles du quaternion, sauf que cette fois-ci ce ne sont plus des complexes mais des quaternions. Mais comme Ruby est faiblement typé, cette particularité n'apparaîtra que lorsque ''a'' ou ''b'' sera utilisé.
Ligne 241 :
Là encore, la méthode ''to_s'' se définit comme celle des quaternions, mais il y a 8 nombres à afficher au lieu de 4:
 
<sourcesyntaxhighlight lang="ruby">
def to_s
'('+a.a.real.to_s+')+('+a.a.imag.to_s+')i+('+a.b.real.to_s+')j+('+a.b.imag.to_s+')k+('+b.a.real.to_s+')l+('+b.a.imag.to_s+')li+('+b.b.real.to_s+')lj+('+b.b.imag.to_s+')lk'
end
</syntaxhighlight>
</source>
 
Pour accéder au premier de ces nombres, que est la partie réelle du ''a'' de ''a'', on note ''a.a.real''. Autrement dit, on parcourt un arbre binaire, de profondeur 3.
Ligne 257 :
Comme pour les quaternions:
 
<sourcesyntaxhighlight lang="ruby">
def abs
Math.hypot(@a.abs,@b.abs)
end
</syntaxhighlight>
</source>
 
====Conjugué====
 
<sourcesyntaxhighlight lang="ruby">
def conj
Octonion.new(@a.conj,Quaternion.new(0,0)-@b)
end
</syntaxhighlight>
</source>
 
===Opérations===
Ligne 277 :
Comme pour les quaternions, on additionne les octonions composante par composante (''a'' avec ''o.a'', ''b'' avec ''o.b''):
 
<sourcesyntaxhighlight lang="ruby">
def +(o)
Octonion.new(@a+o.a,@b+o.b)
end
</syntaxhighlight>
</source>
 
====Soustraction====
 
<sourcesyntaxhighlight lang="ruby">
def -(o)
Octonion.new(@a-o.a,@b-o.b)
end
</syntaxhighlight>
</source>
 
====Multiplication====
 
<sourcesyntaxhighlight lang="ruby">
def *(o)
Octonion.new(@a*o.a-o.b*@b.conj,@a.conj*o.b+o.a*@b)
end
</syntaxhighlight>
</source>
 
Non seulement la multiplication des octonions n'est pas commutative, elle n'est plus associative non plus:
 
<sourcesyntaxhighlight lang="ruby">
m=Octonion.new(p,q)
n=Octonion.new(q,p)
Ligne 307 :
puts((m*n)*o)
puts(m*(n*o))
</syntaxhighlight>
</source>
 
====Division====
 
<sourcesyntaxhighlight lang="ruby">
def /(o)
d=1/o.abs**2
Octonion.new((@a*o.a.conj+o.b*@b.conj)*Quaternion.new(d,0),(Quaternion.new(0,0)-@a.conj*o.b+o.a.conj*@b)*Quaternion.new(d,0))
end
</syntaxhighlight>
</source>
 
Là encore, le quotient d'un octonion par son conjugué est de module 1:
 
<sourcesyntaxhighlight lang="ruby">
puts(m/m.conj)
puts((m/m.conj).abs)
</syntaxhighlight>
</source>
 
===Résumé===
Ligne 329 :
L'objet ''Octonion'' de Ruby est lui aussi, assez léger:
 
<sourcesyntaxhighlight lang="ruby">
class Octonion
 
Ligne 375 :
 
end
</syntaxhighlight>
</source>
 
En l'enregistrant sous le nom ''octonions.rb'', il suffit d'écrire
 
<sourcesyntaxhighlight lang="ruby">
require 'octonions'
</syntaxhighlight>
</source>
 
pour être en mesure d'effectuer des calculs sur les octonions en Ruby.