Produit matriciel

Plan du chapitre "Calcul matriciel"

Produit des matrices

Définition (définition du produit de deux matrices)
Soit {A=(a_{ik})} dans {{\mathcal M}_{n,p}(\mathbb{K})} et {B=(b_{kj})} dans {{\mathcal M}_{p,q}(\mathbb{K})}.
On définit {M=AB}, dans {{\mathcal M}_{n,q}(\mathbb{K})}, par : {\forall\, i\in\{1,\ldots,n\},\;\forall\, j\in\{1,\ldots,q\},\;m_{ij}=\displaystyle\sum_{k=1}^pa_{ik}\,b_{kj}}

Interprétation et visualisation

Le terme de la {i}-ième ligne et de la {j}-ième colonne de {M=AB} est donc obtenu en sommant les produits des termes de même rang dans la {i}-ième ligne {\text{L}_{i}} de {A} et dans la {j}-ième colonne {\text{C}_{j}} de {B}, selon le schéma ci-après (on a encadré les coefficients de {A} et de {B} utiles au calcul du coefficient {c_{ij}}).

On verra plus loin les raisons pour lesquelles on choisit de définir de cette façon le produit matriciel.

Condition impérative de compatibilité

Le produit {AB} n’est possible que si le nombre de colonnes de {A} est égal au nombre de lignes de {B}.
On obtient alors une matrice ayant autant de lignes que {A}, et autant de colonnes que {B}.
En résumé : {\fbox{\text{matrice de type\ }(n,p)}\times\fbox{\text{matrice de type\ }(p,q)}=\fbox{\text{matrice de type\ }(n,q)}}
Avec Python on forme ici deux matrices aléatoires, {A} dans {\mathcal{M}_{4,3}(\mathbb{R})}, l’autre dans {\mathcal{M}_{3,5}(\mathbb{R})} :

>>> A=np.random.randint(10,size=(4,3)); print(A)
[[2 2 7] 
[6 3 8] 
[4 3 3] 
[7 7 0]] 
>>> B=np.random.randint(10,size=(3,5)); print(B)
[[6 8 1 2 6] 
[5 6 2 8 7] 
[5 6 8 4 9]]

On voit qu’on peut calculer {AB} et le résultat est une matrice de type {(4,5)}.
Mais le produit {BA} est impossible à calculer et conduirait à une erreur d’exécution.

>>> print(A.dot(B))    # ou np.dot(A,B)
[[ 57 70 62 48 89] 
[ 91 114 76 68 129] 
[ 54 68 34 44 72] 
[ 77 98 21 70 91]]

En Python, attention à l’opération * qui désigne en fait le produit “terme à terme” des tableaux.
Dans l’exemple ci-après, on effectue le produit terme à terme de deux matrices {A} et {B} de taille {4\times3}.
Le résultat est encore une matrice {4\times3} dont le terme général est {c_{i,j}=a_{i,j}b_{i,j}}. Ce produit (qui peut avoir son utilité) n’a rien à voir avec le produit matriciel dont nous parlons dans ce chapitre!

>>> print(A)
[[9 2 4] 
[4 3 7] 
[9 3 5] 
[6 1 9]] 
>>> print(B)
[[3 2 2] 
[1 8 1] 
[6 8 6] 
[4 5 2]] 
>>> print(A*B) # Attention, ce n’est pas le “vrai” produit matriciel!
[[27 4 8] 
[ 4 24 7] 
[54 24 30] 
[24 5 18]]

La non-commutativité du produit

Les produits {AB} et {BA} ne sont simultanément possibles que si {A} est de type {(n,p)} et {B} de type {(p,n)}.
La matrice {AB} est alors carrée d’ordre {n}, tandis que {BA} est carrée d’ordre {p}.

Si {n\ne p}, les matrices {AB} et {BA}, de formats différents, sont évidemment distinctes!

Si {A} et {B} sont toutes deux carrées d’ordre {n}, alors {AB} et {BA} sont encore carrées d’ordre {n}, mais là encore on a en général {AB\ne BA}. Dans le cas contraire (très rare), on dit que les matrices carrées {A} et {B} commutent (on en reparle plus loin).

Exemple avec Python : on utilise ici la fonction arange (qui forme le vecteur des éléments d’une suite arithmétique, ici la suite {0,1,\ldots,5}) et la fonction reshape (qui redéfinit la taille du tableau, du moment que le nombre de coefficients est le même).

>>> A = np.arange(6).reshape(3,2); print(A)
[[0 1] 
[2 3] 
[4 5]] 
>>> B = np.arange(6).reshape(2,3); print(B)
[[0 1 2] 
[3 4 5]]

On a donc formé une matrice {A} de type {(3,2)}, et une matrice {B} de type {(2,3)}.
Les deux produits {AB} et {BA} sont possibles, mais {AB} est carrée d’ordre {3} et {BA} est carrée d’ordre {2} :

>>> print(A.dot(B))
[[ 3 4 5] 
[ 9 14 19] 
[15 24 33]] 
>>> print(B.dot(A))
[[10 13] 
[28 40]]

Autre exemple, on forme ici deux matrices {A} et {B} carrées d’ordre {3} :

>>> A = np.random.rand(3,3); print(A)
[[ 0.75596295 0.96396382 0.45077587] 
[ 0.67323071 0.04498405 0.88736757] 
[ 0.86576073 0.03023288 0.42663428]] 
>>> B = np.random.rand(3,3); print(B)
[[ 0.68788001 0.35191549 0.98365263] 
[ 0.38822915 0.80922831 0.75737939] 
[ 0.92474908 0.11545089 0.3735433 ]]

On constate que les produits {AB} et {BA} sont différents (c’est le cas général!) :

>>> print(np.dot(A,B))
[[ 1.31110522 1.09814436 1.64207559] 
[ 1.30115841 0.37577006 1.02776536] 
[ 1.00180644 0.37839522 1.03387196]] 
>>> print(np.dot(B,A))
[[ 1.60853994 0.70866068 1.04201804] 
[ 1.49399354 0.43353898 1.2162113 ] 
[ 1.10020024 0.90791139 0.67866832]]

Propriétés du produit matriciel

Proposition (bilinéarité du produit matriciel)
Soit {A,B} dans {{\mathcal M}_{n,p}(\mathbb{K})}, soit {C,D} dans {{\mathcal M}_{p,q}(\mathbb{K})}, et soit {\lambda,\mu} deux scalaires.
Alors on a les égalités {\begin{cases}A(\lambda C+\mu D)=\lambda AC+\mu AD\\(\lambda A+\mu B)C=\lambda AC+\mu BC\end{cases}}

Cette propriété peut s’énoncer de la façon suivante :

  • Si on fixe {A\in{\mathcal M}_{n,p}(\mathbb{K})}, l’application {M\mapsto AM} est linéaire de {{\mathcal M}_{p,q}(\mathbb{K})} dans {{\mathcal M}_{n,q}(\mathbb{K})}.
  • Si on fixe {A\in{\mathcal M}_{p,q}(\mathbb{K})}, l’application {M\mapsto MA} est linéaire de {{\mathcal M}_{n,p}(\mathbb{K})} dans {{\mathcal M}_{n,q}(\mathbb{K})}.
  • On peut résumer den utilisant la notion de bilinéarité :
    L’application {(M,N)\mapsto MN} est bilinéaire de {{\mathcal M}_{n,p}(\mathbb{K})\times{\mathcal M}_{p,q}(\mathbb{K})} dans {{\mathcal M}_{n,q}(\mathbb{K})}.
Proposition (associativité du produit matriciel)
Soit {A} dans {{\mathcal M}_{n,p}(\mathbb{K})}, soit {B} dans {{\mathcal M}_{p,q}(\mathbb{K})}, et soit {C} dans {{\mathcal M}_{q,r}(\mathbb{K})}.
Alors, on a l’égalité {A(BC)=(AB)C} dans {{\mathcal M}_{n,r}(\mathbb{K})}.

Avec Python, on définit ici trois matrices {A}, {B}, {C}, de coefficients aléatoires dans {\{-1,0,1\}}.

>>> A = np.random.randint(-1,2,size=(3,4)); print(A)
[[ 0 1 1 0] 
[ 0 -1 1 0] 
[ 0 1 1 -1]] 
>>> B = np.random.randint(-1,2,size=(4,3)); print(B)
[[ 0 1 0] 
[ 0 1 1] 
[ 1 0 0] 
[ 1 -1 0]] 
>>> C = np.random.randint(-1,2,size=(3,2)); print(C)
[[ 0 1] 
[ 0 1] 
[-1 -1]]

On affiche alors {AB} (qui est dans {\mathcal{M}_{3,3}(\mathbb{R})}), puis {(AB)C} (qui est dans {\mathcal{M}_{3,2}(\mathbb{R})}).
Ensuite on affiche alors {BC} (qui est dans {\mathcal{M}_{4,2}(\mathbb{R})}), puis {A(BC)} (qui est dans {\mathcal{M}_{3,2}(\mathbb{R})}).
On constate que les deux matrices {A(BC)} et {(AB)C} sont égales dans {\mathcal{M}_{3,2}(\mathbb{R})} :

>>> print(A.dot(B))
[[ 1 1 1] 
[ 1 -1 -1] 
[ 0 2 1]] 
>>> print((A.dot(B)).dot(C))
[[-1 1] 
[ 1 1]& [-1 1]] 
>>> print(B.dot(C))
[[ 0 1] 
[-1 0] 
[ 0 1] 
[ 0 0]] 
>>>> print(A.dot(B.dot(C)))
[[-1 1] 
[ 1 1] 
[-1 1]]

Une justification du produit matriciel

Une situation particulière mais importante

L’application {u=(x_{1},x_{2},\ldots, x_{p})\to U=\begin{pmatrix}x_{1}\\ \vdots\\ x_{p} \end{pmatrix}} est un isomorphisme de {\mathbb{K}^{p}} sur {\mathcal{M}_{p,1}(\mathbb{K})}.
Cet isomorphisme permet d’identifier {u} et {U}.

Soit {A} un élément de {\mathcal{M}_{n,p}(\mathbb{K})}. L’application {U\mapsto V=AU} est linéaire de {\mathcal{M}_{p,1}(\mathbb{K})} dans {\mathcal{M}_{n,1}(\mathbb{K})}.

À un isomorphisme près, il s’agit donc d’une application linéaire de {\mathbb{K}^{p}} dans {\mathbb{K}^{n}}.
Considérons par exemple la matrice {A=\begin{pmatrix}2&1&0&3\\ 0&4&1&5\\ 1&6&2&0 \end{pmatrix}}, élément de {\mathcal{M}_{3,4}(\mathbb{R})}.
Si {U=\begin{pmatrix}x_{1}\\x_{2}\\x_{3}\\ x_{4} \end{pmatrix}\in\mathcal{M}_{4,1}(\mathbb{R})} (disons {\mathbb{R}^{4}}), {V=AU=\begin{pmatrix}y_{1}\\y_{2}\\y_{3}\end{pmatrix}\in\mathcal{M}_{3,1}(\mathbb{R})} (disons {\mathbb{R}^{3}}).
Le produit matriciel donne : {\begin{pmatrix}2&1&0&3\\ 0&4&1&5\\ 1&6&2&0 \end{pmatrix}\begin{pmatrix}x_{1}\\x_{2}\\x_{3}\\ x_{4} \end{pmatrix}=\begin{pmatrix}2x_{1}+x_{2}+3x_{4}\\ 4x_{2}+x_{3}+5x_{4}\\ x_{1}+6x_{2}+2x_{3}\end{pmatrix}}

Ainsi {\begin{cases}y_{1}=2x_{1}+x_{2}+3x_{4}\\y_{2}=4x_{2}+x_{3}+5x_{4}\\y_{3}=x_{1}+6x_{2}+2x_{3}\end{cases}}

À isomorphisme près, on a donc défini {f\colon u=(x_{1},x_{2},x_{3},x_{4})\mapsto v=(y_{1},y_{2},y_{3})} linéaire de {\mathbb{R}^{4}} dans {\mathbb{R}^{3}}.

On dira que la matrice {A} est canoniquement associée à l’application linéaire {f}.

Dans le cas général :

On peut légitimement identifier une application linéaire de {\mathbb{K}^{p}} dans {\mathbb{K}^{n}} avec une matrice {A} de {\mathcal{M}_{n,p}(\mathbb{K})}. Si on note {U,V} les matrices colonnes représentant respectivement {u} dans {\mathbb{K}^{p}} et {v} dans {\mathbb{K}^{n}}, cela nous permet d’identifier les égalités {v=f(u)} et {V=AU}.

Identification d’une matrice-ligne et d’une forme linéaire

Un élément {L} de {\mathcal{M}_{1,n}(\mathbb{K})} (une matrice-ligne de largeur {n}) s’identifie à une forme linéaire sur {\mathbb{K}^{n}}.

Par exemple, considérons la matrice ligne {A=\begin{pmatrix}a&b&c&d\end{pmatrix}}.

Pour toute {U=\begin{pmatrix}x\\ y\\ z\\t \end{pmatrix}}, on a : {AX=\begin{pmatrix}a&b&c&d\end{pmatrix}\begin{pmatrix}x\\ y\\ z\\t \end{pmatrix}=ax+by+cz+dt}.

La matrice ligne {A} s’identifie donc à la forme linéaire {f} définie sur {\mathbb{K}^{4}} par :{f(x,y,z,t)=ax+by+cz+dt}

Justification du produit matriciel

Considérons deux applications linéaires {f:\mathbb{K}^{n}\to\mathbb{K}^{p}} et {g:\mathbb{K}^{p}\to\mathbb{K}^{q}}.

L’application {h=g\circ f} est linéaire de {\mathbb{K}^{n}} dans {\mathbb{K}^{q}}.

  • à l’application {f} est canoniquement associée une matrice {A} de {\mathcal{M}_{p,n}(\mathbb{K})}.
  • à l’application {g} est canoniquement associée une matrice {B} de {\mathcal{M}_{q,p}(\mathbb{K})}.
  • à l’application {h} est canoniquement associée une matrice {C} de {\mathcal{M}_{q,n}(\mathbb{K})}.

Pour tous {u\in\mathbb{K}^{n}}, {v\in\mathbb{K}^{p}} et {w\in\mathbb{K}^{q}}, on a : {w=h(u)\Leftrightarrow w=g(f(u))}.

Matriciellement, {w=h(u)} s’écrit {W=CU}, et {w=g(f(u))} s’écrit {W=B(AU)}.

Précisément, la définition du produit matriciel est choisie pour qu’on ait l’égalité {BA=C}.

Autrement dit, si on attache aux matrices {A} et {B} deux applications linéaires {f} et {g}, le produit {BA} est la matrice attachée à l’application linéaire {g\circ f}.

On résume ça en imaginant que {\mathbb{K}^{n}\;\begin{matrix}f\\\longrightarrow\\ A\end{matrix}\;\mathbb{K}^{p}\;\begin{matrix}g\\\longrightarrow\\ B\end{matrix}\;\mathbb{K}^{q}} se “contracte” en {\mathbb{K}^{n}\;\begin{matrix}g\circ f\\\longrightarrow\\ BA\end{matrix}\;\mathbb{K}^{q}}.

Prenons un exemple simple, en dimension {2}.

On considère les endomorphismes de {\mathbb{R}^2} définis par : {\begin{cases}f:(x,y)\to(x+y,2x-y)\cr g:(x,y)\to(x+3y,x-y)\end{cases}}

Ils sont attachées aux matrices {A=\begin{pmatrix}1&1\\ 2&-1 \end{pmatrix}} et {B=\begin{pmatrix} 1&3\\ 1&-1\end{pmatrix}}. On a {BA=\begin{pmatrix}7&-2\\-1&2 \end{pmatrix}}.

On vérifie que {g\circ f} est définie par {g\circ f\colon (x,y)\to(7x-2y,-x+2y)}.

Ainsi {g\circ f} est attachée à {C=\begin{pmatrix}7&-2\\-1&2 \end{pmatrix}} et on a bien {C=BA}.

Produits, lignes et colonnes

Dans le calcul du produit {AB} de deux matrices, on met en rapport les lignes de {A} et les colonnes de {B}.
Il est alors commode de se représenter une matrice quelconque sous la forme :

  • de la superposition de {n} matrices-ligne {\text{L}_{1},\text{L}_{2},\ldots,\text{L}_{n}} de même largeur.
  • de la juxtaposition de {p} matrices-colonne {\text{C}_{1},\text{C}_{2},\ldots,\text{C}_{p}} de même hauteur.

On pourra alors noter symboliquement {\left(\begin{array}{cccc}\text{L}_1\\\text{L}_2\\\vdots\\\text{L}_{n}\end{array}\right)\quad\;\text{et}\;\quad \left(\begin{array}{c|c|c|c}\text{C}_{1}&\text{C}_{2}&\cdots&\text{C}_{p}\end{array}\right)}
Le terme d’indice {(i,j)} de {\left(\begin{array}{cccc}\text{L}_1\\\text{L}_2\\\vdots\\\text{L}_{n}\end{array}\right)\left(\begin{array}{c|c|c|c}\text{C}_{1}&\text{C}_{2}&\cdots&\text{C}_{p}\end{array}\right)} est le “produit scalaire” de {\text{L}_{i}} par {\text{C}_{j}}.

Avec Python, on forme ici les matrices {A} dans {\mathcal{M}_{4,5}(\mathbb{R})} et {B} dans {\mathcal{M}_{5,4}(\mathbb{K})}.

>>> A=np.random.randint(-5,5,size=(4,5)); print(A)
[[ 1 -4 -1 -3 4] 
[-1 1 4 4 -5] 
[ 3 -3 -1 -1 1] 
[-1 -1 2 0 1]] 
>>> B=np.random.randint(-5,5,size=(5,4)); print(B)
[[-1 -4 -3 -3] 
[-1 1 1 0] 
[-2 1 -2 -5] 
[ 2 -5 2 2] 
[-1 -5 -3 -3]]

On extrait la ligne d’indice {3} de {A} (attention à la numérotation Python qui commence à {0} : il s’agit donc ici, avec nos notations, de la ligne {\text{L}_{4}}).
On extrait également la colonne d’indice {2} de {B} (donc c’est la troisième colonne!).
On forme ensuite le produit scalaire de cette ligne et de cette colonne.
Le résultat, égal à {-5}, est effectivement le coefficient de position {(3,2)} de {C=AB} (donc c’est {c_{4,3}}!) :

>>> A[3,:]   # quatrième ligne !!!
array([-1, -1, 2, 0, 1])
>>> B[:,2] # troisième colonne !!!
array([-3, 1, -2, 2, -3])
>>> np.vdot(A[3,:],B[:,2])
-5
>>> A.dot(B) # ou np.dot(A,B)
array([[ -5, -14, -23, -16],
[ 5, 14, 19, 6],
[ -1, -16, -15, -9],
[ -3, 0, -5, -10]])

Si {A} est un élément de {\mathcal{M}_{n,p}(\mathbb{K})} et si les {x_{k}} sont scalaires, on peut écrire : {\underbrace{\left(\begin{array}{c|c|c|c}\text{C}_{1}&\text{C}_{2}&\cdots&\text{C}_{p}\end{array}\right)}_{A}\begin{pmatrix}x_{1}\\ x_{2}\\ \vdots \\ x_{p} \end{pmatrix}=<br /> \displaystyle\sum_{j=1}^{p}x_{j}\text{C}_{j}}

De même, on peut écrire :
{\begin{pmatrix}x_{1}&x_{2}&\cdots&x_{n}\end{pmatrix}\underbrace{\left(\begin{array}{cccc}~\qquad&\text{L}_1&~\qquad\\&\text{L}_2&\\&\vdots&\\&\text{L}_{n}&\end{array}\right)}_{A}=\displaystyle\sum_{i=1}^{n}x_{i}L_{i}}

De même, le produit matriciel {MA} peut s’écrire : {M\underbrace{\left(\begin{array}{c|c|c|c}&&&\\\text{C}_{1}&\text{C}_{2}&\cdots&\text{C}_{p}\\&&&\end{array}\right)}_{A}=\left(\begin{array}{c|c|c|c}&&&\\M\text{C}_{1}&M\text{C}_{2}&\cdots&M\text{C}_{p}\\&&&\end{array}\right)}
De même produit matriciel {AN} peut s’écrire
{\underbrace{\left(\begin{array}{cccc}~\qquad&\text{L}_1&~\qquad\\&\text{L}_2&\\&\vdots&\\&\text{L}_{n}&\end{array}\right)}_{A}N=\left(\begin{array}{cccc}~\qquad&\text{L}_1\,N&~\qquad\\&\text{L}_2\,N&\\&\vdots&\\&\text{L}_{n}\,N&\end{array}\right)}
Ces idées peuvent être mises à profit pour optimiser le calcul d’un produit {AB} de deux matrices :

  • si la matrice {A} est “simple”, on privilégiera un calcul de {AB} par lignes.
  • si la matrice {B} est “simple”, on privilégiera un calcul de {AB} par colonnes.

Posons par exemple {A=\begin{pmatrix}a&b&c&d\\a'&b'&c'&d'\\a''&b''&c''&d''\end{pmatrix}} et {B=\begin{pmatrix}1&2&0\\0&1&-1\\1&0&0\\1&0&1\end{pmatrix}}.

On a ici intérêt à effectuer le calcul de {AB} colonne par colonne : {\begin{array}{rl}AB&=\begin{pmatrix}a&b&c&d\\a'&b'&c'&d'\\a''&b''&c''&d''\end{pmatrix}\begin{pmatrix}1&2&0\\0&1&-1\\1&0&0\\1&0&1\end{pmatrix}\\\\&=\left(\begin{array}{c|c|c|c}\text{C}_{1}&\text{C}_{2}&\text{C}_{3}&\text{C}_{4}\end{array}\right)\begin{pmatrix}1&2&0\\0&1&-1\\1&0&0\\1&0&1\end{pmatrix}\\\\&=\left(\begin{array}{c|c|c}\text{C}_{1}+\text{C}_{3}+\text{C}_{4}&2\text{C}_{1}+\text{C}_{2}&-\text{C}_{2}+\text{C}_{4}\end{array}\right)\\\\&=\left(\begin{array}{c|c|c}a+c+d&2a+b&-b+d\\a'+c'+d'&2a'+b'&-b'+d'\\a''+c''+d'&2a''+b''&-b''+d'' \end{array}\right)\end{array} }
De même, on a intérêt à effectuer le produit {BA} ligne par ligne : {\begin{array}{rl}AB&=\begin{pmatrix}1&2&0\\0&1&-1\\1&0&0\\1&0&1\end{pmatrix}\begin{pmatrix}a&b&c&d\\a'&b'&c'&d'\\a''&b''&c''&d''\end{pmatrix}\\\\&=\begin{pmatrix}1&2&0\\0&1&-1\\1&0&0\\1&0&1\end{pmatrix}\left(\begin{array}{c}\text{L}_1\\\text{L}_2\\\text{L}_{3}\end{array}\right)\\\\&=\left(\begin{array}{c}\text{L}_1+2\text{L}_{2}\\\text{L}_2-\text{L}_{3}\\\text{L}_{1}\\\text{L}_1+\text{L}_{3}\end{array}\right)=\left(\begin{array}{cccc}a+2a'&b+2b'&c+2c'&d+2d'\\a'-a''&b'-b''&c'-c''&d'-d''\\a&b&c&d\\a+a''&b+b''&c+c''&d+d''\end{array}\right)\end{array}}

Produits de matrices de la base canonique

Proposition (produits de matrices de la base canonique)
On se donne les ensembles {\mathcal{M}_{n,p}(\mathbb{K})}, {\mathcal{M}_{p,q}(\mathbb{K})} et {\mathcal{M}_{n,q}(\mathbb{K})}, avec {n,p,q} dans {\mathbb{N}^{*}}.
Soit {E_{i,j}} (resp. {E^{\,'}_{j,k}}, {E^{\,''}_{i,k}}) les matrices de la base canonique de {\mathcal{M}_{n,p}(\mathbb{K})} (resp. {\mathcal{M}_{p,q}(\mathbb{K})}, {\mathcal{M}_{n,q}(\mathbb{K})}).
Si {j\ne j'}, alors {E_{i,j}\,E^{\,'}_{j',k}} est la matrice nulle de {\mathcal{M}_{n,q}(\mathbb{K})}.
Si {j'=j}, alors le produit {E_{i,j}\,E_{j,k}^{\,'}} est égal à {E''_{i,k}}.

Plus généralement, quand on effectue le produit {A\,E_{i,j}} le résultat est une matrice nulle à l’exception de sa {j}-ème colonne qui est la copie de la {i}-ème colonne de {A}.

De même {E_{i,j}A} est nulle à l’exception de sa {i}-ème ligne qui est la copie de la {j}-ème ligne de {A}.

Voici un exemple, où on réutilise une fonction E définie précédemment :

>>> print(A)
[[-3 2 0 3 1] 
[ 0 1 -5 -4 4] 
[ 3 2 2 1 -3] 
[-4 3 -1 1 -3] 
[-4 -1 3 0 4]] 
>>> print(A.dot(E(5,5,2,4)))
[[ 0 0 0 2 0] 
[ 0 0 0 1 0] 
[ 0 0 0 2 0] 
[ 0 0 0 3 0] 
[ 0 0 0 -1 0]] 
>>> print(E(5,5,2,4).dot(A))
[[ 0 0 0 0 0] 
[-4 3 -1 1 -3] 
[ 0 0 0 0 0] 
[ 0 0 0 0 0] 
[ 0 0 0 0 0]]

Page précédente : espaces de matrices
Page suivante : calculs sur les matrices carrées