Julia

publicité
Introduction rapide pour le lycée
François THIRIOUX
[email protected]
Lycée René Perrin – Ugine – Savoie
version du 24 octobre 2015
[email protected]
Table des matières
1 Julia express
2
2 Installer et lancer Julia
3
3 Structures usuelles
4
4 Matrices
5
5 Nombres complexes
10
6 Arithmétique
12
1
[email protected]
1. Julia express
Introduction
La question n’est pas de savoir qui est Julia : ce serait trop facile.
Julia est un jeune langage de programmation créé au MIT en 2009, dont la syntaxe ressemble à
celle de notre cher Python. Il possède une banque déjà fournie de modules additionnels, même
si elle est moins impressionnante que celle de Python. Il existe deux avantages essentiels :
• beaucoup de commandes mathématiques sont présentes nativement ;
• sa rapidité d’exécution est proche de celle du C++.
Il faut noter que la compilation est transparente pour l’utilisateur puisqu’elle est réalisée à la
volée (« JIT », « Just In Time », du projet LLVM). Un programme en Julia s’exécute avec
autant de facilité qu’un script en Python.
Pour avoir une petite idée de la syntaxe et de la rapidité, voici en action un programme très
subtil (...) affichant la liste des diviseurs d’un entier donné :
Julia 0.3
Python 3.4
function diviseurs(n)
for k in 1 : n
if n%k == 0
println(k)
end
end
end
@time diviseurs(944986841)
from time import time
def diviseurs(n) :
for k in range(1,n+1) :
if n%k == 0 :
print(k)
a = time()
diviseurs(944986841)
b = time()
print("durée : ",b-a," secondes")
Résultat
Résultat
elapsed time:
8.857808039 seconds
durée : 77.8134343624115 secondes
Julia, un langage éco-responsable !
Notons par ailleurs que Julia supporte les caractères Unicode, ce qui, en français, signifie qu’on
peut inclure dans un programme des lettres grecques ou des symboles spéciaux faisant office de
variables, de fonctions, etc.
Références et liens
Le but de cette introduction n’est ni de réinventer la roue ni de se contenter de traduire les
ressources existantes en français. Voici donc quelques liens essentiels :
• site officiel : http://julialang.org ;
• documentation officielle : http://docs.julialang.org ;
• https://zestedesavoir.com/articles/141/a-la-decouverte-de-julia ;
• http://learnxinyminutes.com/docs/julia ;
• https://en.wikibooks.org/wiki/Introducing_Julia .
Pour tester Julia sans rien installer, il existe le notebook https://www.juliabox.org .
2
[email protected]
2. Installer et lancer Julia
Windows
Les installeurs sont disponibles à l’adresse julialang.org/downloads . Testé rapidement, le
reste de cette introduction est approfondi sous Ubuntu 15.10 .
GNU-Linux/Ubuntu
Il faut installer les paquets julia et git, présents dans les dépôts Ubuntu. Le second sert ici
à récupérer les modules additionnels (« packages »).
Modules additionnels
Ouvrir un terminal et exécuter julia. Le mode interactif (comme en Python) est activé. Pour
ajouter un module, la commande est Pkg.add("NomDuModule") . Ce module est stocké dans le
répertoire ∼/.julia . Lorsque des paquets supplémentaires sont nécessaires, Julia fait appel à
apt et demande le mot de passe administrateur.
Pour quitter le mode interactif, taper Ctrl-D.
Interfaces
Un éditeur de texte suffit à créer un fichier bidule.jl . On peut ensuite l’exécuter simplement depuis un terminal via julia bidule.jl . La coloration syntaxique est prise en charge
par un éditeur comme Gedit, mais pas l’indentation automatique. On pourra avantageusement
créer un outil externe (greffon à activer dans les préférences de Gedit) avec la commande julia .
On peut également utiliser Qt Creator, par exemple. Il faut configurer un Outil externe (comme
pour Python) via les menus Outils/Options/Environnement/Outils externes :
• exécutable : julia ;
• arguments : %{CurrentDocument:FilePath} ;
• répertoire de travail : %{CurrentDocument:Path} .
L’exécution du fichier par Julia est accessible dans le menu Outils/Externe. On pourra créer un
raccourci clavier... Une coloration syntaxique est disponible à télécharger depuis Outils/Options/
Éditeur de texte/Coloration syntaxique générique.
Pour finir, on peut aussi utiliser un notebook : IJulia. Pour ce faire, exécuter les commandes
suivantes dans un terminal :
julia
julia> Pkg.add("IJulia")
julia> using IJulia
julia> notebook()
La deuxième commande sert à charger le module IJulia, il est donc inutile de la lancer à chaque
fois... Le navigateur par défaut s’ouvre sous l’environnement Jupyter (comme IPython), très
simple à utiliser.
3
[email protected]
3. Structures usuelles
Boucles, conditionnement
Données
4
[email protected]
4. Matrices
Définition
C’est direct :
julia> A=[1 2 3 ; 4 5 6 ; 7 8 7]
3x3
1 2
4 5
7 8
Array{Int64,2}:
3
6
7
Ici 3x3 Array{Int64,2} signifie que A est un tableau d’entiers à deux dimensions, de taille 3×3.
On peut donner la taille de A par :
julia> size(A)
(3,3)
Extraire un élément, une ligne ou une colonne
Les indices débutent à 1, à la différence de Python (entre autres...) :
julia> A[2,1]
4
Les slices sont bien sûr utilisables plus finement que dans ce qui suit...
julia> A[2,:]
1x3 Array{Int64,2}:
4 5 6
julia> A[:,3]
3-element Array{Int64,1}:
3
6
7
5
[email protected]
Opérations
Les sommes, différences ou produits s’effectuent très naturellement. Une puissance aussi :
julia> Aˆ2015
3x3 Array{Int64,2}:
1583313351890381144 -7279767086941224252 -5146998712661124592
-6486402176729027370 -3167002905664645007 -7993517345919539836
7203907103967830684 -1818064437605062198 6654452081578112168
Les opérations élément par élément sont possibles (même chose pour +, − ou /) :
julia> 2*A
3x3 Array{Int64,2}:
2 4 6
8 10 12
14 16 14
Pour la puissance élément par élément :
julia> A.ˆ2
3x3 Array{Int64,2}:
1 4 9
16 25 36
49 64 49
Le point avant la commande indique de traiter élément par élément. Par exemple :
julia> A.>3
3x3 BitArray{2}:
false false false
true true true
true true true
L’exponentielle d’une matrice :
julia> exp(A)
3x3 Array{Float64,2}:
2.71828 7.38906 20.0855
54.5982 148.413 403.429
1096.63 2980.96 1096.63
6
[email protected]
La transposée d’une matrice :
julia> A’
3x3
1 4
2 5
3 6
Array{Int64,2}:
7
8
7
Inversion et équations
On peut inverser A par la commande inv(A) ou classiquement par :
julia> Aˆ(-1)
3x3 Array{Float64,2}:
-2.16667 1.66667 -0.5
2.33333 -2.33333 1.0
-0.5 1.0 -0.5
On peut trouver X telle que A*X=B :
julia> B=[3 ; 2 ; 1]
3-element Array{Int64,1}:
3
2
1
julia> X=A\B
3-element Array{Float64,1}:
-3.66667
3.33333
-6.66134e-16
Vu que la syntaxe est étrange, on peut songer à vérifier :
julia> inv(A)*B
3-element Array{Float64,1}:
-3.66667
3.33333
-6.10623e-16
7
[email protected]
Prions pour qu’aucun élève ne dise qu’on a obtenu deux résultats différents... Si c’est le cas alors
on pourra lui expliquer que le backslash est plus efficace car il provoque la résolution directe
de l’équation A*X=B, au lieu de trouver Aˆ(-1) puis d’en faire le produit avec B . Le gain est
double : en temps d’exécution et en précision.
Matrices utiles
Une matrice identité :
julia> eye(3)
3x3
1.0
0.0
0.0
Array{Float64,2}:
0.0 0.0
1.0 0.0
0.0 1.0
Une matrice diagonale :
julia> diagm([3,5,7])
3x3
3 0
0 5
0 0
Array{Int64,2}:
0
0
7
Une matrice aléatoire :
julia> rand(3,3)
3x3 Array{Float64,2}:
0.869429 0.0627175 0.718558
0.146539 0.0164233 0.0416191
0.510512 0.89997 0.788979
Une matrice nulle :
julia> zeros(3,3)
3x3
0.0
0.0
0.0
Array{Float64,2}:
0.0 0.0
0.0 0.0
0.0 0.0
8
[email protected]
Diagonalisation
Julia retourne par eig(A) un 2-tuple constitué d’un tableau des valeurs propres suivi d’une
matrice de vecteurs propres. Ainsi :
julia> P=eig(A)[2]
3x3 Array{Float64,2}:
-0.248828 -0.571836 0.595561
-0.568631 -0.327291 -0.758896
-0.784056 0.752252 0.263408
julia> D=Pˆ(-1)*A*P
3x3 Array{Float64,2}:
15.0235 1.77636e-15 -6.21725e-15
-4.10783e-15 -1.80181 1.66533e-16
4.05925e-15 -1.29063e-15 -0.221653
On peut alors jouer :
julia> Aˆ7
3x3 Array{Int64,2}:
21834720 26969076 28331784
49897542 61630737 64744788
68801236 84979514 89273248
julia> P*D.ˆ7*Pˆ(-1)
3x3 Array{Float64,2}:
2.18347e7 2.69691e7 2.83318e7
4.98975e7 6.16307e7 6.47448e7
6.88012e7 8.49795e7 8.92732e7
Notons que le résultat donné est identique sans tricher, c’est-à-dire avec Dˆ7 au lieu de D.ˆ7 .
9
[email protected]
5. Nombres complexes
Généralités
Le nombre i se note im . On peut écrire indifféremment 1+2*im ou 1+2im . Il semble clair que
la seconde option est peu habituelle et limitée lorsqu’on a affaire à une variable au lieu de 2 .
Les opérations s’écrivent naturellement. Les fonctions de base sont :
julia> z=1+sqrt(3)*im
1.0 + 1.7320508075688772im
julia> real(z), imag(z), conj(z)
(1.0,1.7320508075688772,1.0 - 1.7320508075688772im)
julia> abs(z)
1.9999999999999998
julia> abs2(z)
3.9999999999999996
julia> angle(z)
1.0471975511965976
julia> ans*180/pi
59.99999999999999
Le premier élève qui se plaindra des approximations sera puni. À propos de punition, Julia
n’est pas toujours bienveillant (quoique...) :
julia> sqrt(-1)
ERROR: DomainError
Ensemble de Mandelbrot
L’utilisation de la bibliothèque graphique Cairo a été introduite dans un chapitre précédent.
# module de dessin
using Cairo
10
[email protected]
# calcul du nombre d’itérations
function iter(z,maxiter)
c = z
for n = 1:maxiter
if abs(z) > 2
return n-1
end
z = z*z + c
end
return maxiter
end
# fonction principale
function mandelbrot()
maxiter = 80
xmin = -2
xmax = 2
ymin = -2
ymax = 2
pas = 0.0005
pixels = 768
xdelta = pixels/(xmax-xmin)
ydelta = pixels/(ymax-ymin)
c = CairoRGBSurface(pixels,pixels)
cr = CairoContext(c)
save(cr)
set_source_rgb(cr,0.9,0.9,0.9)
rectangle(cr,0,0,pixels,pixels)
fill(cr)
restore(cr)
save(cr)
for x = xmin:pas:xmax
for y = ymin:pas:ymax
rouge = max(1-2*iter(x+y*im,maxiter)/maxiter,0)
vert = rouge
bleu = rouge
xcoord = pixels/2+x*xdelta
ycoord = pixels/2-y*ydelta
set_source_rgb(cr, rouge, vert, bleu)
move_to(cr, xcoord, ycoord)
line_to(cr, xcoord+0.1, ycoord+0.1)
stroke(cr)
end
end
restore(cr)
write_to_png(c,"mandelbrot.png")
end
mandelbrot()
11
[email protected]
6. Arithmétique
Fonctions courantes
Elles sont présentes nativement dans Julia :
julia> 2015%7, mod(2015,7), gcd(2016,35), lcm(2016,35)
(6,6,7,10080)
Ce qui touche au théorème de Bézout est aussi disponible :
julia> gcdx(2015,7)
(1,-1,288)
julia> 2015*(-1)+7*288
1
julia> invmod(7,2015)
288
Concernant les nombres premiers et la factorisation :
julia> isprime(68), isprime(97)
(false,true)
julia> factor(123456789)
Dict{Int64,Int64} with 3 entries:
3 => 2
3803 => 1
3607 => 1
On notera que Julia donne ici le résultat sous forme de dictionnaire associant un nombre premier et sa puissance dans la décomposition.
julia> primes(100)
25-element ArrayInt64,1:
2
3
5
12
[email protected]
.
.
.
97
Un exemple de chiffrement RSA
Vu que c’est un peu le but à atteindre en spécialité Mathématiques, allons-y :
julia> e=3; p=41; q=53; k=(p-1)*(q-1); n=p*q; d=invmod(e,k)
1387
julia> mot=2015
2015
julia> motChiffr=powermod(mot,e,n)
1856
julia> motDechiffr=powermod(motChiffr,d,n)
2015
13
[email protected]
Téléchargement