Calcul formel : Mode d'emploi - Exemples en Maple
Claude Gomez, Bruno Salvy, Paul Zimmermann
Masson, 1995
Chapitre V, section 1.4, exercice 1, page 125.
Philippe.Dumas@inria.fr
http://algo.inria.fr/dumas/Maple/
|
|
Exécutons les instructions demandées en supposant que nous utilisons la version V.3.
> l:=[1,2,3];
> v:=linalg[vector]([1,2,3]);
Pour la matrice, nous pouvons employer au choix l'une des deux syntaxes suivantes.
> m:=array(1..3,1..1,[[1],[2],[3]]);
> m:=linalg[matrix](3,1,[[1],[2],[3]]);
À partir de V.4, vector et matrix sont directement disponibles.
> v:=vector([1,2,3]);
> m:=matrix(3,1,[[1],[2],[3]]);
Regardons la structure des objets créés.
> op(0,l),op(l);
Le premier est bien sûr de type list. Le second est un tableau et on n'accède pas aux opérandes de la même façon que pour les autres objets.
> op(0,eval(v)),op(eval(v));
Error, improper op or subscript selector
> whattype(eval(v));
> [op(1,eval(v))],[op(2,eval(v))],[op(3,eval(v))];
Nous avons employé des crochets pour mettre en valeur le fait que la première opérande est la séquence vide. Pour le reste nous voyons qu'un objet de type vector n'est rien d'autre qu'un tableau à un indice. Ceci explique le fait qu'il soit affiché horizontalement.
> op(0,eval(m)),op(eval(m));
Error, improper op or subscript selector
> [op(1,eval(m))],[op(2,eval(m))],[op(3,eval(m))];
On note que les tableaux ne sont que des tables d'un type particulier.
Revenons sur le type vector et sur l'affichage des objets de type vector. Cet affichage est un peu troublant puisqu'un vecteur que l'on pense usuellement comme une colonne est représenté sur une ligne. Pour ne pas mélanger les vecteurs colonnes et les vecteurs lignes, la procédure transpose est quasiment inerte sur ces objets.
> w:=linalg[transpose](eval(v));
> op(0,eval(w)),op(eval(w));
Du coup on ne peut pas confondre un vecteur et son transposé.
> evalm(v-w);
Error, (in linalg[add]) matrix dimensions incompatible
Cependant il convient de signaler que linalg/row et linalg/col renvoient tous les deux des objets de type vector. La distinction entre ligne et colonne est alors perdue.
> A:=array(1..3,1..3,[seq([seq(i+j-1,j=1..3)],i=1..3)]);
> L:=linalg[row](A,2);
> C:=linalg[col](A,2);
> evalm(L-C);
Ce point peut paraître anodin, mais est source d'erreur si l'on n'y prend pas garde. Supposons par exemple que nous ayons une matrice carrée A de taille n et que nous désirions former la matrice carrée Li Cj produit de la ligne d'indice i de A et de la colonne d'indice j de A. La ligne Li est une matrice de type (1,n) et la colonne Cj est de type (n,1). On peut donc les multiplier et leur produit Li Cj est de type (n,n). Une syntaxe naturelle pour effectuer cette opération est
> evalm(linalg[row](A,i) &* linalg[col](A,j)); # wrong
mais ceci provoque une erreur parce que nous essayons de multiplier une matrice de type (n,1) par une matrice de type (n,1). Il convient donc d'écrire
> evalm(linalg[transpose](linalg[row](A,i)) &* linalg[col](A,j)); # right
La procédure submatrix n'a pas cet inconvénient.