Julia est un langage de programmation open-source, multi-plateformes, performant et de haut niveau, dédié au calcul technique.
Julia est propulsé par un compilateur JIT La compilation “Just-In-Time” (au dernier moment) se produit à l’exécution du programme, plutôt que d’être réalisée au préalable. Ceci permet d’offrir la performance d’un code compilé sans sacrifier la flexibilité des langages interprétés. Après une phase d’inférence de types, le compilateur génère une représentation intermédiaire LLVM qui est à son tour compilée sous forme de code natif. basé sur LLVM Low-Level Virtual Machine (LLVM) est une infrastructure de compilation permettant de produire, optimiser et compiler du code sous forme de représentation intermédiaire ou de code binaire natif., ce qui lui permet d’atteindre les mêmes performances que des langages comme C et FORTRAN tout en évitant d’avoir à écrire du code bas-niveau. Comme le code est compilé à la volée, il est possible de l’évaluer dans une console ou REPL Read-Eval-Print-Loop : Boucle de Lecture-Évaluation-Affichage, ce qui fait d’ailleurs partie des modes de développement recommandés.
Julia est un langage à typage dynamique, propose des fonctionnalités de multiple dispatchÉtant donné que le type des arguments passés aux fonctions est déterminé lors de l’exécution, le compilateur peut choisir une implémentation optimale adaptée aux arguments fournis ainsi qu’à l’architecture matérielle ciblée., et a été conçu pour le parallélisme et le calcul distribué.
Julia intègre un gestionnaire de paquets.
Julia intègre aussi une bibliothèque mathématique fournie, comprenant des fonctions spéciales (p.ex. Gamma). Le langage supporte aussi les nombres complexes par défaut.
Julia permet de faire de la méta-programmation et de la génération de code grâce à des macros inspirées des langages LISP.
Julia est né en 2012.
Affectation | answer = 42 x, y, z = 1, [1:10; ], "A string" x, y = y, x # échanger x et y |
Déclaration constante | const DATE_OF_BIRTH = 2012 |
Commentaire en fin de ligne | i = 1 # Ceci est un commentaire |
Commentaire délimité | #= Ceci est un autre commentaire =# |
Chainage | x = y = z = 1 # de droite à gauche 0 < x < 3 # true 5 < x != y < 5 # false |
Définition de fonction | function add_one(i) return i + 1 end |
Insertion de symboles LaTeX | \delta + [Tab] |
Opérations fondamentales | + , - ,* ,/ |
Exponentiation | 2^3 == 8 |
Division | 3/12 == 0.25 |
Division inverse | 7\3 == 3/7 |
Reste (modulo) | x % y ou rem(x,y) |
Négation | !true == false |
Égalité | a == b |
Non-égalité | a != b ou a ≠ b |
Inégalités strictes | < et > |
Infériorité large | <= ou ≤ |
Supériorité large | >= ou ≥ |
Opérations élément-par-élément | [1, 2, 3] .+ [1, 2, 3] == [2, 4, 6] [1, 2, 3] .* [1, 2, 3] == [1, 4, 9] |
Not a Number | isnan(NaN) plutôt que NaN == NaN |
Opérateur ternaire | a == b ? "Equal" : "Not equal" |
ET et OU logiques (court-circuités) | a && b et a || b |
Équivalence d’objets | a === b |
Rappeler le dernier résultat | ans |
Interrompre l’exécution | [Ctrl] + [C] |
Effacer l’écran | [Ctrl] + [L] |
Lancer un programme Julia (script) | include("filename.jl") |
Aide sur la fonction func |
?func |
Toutes les pages d’aide où func est mentionnée |
apropos("func") |
Mode de commandes shell | ; (en début de ligne) |
Mode du gestionnaire de paquets | ] (en début de ligne) |
Mode d’aide | ? (en début de ligne) |
Sortir d’un mode spécifique / Revenir au REPL | [Backspace] (en début de ligne) |
Sortir du REPL | exit() ou [Ctrl] + [D] |
Pour que Julia démarre plus rapidement, de nombreuses fonctionnalités
essentielles sont disponibles dans les bibliothèques standard, distribuées et
installées avec Julia. Pour appeler les fonctions de ces bibliothèques, utilisez
la commande : using PackageName
. Nous listons ici quelques bibliothèques
standard et fonctions fréquemment utilisées.
Random |
rand , randn , randsubseq |
Statistics |
mean , std , cor , median , quantile |
LinearAlgebra |
I , eigvals , eigvecs , det , cholesky |
SparseArrays |
sparse , SparseVector , SparseMatrixCSC |
Distributed |
@distributed , pmap , addprocs |
Dates |
DateTime , Date |
Les paquets doivent être enregistrés avant de
pouvoir être désignés par leur nom en utilisant le gestionnaire de paquets. La
plupart des commandes ci-dessous acceptent aussi une URL de dépôt git pour
identifier un paquet non-enregistré. Le gestionnaire de paquets de Julia 1.0
peut être utilisé de deux manières : en tapant using Pkg
puis en utilisant les
fonctions du module Pkg
, ou bien en entrant dans le mode REPL dédié à la
gestion des paquets à l’aide de la touche ]
(Pour revenir au REPL Julia
standard, tapez [BackSpace]
dans une ligne vide). NB: les nouvelles
fonctionnalités de Pkg
arrivent souvent dans le mode REPL interactif, avant
d’intégrer l’API du module Pkg
.
Pkg
dans un code JuliaLister les paquets installés (format pour humains) | Pkg.status() |
Mettre à jour les paquets | Pkg.update() |
Installer PackageName |
Pkg.add("PackageName") |
Reconstruire PackageName |
Pkg.build("PackageName") |
Utiliser PackageName (après installation) |
using PackageName |
Supprimer PackageName |
Pkg.rm("PackageName") |
pkg
Installer PackageName |
add PackageName |
Supprimer PackageName |
rm PackageName |
Mettre à jour PackageName |
update PackageName |
Utiliser une version de développement | dev PackageName ou dev GitRepoUrl |
Après dev , revenir à une version publiée |
free PackageName |
Caractère | chr = 'C' |
Chaîne de caractères | str = "A string" |
Codage d’un caractère | Int('J') == 74 |
Caractère depuis son code | Char(74) == 'J' |
Tout caractère UTF | chr = '\uXXXX' # 4-digit HEX chr = '\UXXXXXXXX' # 8-digit HEX |
Itération sur une chaîne de caractère | for c in str println(c) end |
Concaténation | str = "Learn" * " " * "Julia" |
Interpolation de chaînes | a = b = 2 println("a * b = $(a*b)") |
Premier caractère ou expression régulière correspondant | findfirst(isequal('i'), "Julia") == 4 |
Remplacer une une sous-chaîne ou expression régulière | replace("Julia", "a" => "us") == "Julius" |
Dernier indice (d’une collection) | lastindex("Hello") == 5 |
Nombre de caractères | length("Hello") == 5 |
Expression régulière | pattern = r"l[aeiou]" |
Sous-expression | str = "+1 234 567 890" pat = r"\+([0-9]) ([0-9]+)" m = match(pat, str) m.captures == ["1", "234"] |
Toutes les occurrences | [m.match for m = eachmatch(pat, str)] |
Toutes les occurrences (en tant qu’itérateur) | eachmatch(pat, str) |
Attention aux encodages Unicode multi-byte en UTF-8:
10 == lastindex("Ångström") != length("Ångström") == 8
Les chaînes sont immuables.
Type Entier | IntN et UIntN , avec N ∈ {8, 16, 32, 64, 128} , BigInt |
Type Flottant | FloatN avec N ∈ {16, 32, 64} BigFloat |
Valeurs minimale et maximale de types | typemin(Int8) typemax(Int64) |
Type Complex | Complex{T} |
Unité imaginaire | im |
Précision de la machine | eps() # identique à eps(Float64) |
Arrondi | round() # flottant round(Int, x) # entier |
Conversion de type | convert(TypeName, val) # essai/erreur typename(val) # appelle une conversion |
Constantes globales | pi # 3.1415... π # 3.1415... im # real(im * im) == -1 |
Autres constantes | using Base.MathConstants |
Julia ne vérifie pas automatiquement les dépassements numériques. Utiliser le paquet SaferIntegers pour employer des Entiers en contrôlant les dépassements.
Plusieurs fonctions de nombre aléatoire requièrent using Random
.
Définir la graine | seed!(seed) |
Nombres aléatoires | rand() # uniform [0,1) randn() # normal (-Inf, Inf) |
Aléatoire depuis une autre distribution | using Distributions my_dist = Bernoulli(0.2) # For example rand(my_dist) |
Sous-échantillon aléatoire dans A avec une probabilité d’inclusion p | randsubseq(A, p) |
Permutation aléatoire d’éléments de A | shuffle(A) |
Déclaration | arr = Float64[] |
Pré-allocation | sizehint!(arr, 10^4) |
Accès et mutation | arr = Any[1,2] arr[1] = "Some text" |
Comparaison | a = [1:10;] b = a # b pointe vers a a[1] = -99 a == b # true |
Copie des éléments (distincte en mémoire) | b = copy(a) # un seul niveau b = deepcopy(a) # récursivement |
Sous-tableau de m à n |
arr[m:n] |
Tableau de n éléments, rempli de 0.0 |
zeros(n) |
Tableau de n éléments, rempli de 1.0 |
ones(n) |
Tableau de n éléments, non initialisé |
Vector{Type}(undef,n) |
n nombres équi-répartis entre start et stop |
range(start,stop=stop,length=n) |
n nombres (Int8 ) aléatoires |
rand(Int8, n) |
Remplir arr avec des val |
fill!(arr, val) |
Suppression d’un élément en fin de tableau | pop!(arr) |
Suppression d’un élément en début de tableau | popfirst!(a) |
Ajout d’un élément en fin de tableau | push!(arr, val) |
Ajout d’un élément en début de tableau | pushfirst!(arr, val) |
Suppression de l’élément d’indice idx |
deleteat!(arr, idx) |
Tri (en place) | sort!(arr) |
Concaténation de b à la suite de a (en place) |
append!(a,b) |
Test si val est un élément de arr |
in(val, arr) ou val in arr |
Produit scalaire | dot(a, b) == sum(a .* b) |
Changement de dimensions (si possible) | reshape(1:6, 3, 2)' == [1 2 3; 4 5 6] |
Conversion en chaîne de caractères (éléments séparés par delim ) |
join(arr, delim) |
Pour accéder à la plupart des outils d’algèbre linéaire, utiliser using LinearAlgebra
.
Matrice identité | I # utiliser seulement la variable I. Se conformera automatiquement aux dimensions requises. |
Définir une matrice | M = [1 0; 0 1] |
Dimensions d’une matrice | size(M) |
Sélectionner la i -ème ligne |
M[i, :] |
Sélectionner la i -ème colonne |
M[:, i] |
Concaténer horizontalement | M = [a b] or M = hcat(a, b) |
Concaténer verticalement | M = [a ; b] or M = vcat(a, b) |
Transposition de matrice | transpose(M) |
Transposition de matrice conjuguée | M' or adjoint(M) |
Trace de la matrice | tr(M) |
Déterminant de la matrice | det(M) |
Rang de la matrice | rank(M) |
Valeurs propres de la matrice | eigvals(M) |
Vecteurs propres de la matrice | eigvecs(M) |
Matrice inverse | inv(M) |
Résoudre M*x == v |
M\v est meilleur Numériquement plus stable et aussi plus rapide. que inv(M)*v |
Pseudo-inverse de Moore-Penrose | pinv(M) |
Julia supporte nativement la décomposition de matrice.
Julia essaie d’inférer le type d’une matrice (si elle est symétrique,
hermitienne, etc.), mais y échoue parfois. Pour aider Julia à exécuter
les algorithmes optimaux, des matrices spéciales peuvent être déclarées
pour avoir une structure avec des fonctions comme Symmetric
, Hermitian
,
UpperTriangular
, LowerTriangular
, Diagonal
, et d’autres.
Tests conditionnels | if-elseif-else-end |
Boucle simple | for i in 1:10 println(i) end |
Boucle à indices multiples | for i in 1:10, j = 1:5 println(i*j) end |
Énumeration | for (idx, val) in enumerate(arr) println("the $idx-th element is $val") end |
Boucle “tant que” | while bool_expr # do stuff end |
Sortie de boucle prématurée | break |
Saut à l’itération suivante | continue |
Tous les arguments de fonctions sont passés par référence.
Par convention, les fonctions dont le nom se termine par !
changent (mutent)
au moins l’un de leurs arguments (en général le premier). Par exemple :
sort!(arr)
.
Les arguments positionnels sont séparés par une virgule. Ils sont obligatoires,
sauf si une valeur par défaut est fournie dans la signature de la fonction, au
moyen du signe =
. A partir du premier argument optionnel, tous les arguments
positionnels suivants doivent aussi être optionnels.
Les arguments par mot-clé sont identifiés par leur nom, et listés dans la signature de fonction après un point-virgule :
function func(req1, req2, opt1=dflt1; key1=dflt1, key2=dflt2)
# do stuff
end
Le point-virgule n’est pas nécessaire pour identifier les arguments par mot-clé lors de l’appel à la fonction :
func(val_req1, val_req2, key1=val_key1)
# opt1 et key2: valeur par défaut
Le mot-clé return
est optionnel. S’il n’est pas présent, la valeur de la
dernière expression évaluée est renvoyée.
On peut renvoyer plusieurs valeurs en utilisant un Tuple
: return (val1, val2)
Les arguments passés à Julia en ligne de commande (julia script.jl arg1
arg2...
) peuvent être récupérés dans la constante globale ARGS
:
for arg in ARGS
println(arg)
end
Les fonctions anonymes sont souvent utiles en conjonction avec des fonctions
d’ordre supérieur ou des listes en compréhension:
x -> x^2
.
Les fonctions peuvent accepter un nombre variable d’arguments:
function func(a...)
println(a)
end
func(1, 2, [3:5]) # tuple: (1, 2, UnitRange{Int64}[3:5])
Les déclarations de fonctions peuvent être imbriquées:
function outerfunction()
# do some outer stuff
function innerfunction()
# do inner stuff
# can access prior outer definitions
end
# do more outer stuff
end
Les fonctions peuvent spécifier un type pour leur arguments ainsi que leur résultat :
# accepte n'importe quel argument sous-typant un nombre,
# et le renvoie sous forme de chaîne de caractères
function stringifynumber(num::T)::String where T <: Number
return "$num"
end
Les fonctions peuvent être
“vectorisées”,
(appliquées élément-par-élément) en utilisant la syntaxe “.
” :
julia> using Statistics
julia> A = rand(3, 4);
# La soustraction est "broadcastée" ici
julia> B = A .- mean(A, dims=1)
3×4 Array{Float64,2}:
0.0387438 0.112224 -0.0541478 0.455245
0.000773337 0.250006 0.0140011 -0.289532
-0.0395171 -0.36223 0.0401467 -0.165713
julia> mean(B, dims=1)
1×4 Array{Float64,2}:
-7.40149e-17 7.40149e-17 1.85037e-17 3.70074e-17
Julia génère des versions spécialisées Le dispatch multiple choisit la méthode la plus adaptée aux types d’arguments fournis (dynamiquement, i.e sur la base des types de valeurs constatés lors de l’exécution). A partir du code de la méthode choisie, la spécialisation permet ensuite de générer un code binaire natif optimal pour les types d’arguments fournis. Tout ceci est différent de la surcharge de fonctions, qui s’appuie exclusivement sur les types connus à la compilation. de chaque fonction, pour chaque type de données passées en argument. Quand une fonction est appelée à nouveau pour les mêmes types d’arguments, une version précédemment spécialisée peut être ré-utilisées ce qui évite d’avoir à repasser par une phase de compilation.
Il est possible que l’ensemble des méthodes définies conduisent à des ambiguïtés potentielles, mais réaliser effectivement un appel à une méthode ambiguë provoque une erreur à l’exécution.
Des dépassements de pile (Stack Overflows) peuvent arriver lorsque des appels de fonctions récursives s’imbriquent sur trop de niveaux. Des techniques de trampoline peuvent être mises en place pour émuler l’optimisation de la récursivité terminale (Tail Call Optimization), que Julia ne réalise pas (encore ?) par défaut. Les situations de récursivité terminale peuvent aussi être récrites sous forme de boucle.
Dictionnaire | d = Dict(key1 => val1, key2 => val2, ...) d = Dict(:key1 => val1, :key2 => val2, ...) |
Toutes clés (itérateur) | keys(d) |
Toutes valeurs (itérateur) | values(d) |
Itérer par paire clé-valeur | for (k,v) in d println("key: $k, value: $v") end |
Vérifier la présence de la clé :k |
haskey(d, :k) |
Copier les clés (ou valeurs) vers un tableau | arr = collect(keys(d)) arr = [k for (k,v) in d] |
Les dictionnaires sont muables; quand des symboles sont utilisés comme clés, les clés sont immuables.
Déclaration | s = Set([1, 2, 3, "Some text"]) |
Union s1 ∪ s2 |
union(s1, s2) |
Intersection s1 ∩ s2 |
intersect(s1, s2) |
Différence s1 \\ s2 |
setdiff(s1, s2) |
Différence s1 △ s2 |
symdiff(s1, s2) |
Inclusion s1 ⊆ s2 |
issubset(s1, s2) |
Vérifier si un élément est contenu dans un ensemble est effectué en O(1).
Appeler une fonction pour chaque élément de coll |
map(fun, coll) oumap(coll) do elem # faire qqch avec elem end |
Garder les valeurs satisfaisant un prédicat | filter(pred, coll) |
Liste en compréhension | arr = [f(elem) for elem in coll] |
Julia n’a pas de classes, et par conséquent pas de méthodes de classe. Les types Julia sont similaires à des classes sans méthode.
Les types abstraits peuvent être sous-typés, mais pas instanciés. Les types concrets ne peuvent être sous-typés.
Par défaut, les struct
s sont immutables. Les types immutables améliorent la
performance et sont thread-safe puisqu’on ne peut accéder à leurs instances
qu’en lecture.
Les types Union
permettent de représenter un ensemble de types.
Assertion de type, annotation | var::TypeName |
Déclaration de type | struct Programmer name::String birth_year::UInt16 fave_language::AbstractString end |
Déclaration de type mutable | remplacer struct par mutable struct |
Alias de type | const Nerd = Programmer |
Liste des constructeurs d’un type | methods(TypeName) |
Instanciation d’un type (construction d’une instance) | me = Programmer("Ian", 1984, "Julia") me = Nerd("Ian", 1984, "Julia") |
Déclaration d’un sous-type | abstract type Bird end struct Duck <: Bird pond::String end |
Type paramétrique | struct Point{T <: Real} x::T y::T end p =Point{Float64}(1,2) |
Type union | Union{Int, String} |
Parcours de la hiérarchie de types | supertype(TypeName) and subtypes(TypeName) |
Supertype universel | Any |
Liste des champs | fieldnames(TypeName) |
Liste des types des champs | TypeName.types |
Lorsqu’une définition de type inclut un constructeur interne, les
constructeurs externes par défaut ne sont plus disponibles. Ils doivent être
définis manuellement si nécessaire. Un constructeur interne est utile pour
garantir des invariants sur les champs d’un type. (Ces invariants pourront quand
même être enfreints par une modification directe des champs, à moins que le type
soit immutable). Le mot-clé new
utilisé dans un constructeur interne permet de
créer un objet du type adéquat.
Les paramètres de type sont invariants, c’est à dire que Point{Float64} <:
Point{Real}
est faux, alors même que Float64 <: Real
.
En revanche, les Tuple
sont covariants : Tuple{Float64} <: Tuple{Real}
.
La représentation interne d’un morceau de code après inférence de types peut
être consultée grâce à code_typed()
. Ceci est en particulier utile pour
identifier les endroits où des expressions de type Any
sont manipulées plutôt
que du code natif de type spécifique.
Null des programmeurs | nothing |
Donnée manquante | missing |
Pas un Nombre Flottant | NaN |
Filtrer les manquants | collect(skipmissing([1, 2, missing])) == [1,2] |
Remplacer les manquants | collect((df[:col], 1)) |
Vérifier les manquants | ismissing(x) pas x == missing |
Lancer SomeExcep |
throw(SomeExcep()) |
Relancer l’exception courante | rethrow() |
Définir NewExcep |
struct NewExcep <: Exception v::String end Base.showerror(io::IO, e::NewExcep) = print(io, "A problem with $(e.v)!") throw(NewExcep("x")) |
Lever une erreur avec un message | error(msg) |
Gérer les exceptions | try # quelque chose de dangereux catch ex if isa(ex, SomeExcep) # gérer SomeExcep elseif isa(ex, AnotherExcep) # gérer AnotherExcep else # gérer les autres exceptions end finally # fait dans tous les cas end |
Les modules sont des espaces de noms séparés qui groupent des fonctionnalités similaires.
Définition de module | module PackageName # déclarations de fonctions, types... # 'export' rend les définitions accessibles end |
Inclure un fichier source | include("filename.jl") |
Chargement | # tous les noms exportés using ModuleName # uniquement x, y using ModuleName: x, y # uniquement ModuleName import ModuleName # uniquement x, y # accessibles à l'extension de méthodes import ModuleName: x, y import ModuleName.x, ModuleName.y |
Liste des définitions | # Liste des noms exportés par ModuleName names(ModuleName) # y compris non-exportés, obsolètes # et noms générés par le compilateur names(ModuleName, all::Bool) # y compris noms importés d'un autre module names(ModuleName, all::Bool, imported::Bool) |
Une fonction foo
rendue visible par using Foo
ne peut être étendue par une
nouvelle méthode qu’explicitement : function Foo.bar(...)
.
Avec import Foo.bar
, l’ajout de méthode peut être non qualifié :
function bar(...)
suffit.
Julia est homoiconique: les programmes sont représentés comme des structures de données
du langage lui-même. De fait, tout est une expression Expr
.
Les symboles sont des chaînes internes Une seule copie
de chaque valeur de chaîne distincte (immuable) est stockée. préfixés par deux points :
.
Les symboles sont plus efficaces et ils sont typiquement utilisés comme identifiants, clés
(dans les dictionnaires), ou colonnes dans les tableaux. Les symboles ne peuvent pas être concaténés.
Citer :( ... )
ou quote ... end
crée une expression, tout comme
Meta.parse(str)
Cette forme est probablement
plus familière aux personnes avec une connaissance du SQL dynamique. La fonction Meta.parse
est similaire à EXECUTE IMMEDIATE
dans Oracle et PostgreSQL ou la procédure
sp_executesql()
dans SQL Server. , et Expr(:call, ...)
.
x = 1
line = "1 + $x" # some code
expr = Meta.parse(line) # make an Expr object
typeof(expr) == Expr # true
dump(expr) # generate abstract syntax tree
eval(expr) == 2 # evaluate Expr object: true
Les macros permettent à du code généré (i.e. expressions) d’être inclus dans un programme. Voir le chapitre sur la métaprogrammation.
Définition | macro macroname(expr) # do stuff end |
Usage | macroname(ex1, ex2, ...) or @macroname ex1, ex2, ... |
Macros intégrées | @test # equal (exact) @test x ≈ y # isapprox(x, y) @assert # assert (unit test) @which # types utilisés @time # statistiques de tmeps et mémoire @elapsed # temps écoulé @allocated # mémoire allouée @profile # profil @spawn # exécuter sur un travailleur quelconque @spawnat # exécuter sur un travailleur spécifique @async # tâche asynchrone @distributed # parallélisation pour boucles @everywhere # rendre disponible à tous les travailleurs |
Règles pour créer des macros hygiéniques:
local
.eval
au sein de la macro.$(esc(expr))
Les outils de calcul parallèle sont disponibles dans la librairie standarde Distributed
.
Lancer REPL avec N travailleurs | julia -p N |
Nombre de travailleurs disponibles | nprocs() |
Ajouter N travailleurs | addprocs(N) |
Voir tous les IDs des travailleurs | for pid in workers() println(pid) end |
Obtenir l’ID du travailleur exécutant | myid() |
Enlever travailleur | rmprocs(pid) |
Exécuter f avec les arguments args via pid | r = remotecall(f, pid, args...) # ou: r = @spawnat pid f(args) ... fetch(r) |
Exécuter f avec les arguments args via pid (plus efficace) | remotecall_fetch(f, pid, args...) |
Exécuter f avec les arguments args via n’importe quel travailleur | r = @spawn f(args) ... fetch(r) |
Exécuter f avec les arguments args via tous les travailleurs | r = [@spawnat w f(args) for w in workers()] ... fetch(r) |
Rendre expr disponible à tous les travailleurs | @everywhere expr |
Parallélisation pour boucle avec la fonction réductriceUn réducteur combine les résultats de différents travailleurs (indépendants). red | sum = @distributed (red) for i in 1:10^6 # travail parallèle end |
Applique f à tous les éléments de la collection coll | pmap(f, coll) |
Les travailleurs sont aussi appelés processus concurrents/parallèles.
Il vaut mieux que les modules avec des capacités de processus parallèle soient partagés au sein d’un fichier de fonctions qui contient toutes les fonctions et variables requises par tous les travailleurs, et un fichier pilote qui gère le traitement de la donnée. Le pilote doit évidemment importer le fichier de fonctions.
Un exemple non-trivial (décompte de mots) d’une fonction reductrice est procuré par Adam DeConinck.
Lire un flux | stream = stdin for line in eachline(stream) # do stuff end |
Lire un fichier | open(filename) do file for line in eachline(file) # do stuff end end |
Lire un fichier CSV | using CSV data = CSV.read(filename) |
Ecrire un fichier CSV | using CSV CSV.write(filename, data) |
Sauvegarder un objet Julia | using JLD save(filename, "object_key", object, ...) |
Charger un objet Julia | using JLD d = load(filename) # Returns a dict of objects |
Sauvegarder un fichier HDF5 using HDF5 h5write(filename, "key", object) |
|
Charger un fichier HDF5 | using HDF5 h5read(filename, "key") |
Pour des outils similaires à dplyr
, voir
DataFramesMeta.jl.
Lire Stata, SPSS, etc. | StatFiles Package |
DécrireSimilaire à summary(df) dans R. un data frame |
describe(df) |
Obtenir la colonne col en vecteur |
v = df[:col] |
Sort by col |
sort!(df, [:col]) |
col CatégoriqueSimilaire à df$col = as.factor(df$col) dans R. |
categorical!(df, [:col]) |
Lister les niveaux de col |
levels(df[:col]) |
Toutes observations telles que col==val |
df[df[:col] .== val, :] |
Restructurer d’un format large à long | stack(df, [1:n; ]) stack(df, [:col1, :col2, ...]) melt(df, [:col1, :col2]) |
Restructurer d’un format long à large | unstack(df, :id, :val) |
Rendre Nullable |
allowmissing!(df) or allowmissing!(df, :col) |
Itérer par ligne | for r in eachrow(df) # do stuff. # r is Struct with fields of col names. end |
Itérer par colonne | for c in eachcol(df) # do stuff. # c is tuple with name, then vector end |
Appliquer func par groupes |
by(df, :group_col, func) |
Interroger | using Query query = @from r in df begin @where r.col1 > 40 @select {new_name=r.col1, r.col2} @collect DataFrame # Default: iterator end |
Type | typeof(name) |
Vérification de type | isa(name, TypeName) |
Lister les sous-types | subtypes(TypeName) |
List les super-types | supertype(TypeName) |
Méthodes d’une fonction | methods(func) |
JIT bytecode | code_llvm(expr) |
Code Assembleur | code_native(expr) |
Plusieurs paquets centraux sont gérés communautairement avec des noms sous la forme de Julia[Topic].
Statistiques | JuliaStats |
Machine Learning Scientifique | SciML (ancien DifferentialEquations.jl) |
Différentiation automatique | JuliaDiff |
Optimisation numérique | JuliaOpt |
Tracés graphiques (plots) | JuliaPlots |
Analyses de réseau (graphes) | JuliaGraphs |
Web | JuliaWeb |
Géo-Spatial | JuliaGeo |
Machine Learning | JuliaML |
Paquets les plus utilisés | DataFrames # régresion linéaire/logistique Distributions # Distributions stistiques Flux # Machine learning Gadfly # Tracés graphiques simili-ggplot2 Graphs # Analyse de réseau TextAnalysis # Traitement de Langage Naturel (NLP) |
La principale convention dans Julia est d’éviter les underscores à moins qu’ils ne soient requis par souci de lisibilité.
Les noms de variable doivent être en minuscules: somevariable
.
Les noms de constante doivent être en majuscules: SOMECONSTANT
.
Les noms de fonction doivent être en minuscules: somefunction
.
Les noms de macro doivent être en minuscules: @somemacro
.
Les noms de type doivent être en notation chameau: SomeType
.
Les fichiers Julia ont une extension jl
.
Pour davantage d’informations à propos du style du code Julia, visiter le manuel: guide du style.
sizehint!
pour les tableaux larges.arr = nothing
.disable_gc()
....
) comme mot-clé d’argument.!
) pour éviter de copier des structures de données.try
-catch
dans les boucles (notamment de calcul intensif).Any
dans les collections.eval
lors de l’exécution.