Ve

Vecteurs en Julia

1 exercice

À propos de Vecteurs

L'un des objectifs centraux de Julia est de pouvoir effectuer des calculs sur des données numériques, rapidement et efficacement. Et sur beaucoup de données numériques.

En général, ces données sont stockées dans des tableaux (ou dans un type apparenté), et l'on peut donc dire sans exagérer que les tableaux sont au cœur du langage Julia.

Un tableau peut être de taille arbitraire (seules les limites de mémoire de ta machine le contraignent) et avoir un nombre arbitraire de dimensions.

Certains types de tableaux portent des noms particuliers (empruntés à l'algèbre linéaire). Un tableau à une dimension s'appelle un Vector et un tableau à deux dimensions s'appelle un Matrix. Tous deux sont des sous-types de Array en Julia.

Ce concept d'introduction se concentre sur les bases des vecteurs. Les tableaux de dimension supérieure seront abordés plus loin dans le programme.

Crée des vecteurs

En Julia, un vecteur est une séquence ordonnée de valeurs auxquelles on accède par un numéro d'indice.

La façon la plus simple de créer un vecteur est de lister les valeurs entre crochets :

julia> num_vec = [1, 4, 9]
3-element Vector{Int64}:
 1
 4
 9

julia> str_vec = ["arrays", "are", "important"]
3-element Vector{String}:
 "arrays"
 "are"
 "important"

Le type du vecteur correspond au type de chacun de ses éléments.

Techniquement, il s'agit d'un vecteur colonne, mais si l'algèbre linéaire ne t'est pas familière, ignore ce détail pour l'instant. Cela deviendra plus clair après le concept sur les tableaux multidimensionnels.

Alors, un vecteur doit forcément être homogène (tous les éléments du même type) ?

D'une certaine manière, oui, et c'est ce qu'il faut viser si tu veux les meilleures performances. Julia peut toutefois contourner cette limitation (quand c'est nécessaire) en utilisant le type Any :

julia> mixed_vector = [1, "str", 'c']
3-element Vector{Any}:
 1
  "str"
  'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)

Quand on crée un vecteur vide, Julia utilise par défaut le type d'élément Any, mais on peut le définir plus précisément en annotant le tableau vide avec le type d'élément souhaité.

julia> empty_vec = []
Any[]

julia> empty_int_vec = Int64[]
Int64[]

Vecteurs pré-remplis

Il est très courant de partir de vecteurs ne contenant que des 0 ou que des 1. Pour cela, il existe des fonctions nommées (sans surprise) zeros() et ones(), qui prennent la taille du vecteur en paramètre. Le type par défaut est Float64, mais on peut éventuellement en spécifier un autre.

De la même manière, la fonction fill() prend à la fois la valeur à répéter et la taille de vecteur souhaitée.

julia> zeros(3)
3-element Vector{Float64}:
 0.0
 0.0
 0.0

julia> ones(3)
3-element Vector{Float64}:
 1.0
 1.0
 1.0

julia> ones(Int64, 3)
3-element Vector{Int64}:
 1
 1
 1

julia> fill(42, 3)
3-element Vector{Int64}:
 42
 42
 42

Il existe bien d'autres possibilités : voir le manuel.

Lis et retiens bien cette règle :

  • Par défaut, l'indexation en Julia commence à 1, et non à 0.

Cela ne surprendra personne parmi ceux qui ont utilisé d'autres langages de science des données (R, Matlab, Fortran...), mais peut sembler choquant aux informaticiens venus des langages de la famille du C.

Pour le reste, les indices fonctionnent comme on peut s'y attendre : il suffit de les mettre entre crochets :

squares = [0, 1, 4, 9, 16]
squares[1]  # 0
squares[3]  # 4
squares[begin]  # 0 ("begin" is synonym for 1)
squares[end]  # 16 ("end" is synonym for length(squares))

Remarque la commodité de l'indexation avec end (qui est très utile) et avec begin (qui l'est probablement moins).

Les programmeurs Python se demandent peut-être ce qu'il en est des indices négatifs. Oublie : ils ne font pas partie de Julia et déclenchent une BoundsError, tout comme un indice inférieur à 1 ou supérieur à length(squares).

Opérations sur les vecteurs

Les vecteurs en Julia sont mutables : on peut modifier le contenu de chaque cellule individuellement.

julia> vals = [1, 3, 5, 7]
4-element Vector{Int64}:
 1
 3
 5
 7

julia> vals[2] = 4  # reassign the value of this element
4

# Only the value at position 2 changes:
julia> vals
4-element Vector{Int64}:
 1
 4
 5
 7

Il existe de nombreuses fonctions disponibles pour manipuler les vecteurs, même si la documentation de Julia les généralise à des « collections » plutôt qu'à des vecteurs.

Remarque que, par convention, les fonctions qui modifient leur entrée portent un ! dans leur nom. Le compilateur ne l'impose pas, mais c'est une convention très forte dans le monde Julia.

Voici quelques-unes des fonctions utiles :

  • Pour ajouter des valeurs à la fin du vecteur, utilise push!().
  • Pour supprimer la dernière valeur, utilise pop!().
  • Pour agir sur le début du vecteur, les fonctions correspondantes sont pushfirst!() et popfirst!().
  • Pour insérer ou supprimer un élément à n'importe quelle position, il y a insert!() et deleteat!().
julia> vals = [1, 3]
2-element Vector{Int64}:
 1
 3

julia> push!(vals, 5, 6)  # can add multiple values
4-element Vector{Int64}:
 1
 3
 5
 6

julia> pop!(vals)  # mutates vals, return popped value
6

julia> vals
3-element Vector{Int64}:
 1
 3
 5

Concaténation

La concaténation est assez simple pour les vecteurs, même si un coup d'œil au manuel laisse entrevoir des complications en réserve dès qu'on aborde les tableaux multidimensionnels.

La fonction append!() accepte en entrée un mélange de plusieurs vecteurs et d'éléments isolés.

julia> append!([1, 2], [3, 4], [-1, -2], 15)
7-element Vector{Int64}:
  1
  2
  3
  4
 -1
 -2
 15
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet

Apprends Vecteurs