import LinearAlgebra
LinearAlgebra.inv([4 5 ; 3 4])
2×2 Matrix{Float64}:
4.0 -5.0
-3.0 4.0
Cours ENPC - Pratique du calcul scientifique
Organisation de chaque séance
Chaque séance comprendra
une partie théorique avec diapositives,
une partie pratique sur machine.
Modalités d’évaluation
3 devoirs (3 x 10%) sous forme de Jupyter notebooks:
Devoir 1 remis aujourd’hui,
Devoir 2 remis en 3ème séance (29 avril),
Devoir 3 remis en 5ème séance (13 mai).
Examen final sur machine, sans IA (70%)
Programme détaillé
Date | Sujet |
---|---|
Mardi 8 avril | Introduction à Julia (devoir 1 \(\rightarrow\) lundi 14 avril) |
Mardi 15 avril | Interpolation et intégration |
Mardi 29 avril | Systèmes linéaires (devoir 2 \(\rightarrow\) lundi 12 mai) |
Mardi 6 mai | Problèmes aux valeurs propres |
Mardi 13 mai | Systèmes non-linéaires (devoir 3 \(\rightarrow\) lundi 26 mai) |
Mardi 20 mai | Équations différentielles ordinaires |
Mardi 27 mai | Examen final |
Notes importantes
Le contenu du premier notebook est essentiel pour la suite du cours.
Le cours avance rapidement et demande un travail régulier.
La présence en séance est obligatoire (-2/20 par absence non justifiée).
$$
% % %
%
$$
\[ \definecolor{gris_C}{RGB}{96,96,96} \definecolor{blanc_C}{RGB}{255,255,255} \definecolor{pistache_C}{RGB}{176,204,78} \definecolor{pistache2_C}{RGB}{150,171,91} \definecolor{jaune_C}{RGB}{253,235,125} \definecolor{jaune2_C}{RGB}{247,208,92} \definecolor{orange_C}{RGB}{244,157,84} \definecolor{orange2_C}{RGB}{239,119,87} \definecolor{bleu_C}{RGB}{126,151,206} \definecolor{bleu2_C}{RGB}{90,113,180} \definecolor{vert_C}{RGB}{96,180,103} \definecolor{vert2_C}{RGB}{68,141,96} \definecolor{pistache_light_C}{RGB}{235,241,212} \definecolor{jaune_light_C}{RGB}{254,250,224} \definecolor{orange_light_C}{RGB}{251,230,214} \definecolor{bleu_light_C}{RGB}{222,229,241} \definecolor{vert_light_C}{RGB}{216,236,218} \]
Langage de programmation créé en 2009 au MIT
Par Jeff Bezanson, Stefan Karpinski, Viral B. Shah, Alan Edelman
Version 1.11.4 depuis le 10/03/2025
Documentation générale de Julia
: https://docs.julialang.org/en/v1/
Julia
→ deux optionsjuliaup
installer juliaup
depuis https://github.com/JuliaLang/juliaup
ajouter des versions, par exemple la dernière
PS [path] juliaup add release
Option préconisée : VSCode
https://code.visualstudio.com/
Installer Jupyter
https://jupyter.org/install
Installer la bibliothèque IJulia
→ https://github.com/JuliaLang/IJulia.jl
Voir vidéos de D. Anthoff sur l’utilisation de VSCode
pour Julia
, p. ex. lien 1 ou lien 2
REPL = read–eval–print loop → console de Julia
Le REPL est accessible
de manière autonome en tant qu’exécutable ou en tapant julia
dans une console (si PATH
à jour)
intégré dans VSCode
en tapant Maj+Ctrl+P
puis en cherchant Julia: Start REPL
Dans VSCode
, on peut taper ses lignes de code dans un fichier *.jl
et les lancer une par une dans la console intégrée par Maj+Entrée
.
Depuis le REPL, taper
]
donne accès au gestionnaire de bibliothèques
;
donne accès au shell mode
?
donne accès à l’aide en ligne
⟵
retourne au mode normal
Tab
pour la complétion automatique
les flèches haut et bas pour naviguer dans l’historique (éventuellement filtré par le début de ligne tapé)
Pour appeler une bibliothèque déjà installée
import
using
(plus besoin de préfixer le nom de la bibliothèque ensuite)Pour installer une nouvelle bibliothèque : 2 options
]
puisImportant
L’installation d’une bibliothèque dans un environnement ne se fait qu’une seule fois.
Toute tentative de réinstallation est non seulement inutile mais surtout chronophage.
Julia
?Python | Matlab | Julia | C | |
---|---|---|---|---|
Libre ? | ✔️ | ❌ | ✔️ | ✔️ |
Rapide ? | ❔ | ❔ | ✔️ | ✔️ |
Facile à apprendre ? | ✔️ | ✔️ | ✔️ | ❌ |
Adapté au calcul scientifique ? | ❔ | ✔️ | ✔️ | ❌ |
Richesse de l’écosystème ? | ✔️ | ❔ | ❔ | ✔️ |
Julia
est facile à apprendre, à lire et à maintenir (comparable à Python
)
Julia
est rapide (comparable à C/C++
, Fortran
)
Julia
est efficace (dispatch multiple, macros,…)
Julia
est bien adapté au calcul scientifique
Julia
est facile à apprendre, à lire et à maintenir1 is a Int64
π is a Irrational{:π}
1//2 is a Rational{Int64}
4.641592653589793 is a Float64
lambda
de python) ou de fonctions anonymesBibliothèque de base contient les tableaux et leurs opérations courantes (+
, -
, *
, \
) puis LinearAlgebra
pour det
, eigen
…
Compréhension de tableau (for
dans le tableau)
Julia
est rapideCompilation à la volée (Just-in-time compilation)
Parangonnage (cf. https://julialang.org/benchmarks)
⚠ Ces résultats ne tiennent pas compte du temps de compilation.
The vertical axis shows each benchmark time normalized against the C implementation. The benchmark data shown above were computed with Julia v1.0.0, SciLua v1.0.0-b12, Rust 1.27.0, Go 1.9, Java 1.8.0_17, Javascript V8 6.2.414.54, Matlab R2018a, Anaconda Python 3.6.3, R 3.5.0, and Octave 4.2.2. C and Fortran are compiled with gcc 7.3.1, taking the best timing from all optimization levels (-O0 through -O3). C, Fortran, Go, Julia, Lua, Python, and Octave use OpenBLAS v0.2.20 for matrix operations; Mathematica uses Intel MKL. The Python implementations of matrix_statistics and matrix_multiply use NumPy v1.14.0 and OpenBLAS v0.2.20 functions; the rest are pure Python implementations. Raw benchmark numbers in CSV format are available under https://github.com/JuliaLang/Microbenchmarks.
These micro-benchmark results were obtained on a single core (serial execution) on an Intel Core i7-3960X 3.30GHz CPU with 64GB of 1600MHz DDR3 RAM, running openSUSE LEAP 15.0 Linux.
Julia
est efficaceUn atout majeur est le multiple dispatch
Exemple tiré de la conférence The Unreasonable Effectiveness of Multiple Dispatch de Stefan Karpinski
abstract type Animal end
struct Chien <: Animal; nom::String end
struct Chat <: Animal; nom::String end
function rencontre(a::Animal,b::Animal)
verb = agit(a,b)
println("$(a.nom) rencontre $(b.nom) et $verb")
end
agit(a::Chien,b::Chien) = "le renifle" ; agit(a::Chien,b::Chat) = "le chasse"
agit(a::Chat,b::Chien) = "s'enfuit" ; agit(a::Chat,b::Chat) = "miaule"
medor = Chien("Médor") ; 🐶 = Chien("🐶")
felix = Chat("Félix") ; 🐱 = Chat("🐱")
rencontre(medor,🐶)
rencontre(🐶,felix)
rencontre(felix,🐶)
rencontre(🐱,felix)
Médor rencontre 🐶 et le renifle
🐶 rencontre Félix et le chasse
Félix rencontre 🐶 et s'enfuit
🐱 rencontre Félix et miaule
Exemple adapté du blog de Mosè Giordano
abstract type HandShape end
struct Rock <: HandShape end
struct Paper <: HandShape end
struct Scissors <: HandShape end
play(::Type{Paper}, ::Type{Rock}) = println("Paper VS Rock ⇒ Paper wins")
play(::Type{Scissors}, ::Type{Paper}) = println("Scissors VS Paper ⇒ Scissors wins")
play(::Type{Rock}, ::Type{Scissors}) = println("Rock VS Scissors ⇒ Rock wins")
play(::Type{T}, ::Type{T}) where {T<: HandShape} = println("Tie between $(T), try again")
play(a::Type{<:HandShape}, b::Type{<:HandShape}) = play(b, a) # Commutativity
play(Paper, Rock)
play(Scissors, Scissors)
play(Paper, Scissors)
Paper VS Rock ⇒ Paper wins
Tie between Scissors, try again
Scissors VS Paper ⇒ Scissors wins
Il est aisé d’ajouter de nouveaux types a posteriori
Exemple inspiré de la conférence The Unreasonable Effectiveness of Multiple Dispatch par Stefan Karpinski
\[\sum_{i=1}^p\mathbf{\boldsymbol{v}}_i^\mathrm{T} \mathsf{A} \mathbf{\boldsymbol{v}}_i, \quad \mathsf{A}∈{\mathbb{{R}}}^{n×n},\;\mathbf{\boldsymbol{v}}_i∈{\mathbb{{R}}}^n\]
using LinearAlgebra
inner(v, A, w) = v'A*w
# function inner_sum(A, vs)
# t = zero(eltype(A))
# for v ∈ vs t += inner(v, A, v) end
# return t
# end
inner_sum(A, vs) = sum(inner(v, A, v) for v ∈ vs)
n = 10_000 ; p = 100
A = rand(n, n)
vs = [rand(n) for _ ∈ 1:p]
@time inner_sum(A, vs)
7.854520 seconds (57.46 k allocations: 10.482 MiB, 0.41% compilation time)
1.251779779546054e9
Cas particulier de vecteurs \(\mathbf{\boldsymbol{v}}_i=(0,\cdots,0,1,0,\cdots,0)^\mathrm{T}\)
\[\mathbf{\boldsymbol{v}}^\mathrm{T} \mathsf{A} \mathbf{\boldsymbol{w}} = A_{\mathrm{ind}(\mathbf{\boldsymbol{v}}), \mathrm{ind}(\mathbf{\boldsymbol{w}})}\]
size
et getindex
doivent être définis pour les calculs matriciels usuels)inner
Julia
est bien adapté au calcul scientifique$$
% % %
%
$$
… éq. d’Euler-Lagrange \(\frac{{\mathrm{d}}}{{\mathrm{d}}t}\left(\frac{∂ℒ}{∂\dot{q_i}}\right) -\frac{∂ℒ}{∂q_i}=0\)
…
using SymPy, LinearAlgebra, TensND
Spherical = coorsys_spherical()
θ, ϕ, r = getcoords(Spherical)
𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ = unitvec(Spherical)
@set_coorsys Spherical
𝕀, 𝕁, 𝕂 = ISO() ; 𝟏 = tensId2()
k, μ = symbols("k μ", positive = true)
λ = k -2μ/3
u = SymFunction("u", real = true)
𝛆 = SYMGRAD(u(r) * 𝐞ʳ)
𝛆 |> intrinsic
(u(r)/r)𝐞ᶿ⊗𝐞ᶿ + (u(r)/r)𝐞ᵠ⊗𝐞ᵠ + (Derivative(u(r), r))𝐞ʳ⊗𝐞ʳ
\(u{\left(r \right)} = \frac{C_{1}}{r^{2}} + C_{2} r\)
La documentation officielle → https://docs.julialang.org/en/v1/
Learn X in Y minutes → https://learnxinyminutes.com/docs/julia
Intro to Julia tutorial (version 1.0) by Jane Herriman → https://youtu.be/8h8rQyEpiZA
The Unreasonable Effectiveness of Multiple Dispatch → https://www.youtube.com/watch?v=kc9HwsxE1OY