Utilisateur:Tkova474/Brouillon

En informatique, un langage de programmation matriciel généralise de façon transparente les opérations effectués sur les scalaires à des vecteurs, des matrices, et des tableaux de dimensions supérieures.

La programmation matriciel permet une grande concision lorsque l'on manipule des tableaux. Le niveau de concision peut être spectaculaire dans certain cas : il n'est en effet pas rare de trouver des unilignes dans un langage de programmation matriciel qui demande plus de deux pages de code Java.[1]

De nombreux langages de programmation actuels permettent la programmation matriciel et sont utilisés en science ou en ingénierie ; on peut citer Fortran 90, Mata, MATLAB, Analytica, TK Solver (avec des listes), Octave, R, Cilk Plus, Julia, et l'extension NumPy de Python. Dans ces langages, une opération qui opère sur des tableaux est souvent appelé une opération vectorisée[2] indépendamment du fait qu'elle soit exécutée ou non sur un processeur vectoriel.

Les Principes

modifier

L'idée fondamentale derrière la programmation matricielle est le fait que les opérations s'effectuent sur des ensembles de variables en une instruction. Cela en fait un outil de programmation haut-niveau car il permet au programmateur de penser et d'agir sur des données agrégées sans avoir à utiliser de façon explicites des boucles sur des opérations scalaires.

Ainsi, elle permet l'exploitation efficace de certaines données où les éléments individuels sont similaires ou adjacent (par exemple, les valeur d'un pixel dans une image).

Dans ce contexte, le rang d'une fonction (par analogie avec le rang d'un tenseur) est un concept important de la programmation matricielle : les fonctions qui effectuent des opérations sur des données peuvent ainsi être classée par le nombre de dimensions sur lesquelles elles agissent. La multiplication classique, par exemple, est une fonction de rang 0 car elle opère sur des données de dimension 0 (des nombres individuels). Le produit vectoriel, lui, est un exemple de fonction de rang 1 var elle opère sur des vecteurs et non des scalaires. Le produit matriciel est un exemple d'une fonction de rang 2 car elle opère sur des objets à 2 dimensions (matrices). Certaines opérations réduisent la dimension du résultat d'une ou plusieurs unités par rapport à la dimension des données fournies. Ainsi, la sommation d’éléments suivant une des dimension réduira la dimension du résultat de 1.

Utilisation

modifier

La programmation matricielle est bien adaptée à la parallélisation implicite; un sujet de recherche d'actualité.

Langages

modifier

Les exemples canoniques de langages de programmation matriciel sont APL, J, et Fortran. Il existe également : D, A+, Analytica, Chapel, IDL, Julia, K, Q, Mata (pour le logiciel Stata), Mathematica, MATLAB, MOLSF, NumPy (pour le langage Python), GNU Octave, PDL, R, S-Lang, SAC, Nial et ZPL.

Langages scalaires

modifier

Dans les langages scalaires comme C ou Pascal, les opérations s'effectuent seulement sur des variables seules (de dimension 0), ainsi a+b exprime l'addition de deux nombres. Dans ce type de langage, l’addition de deux tableaux requière ainsi l'utilisation de l'indexage et de boucles. En plus d'être fastidieux, cela est difficilement lisible et peut facilement conduire à des erreurs.

for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)
        a[i][j] += b[i][j];

Langages matriciels

modifier

Pour les langages matriciels, les opérations sont généralisé afin de s'appliquer naturellement à la fois aux scalaires et aux tableaux. Ainsi, a+b exprime la somme de deux scalaires si a et b sont des scalaires, ou la somme de deux tableaux si il s'agit de tableaux.

Un langage matriciel peut ainsi grandement simplifié la programmation. Comme pour tous les outils de programmation haut-niveau, cela se fait possiblement au risque d'un de coût d'abstraction.[3][4][5]

Le code C précédent deviendrait, dans le langage Ada,[6] qui permet la programmation matricielle.

 A := A + B;

Le langage de programmation Mata du logiciel Stata permet également la programmation matricielle.

. mata:

: A = (1,2,3) \(4,5,6)

: A
       1   2   3
    +-------------+
  1 |  1   2   3  |
  2 |  4   5   6  |
    +-------------+

: B = (2..4) \(1..3)

: B
       1   2   3
    +-------------+
  1 |  2   3   4  |
  2 |  1   2   3  |
    +-------------+

: C = J(3,2,1)           // Une matrice remplie de 1 de dimension 3 x 2

: C
       1   2
    +---------+
  1 |  1   1  |
  2 |  1   1  |
  3 |  1   1  |
    +---------+

: D = A + B

: D
       1   2   3
    +-------------+
  1 |  3   5   7  |
  2 |  5   7   9  |
    +-------------+

: E = A*C

: E
        1    2
    +-----------+
  1 |   6    6  |
  2 |  15   15  |
    +-----------+

: F = A:*B

: F
        1    2    3
    +----------------+
  1 |   2    6   12  |
  2 |   4   10   18  |
    +----------------+

: G = E :+ 3

: G
        1    2
    +-----------+
  1 |   9    9  |
  2 |  18   18  |
    +-----------+

: H = F[(2\1), (1, 2)]    // Utilisation des indices pour avoir une sous-matrice de F
:                         // et intervertir les colonnes 1 et 2
: H
        1    2
    +-----------+
  1 |   4   10  |
  2 |   2    6  |
    +-----------+

: I = invsym(F'*F)        // Inverse généralisée (F*F^(-1)F=F) d'une 
:                         // matrice symétrique semi-définie positive
: I
[symmetric]
                 1             2             3
    +-------------------------------------------+
  1 |            0                              |
  2 |            0          3.25                |
  3 |            0         -1.75   .9444444444  |
    +-------------------------------------------+

: end

Le nom du langage (matrix laboratory) vient de la volonté de s'inscrire dans ce paradigme de la programmation. Une implémentation dans MATLAB permet la même concision qu'avec le langage Ada :

A = A + B;

Une variante du langage MATLAB est le langage de GNU Octave, qui étend le langage avec des affectations augmentées :

A += B;

Les deux logiciels MATLAB et GNU Octave permette nativement la résolution d'opération d'algèbre linéaire tel que le produit matriciel, l'inversion matricielle, et la résolution d'un système d'équations linéaires, jusqu'à utiliser des pseudo-inverse de Moore-Penrose.[7][8]

Le langage R utilise le paradigme matriciel par défaut. L'exemple suivant illustre la multiplication de deux matrices suivie par l'addition d'un scalaire (en fait, un vecteur d'un élément) puis un vecteur:

> A <- matrix(1:6, nrow=2)
> A
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> B <- t( matrix(6:1, nrow=2) )  # t() est l'opérateur transposé
> B
     [,1] [,2]
[1,]    6    5
[2,]    4    3
[3,]    2    1
> C <- A %*% B
> C
     [,1] [,2]
[1,]   28   19
[2,]   40   28
> D <- C + 1
> D
     [,1] [,2]
[1,]   29   20
[2,]   41   29
> D + c(1, 1)  # c() crée un vecteur
     [,1] [,2]
[1,]   30   21
[2,]   42   30

L'opérateur division à gauche : lien entre concept mathématique et sa notation dans certains langages

modifier

L'opérateur de division matriciel à gauche permet d'exprimer de façon concise des propriétés des matrices. Ainsi, si le déterminant de la matrice A n'est pas nul, alors il est possible de résoudre l'équation vectorielle A * x = b en multipliant à gauche des deux côté par l'inverse de A: A−1 (avec les langages MATLAB et GNU Octave : A^-1). Ainsi, tant que A est inversibles (de rang plein) :

A^-1 *(A * x)==A^-1 * (b)
(A^-1 * A)* x ==A^-1 * b       (associativité du produit matriciel)
x = A^-1 * b

avec == , l'opérateur d'équivalence. Les instructions précédentes sont également valides avec MATLAB si la troisième est exécuté avant les deux autres (aux erreurs d'arrondis près).

Si le système est surdéterminé - avec A qui a plus de lignes que de colonnes - le pseudo-inverse A+ (avec les langages MATLAB et GNU Octave : pinv(A)) peut remplacer l'inverse A−1 comme suit :

pinv(A) *(A * x)==pinv(A) * (b)
(pinv(A) * A)* x ==pinv(A) * b       (associativité du produit matriciel)
x = pinv(A) * b

Néanmoins, ces solutions ne sont ni les plus concises (il est nécessaire de différencier les systèmes surdéterminés) ni les plus efficaces informatiquement parlant. Ce point peut être facile à cerné lorsque l'on étudie l'équivalent scalaire a * x = b, dont la solution x = a^-1 * b requiert deux opérations à la place d'une seule opération avec x = b / a. Le probleme vient que la multiplication matricielle n'est pas commutative. C'est pourquoi le langage MATLAB a introduit l'opérateur de division matriciel à gauche \ afin de pouvoir poursuivre l'analogie avec le cas scalaire, et ainsi simplifié le raisonnement mathématique et la concision :

A \ (A * x)==A \ b
(A \ A)* x ==A \ b       (associativité du produit matriciel)
x = A \ b

Ceci est un exemple de la sobriété que permet les langages matriciels, à la fois au niveau de la lisibilité du code, du respect du raisonnement mathématique sous-jacent et de l'efficacité de la résolution numérique. Pour ce dernier point, beaucoup de langages de programmation matriciel se basent sur des librairies d'algèbre linéaire éprouvées comme ATLAS or LAPACK.[9][10]

Librairies tierces

modifier

La capacité de certains langage à surcharger un opérateur permettent de passer d'un langage scalaire à un langage matriciel. Ainsi, dans le langage C++ plusieurs librairies d'algèbre linéaire sont explicitement influencées par les paradigmes de la programmation matricielle, comme pour les librairies Armadillo et Blitz++.[11][12]

Références

modifier
  1. Michael Schidlowsky, « Java and K » (consulté le )
  2. « The NumPy array: a structure for efficient numerical computation », Computing in Science and Engineering, IEEE,‎
  3. Surana P, « Meta-Compilation of Language Abstractions. », {{Article}} : paramètre « périodique » manquant,‎ (lire en ligne [PDF], consulté le )
  4. Kuketayev, « The Data Abstraction Penalty (DAP) Benchmark for Small Objects in Java. » (consulté le )
  5. (en) Chatzigeorgiou et Stephanides, Proceedings - 7th International Conference on Reliable Software Technologies - Ada-Europe'2002, Springer, , 367 p. (ISBN 978-3-540-43784-0, lire en ligne), « Evaluating Performance and Power Of Object-Oriented Vs. Procedural Programming Languages »
  6. Ada Reference Manual: G.3.1 Real Vectors and Matrices
  7. « GNU Octave Manual. Arithmetic Operators. » (consulté le )
  8. « MATLAB documentation. Arithmetic Operators. » (consulté le )
  9. « GNU Octave Manual. Appendix G Installing Octave. » (consulté le )
  10. « Mathematica 5.2 Documentation. Software References. » (consulté le )
  11. « Reference for Armadillo 1.1.8. Examples of Matlab/Octave syntax and conceptually corresponding Armadillo syntax. » (consulté le )
  12. « Blitz++ User's Guide. 3. Array Expressions. » (consulté le )
modifier

{{Programming language}} [[Category:Array programming languages| ]] [[Category:Programming paradigms]] [[Category:Articles with example MATLAB/Octave code]] [[Category:Articles with example BASIC code]] [[Category:Articles with example Ada code]]