Mathématiques avec Python et Ruby/Nombres complexes en Ruby

On a inventé les nombres complexes juste parce qu'on voulait que certaines équations, comme , aient une solution (dans le cas présent, notée i). C'est typique des mathématiques, ça:

  1. On se fait un petit caprice;
  2. Pour le satisfaire, on invente une grosse théorie;
  3. D'autres gens utilisent cette théorie pour résoudre des problèmes, souvent issus des mathématiques appliquées, et qui n'ont plus rien de capricieux !

Instanciation d'un complexe

modifier

Pour créer dans Ruby le complexe x+iy, on utilise Complex(x,y):

a=Complex(4,3)
puts(a)

Les nombres x et y sont juste des nombres: Ils peuvent très bien être des entiers ou des fractions. On appelle entier de Gauss un nombre complexe dont les parties réelle et imaginaire sont des entiers relatifs.

Opérations

modifier

La somme, la différence, le produit et le quotient de deux nombres complexes sont des nombres complexes:

a=Complex(2,3)
b=Complex(4,3)
puts(a+b)
puts(a-b)
puts(a*b)
puts(a/b)

Ces exemples illustrent le fait que la somme, la différence et le produit d'entiers de Gauss sont des entiers de Gauss. Par contre leur quotient exact ne l'est pas forcément. L'exemple de la soustraction montre que même lorsque le résultat d'une opération est réel, Ruby le considère quand même comme un complexe (de partie imaginaire nulle).

Ainsi,

i=Complex(0,1)
puts(i**2)
puts(i**i)

On voit que pour Ruby,   et non -1. On voit également que   est réel. En effet, la puissance se note toujours ** en Ruby, et l'exposant n'est pas nécessairement réel.

Il est donc possible de calculer "la" racine carrée d'un complexe z avec z**0.5. Mais si 7+24i est le carré de deux complexes, "sa" racine carrée calculée par Ruby est 4+3i et non -4-3i. Comment Ruby choisit-il parmi ces deux nombres?

De même, -1 a deux racines carrées dans  : i et -i. Ruby n'en reconnaît qu'une, et on se doutait qu'il choisirait i plutôt que son opposé. Mais

puts((-1)**0.5)
puts(Complex(-1,0)**0.5)

Si -1 est réel, il n'a pas de racine carrée du tout (sous-entendu dans  ), alors que si -1 est complexe, "sa" racine carrée est proche de i mais pas exactement égale à i (sa partie réelle étant de l'ordre de  ).

Propriétés

modifier

Les parties réelle et imaginaire d'un complexe a sont des propriétés de celui-ci:

a=Complex(4,3)
puts(a.real)
puts(a.imag)
puts(a.conj)

Il en est donc de même de son conjugué, qui est un complexe (contrairement à sa partie réelle, qui peut être un réel, mais aussi un entier ou une fraction, selon le cas).

D'autres propriétés d'un complexe sont son module et son argument:

a=Complex(4,3)
puts(a.abs)
puts(a.arg)
puts(a.polar)


z.polar permet d'avoir d'un coup le module et l'argument d'un complexe. Il permet de résoudre plus rapidement le problème vu dans le chapitre sur les nombres réels: Chercher le plus petit angle (en radians) et l'hypoténuse d'un triangle rectangle dont les côtés mesurent 12 cm et 5 cm:

a=12
b=5
z=Complex(a,b)
puts(z.polar)

Fonctions

modifier

CMath contient des versions complexes des fonctions trigonométriques, exponentielles et logarithmes:

Exponentielles

modifier

On peut retrouver l'écriture exponentielle des complexes de module 1 à condition de considérer l'exposant comme imaginaire (ci-dessous, pour vérifier numériquement que  ):

require 'cmath'
t=Complex(0,Math::PI/3)
w=CMath.exp(t)
puts(w.real==0.5)
puts(w.real-0.5)
puts(w.imag==Math.sqrt(3)/2)

Comme d'habitude, 0,5 n'étant pas stocké très précisément en machine, l'égalité des parties réelles n'est qu'approximative.

Pour calculer les cosinus hyperbolique, sinus hyperbolique et tangente hyperbolique de 4+3i, on fait ainsi:

require 'cmath'
a=Complex(4,3)
puts(CMath.cosh(a))
puts(CMath.sinh(a))
puts(CMath.tanh(a))

Logarithmes

modifier

Pour calculer les images de 4+3i par les fonctions logarithme népérien, logarithme décimal, arguments des fonctions trigonométriques hyperboliques, on peut faire ainsi:

require 'cmath'
a=Complex(4,3)
puts(CMath.log(a))
puts(CMath.log10(a))
puts(CMath.acosh(a))
puts(CMath.asinh(a))
puts(CMath.atanh(a))

Fonctions trigonométriques

modifier

directes

modifier

Les cosinus, sinus et tangente d'un nombre complexe z se calculent avec le module cmath:

require 'cmath'
z=Complex(4,3)
puts(CMath.cos(z))
puts(CMath.sin(z))
puts(CMath.tan(z))

indirectes

modifier

Les fonctions trigonométriques inverses se calculent de manière analogue, en mettant juste un C devant Math:

require 'cmath'
z=Complex(4,3)
puts(CMath.acos(z))
puts(CMath.asin(z))
puts(CMath.atan(z))


La fonction arc tangente se calcule aussi avec deux nombres complexes:

require 'cmath'
a=Complex(4,3)
b=Complex(2,1)
puts(CMath.atan2(a,b))

Ça doit sûrement servir à quelque chose, mais à quoi?