Calcul formel : Mode d'emploi - Exemples en Maple
Claude Gomez, Bruno Salvy, Paul Zimmermann
Masson, 1995
Chapitre V, section 2.5, exercice 1, page 136.
Philippe.Dumas@inria.fr
http://algo.inria.fr/dumas/Maple/
|
|
On peut imaginer deux versions suivant que l'on appelle simplement linalg/det pour calculer les cofacteurs ou que l'on appelle récursivement la procédure que l'on définit pour calculer ces cofacteurs. En Maple V.3, cela donne les deux procédures suivantes. Le cas d'une matrice de taille 1 est traité à part car le développement suivant une colonne n'a alors pas de sens. Dans la version récursive le choix de la colonne utilisée pour un cofacteur est assez arbitraire; le problème est surtout que le choix fasse sens.
> `det wrt a column 1`:=proc(M:matrix(anything,square),j:posint)
local d,k,i;
d:=linalg[coldim](M);
if j>d then ERROR(`index of column`,j,
`larger than upper array bound`,d) fi;
if d=1 then RETURN(M[1,1]) fi;
convert([seq((-1)^(j+k)*M[k,j]*
linalg[det](linalg[submatrix](M,
[seq(i,i=1..k-1),seq(i,i=k+1..d)],
[seq(i,i=1..j-1),seq(i,i=j+1..d)])),k=1..d)],`+`)
end:
> `det wrt a column 2`:=proc(M:matrix(anything,square),j:posint)
local d,k,i;
d:=linalg[coldim](M);
if j>d then ERROR(`index of column`,j,
`larger than upper array bound`,d) fi;
if d=1 then RETURN(M[1,1]) fi;
convert([seq((-1)^(j+k)*M[k,j]*
`det wrt a column 2`(linalg[submatrix](M,
[seq(i,i=1..k-1),seq(i,i=k+1..d)],
[seq(i,i=1..j-1),seq(i,i=j+1..d)]),1+(j-1 mod d)),
k=1..d)],`+`)
end:
On aurait pu employer linalg/delcols et linalg/delrows pour calculer les mineurs.
En Maple V.4, la syntaxe est un peu plus agréable parce qu'on dispose de add.
> `det wrt a column 1`:=proc(M::matrix(square),j::posint)
local d,k;
d:=linalg[coldim](M);
if j>d then ERROR(`index of column`,j,
`larger than upper array bound`,d) fi;
if d=1 then RETURN(M[1,1]) fi;
add((-1)^(j+k)*M[k,j]*
linalg[det](linalg[submatrix](M,
[seq(i,i=1..k-1),seq(i,i=k+1..d)],
[seq(i,i=1..j-1),seq(i,i=j+1..d)])),k=1..d)
end:
> `det wrt a column 2`:=proc(M::matrix(square),j::posint)
local d,k;
d:=linalg[coldim](M);
if j>d then ERROR(`index of column`,j,
`larger than upper array bound`,d) fi;
if d=1 then RETURN(M[1,1]) fi;
add((-1)^(j+k)*M[k,j]*
`det wrt a column 2`(linalg[submatrix](M,
[seq(i,i=1..k-1),seq(i,i=k+1..d)],
[seq(i,i=1..j-1),seq(i,i=j+1..d)]),1+(j-1 mod d)),
k=1..d)
end:
En Maple V.5, on utilise la distinction entre nom et chaîne de caractères dans les messages d'erreur.
> `det wrt a column 1`:=proc(M::matrix(square),j::posint)
local d,k;
d:=linalg[coldim](M);
if j>d then ERROR("index of column",j,
"larger than upper array bound",d) fi;
if d=1 then RETURN(M[1,1]) fi;
add((-1)^(j+k)*M[k,j]*linalg[det](linalg[submatrix](M,
[seq(i,i=1..k-1),seq(i,i=k+1..d)],
[seq(i,i=1..j-1),seq(i,i=j+1..d)])),k=1..d)
end:
> `det wrt a column 2`:=proc(M::matrix(square),j::posint)
local d,k;
d:=linalg[coldim](M);
if j>d then ERROR("index of column",j,
"larger than upper array bound",d) fi;
if d=1 then RETURN(M[1,1]) fi;
add((-1)^(j+k)*M[k,j]*
`det wrt a column 2`(linalg[submatrix](M,
[seq(i,i=1..k-1),seq(i,i=k+1..d)],
[seq(i,i=1..j-1),seq(i,i=j+1..d)]),1+(j-1 mod d)),
k=1..d)
end:
On peut tester ces deux procédures. En Maple V.4 ou V.5 cela donne par exemple ce qui suit.
> d:=4:
> A:=matrix(d,d,a):
> Delta:=linalg[det](A):
> Delta1:=`det wrt a column 1`(A,1);
> Delta2:=`det wrt a column 2`(A,1);
> collect(Delta1-Delta2,a);
> collect(Delta1-Delta,a);
La même séquence fonctionne pour d=6, mais il n'est guère intéressant de contempler le résultat qui comporte sept cent vingt termes.