Calcul formel : Mode d'emploi - Exemples en Maple
Claude Gomez, Bruno Salvy, Paul Zimmermann
Masson, 1995
Chapitre V, section 3.4, exercice 1, page 142.
Philippe.Dumas@inria.fr
http://algo.inria.fr/dumas/Maple/
|
|
Nous définissons la procédure coplanar qui répond à la question. Cette procédure commence par vérifier qu'elle reçoit bien (au moins) quatre arguments. Comme les vecteurs peuvent être représentés aussi bien par des listes que des vecteurs (au sens Maple) une éventuelle conversion est appliquée. Si jamais les arguments ne sont ni des listes ni des vecteurs, la procédure renvoie une erreur. Notez que la correction des données n'est pas totalement vérifiée. Par exemple il se pourrait que les vecteurs n'aient pas tous la même taille mais cela provoquerait une erreur plus loin. Si les points sont P1, P2, P3, P4, les vecteurs V1=P1-P4, V2=P2-P4, V3=P3-P4 sont calculés. Ceci détruit la symétrie du problème, mais l'énoncé ne nous pousse pas à faire mieux. Enfin le déterminant des trois vecteurs est calculé ; s'il est nul la procédure renvoie vrai et sinon faux. Nous allons revenir sur l'emploi de userinfo et sur l'emploi de Normalizer. En Maple V.3, il convient d'écrire linalg[vector] au lieu de vector à la ligne marquée d'un dièse. En Maple V.4, nous employons les noms P1, P2 ... V3 et non P[1], P[2] ... V[3] à cause d'une faiblesse de linalg/augment sur les noms indexés.
> coplanar:=proc()
local i,P,V,Delta;
if nargs<4 then
ERROR(`expected 4 arguments, but received`,args)
fi;
for i to 4 do
if type(args[i],list) then P[i]:=vector(args[i]) #
elif type(args[i],vector) then P[i]:=args[i]
else ERROR(`expected its`,i,`th argument to be a list or a
vector but received`,args)
fi
od;
for i to 3 do V[i]:=evalm(P[i]-P[4]) od;
Delta:=linalg[det](linalg[augment](V[1],V[2],V[3]));
userinfo(2,`coplanar`,Normalizer(Delta));
evalb(Normalizer(Delta)=0)
end:
Testons la procédure.
> a:=[1,2,3]:
b:=[-1,2,3]:
c:=[0,1,1]:
d:=evalm((2*a+b-c)/2):
> coplanar(a,b,c,d);
Les quatre points sont coplanaires puisque le quatrième est barycentre des trois premiers. Reprenons la même idée mais avec des poids formels.
> a:=[1,2,3]:
b:=[-1,2,3]:
c:=[0,3,1]:
d:=evalm((x*a+y*b+z*c)/(x+y+z)):
> coplanar(a,b,c,d);
Continuons sur la même idée.
> a:=[1,2,3]:
b:=[-1,2,3]:
c:=[0,3,1]:
d:=evalm((cos(theta)^2*a+sin(theta)^2*b)):
> coplanar(a,b,c,d);
Ici le résultat est incorrect parce que la nullité du déterminant n'a pas été reconnue. Effectivement si le déterminant est vu comme 0, alors il est vraiment nul, le résultat renvoyé est true et ce résultat est correct. Par contre il se pourrait que le déterminant soit nul mais que le système ne le voit pas ; le résultat renvoyé est alors false, mais ce résultat n'est pas garanti. Illustrons mieux la situation, en employant infolevel et le userinfo que nous avons inclus dans la procédure. Cela va nous permettre d'afficher la valeur du déterminant calculée par le système.
> infolevel[coplanar]:=2:
> coplanar(a,b,c,d);
coplanar: -14+14*cos(theta)^2+14*sin(theta)^2
Nous voyons bien que le système n'a pas reconnu 0. La procédure Normalizer que nous avons incluse dans la procédure va maintenant nous servir. Par défaut, Normalizer vaut normal et c'est pourquoi les calculs avaient fonctionné correctement jusqu'ici. Comme le dernier exemple emploie des fonctions trigonométriques, nous affectons à Normalizer la procédure combine/trig ; en effet un polynôme trigonométrique nul écrit sous forme linéarisée se réduit à 0.
> Normalizer:=readlib(`combine/trig`);
> coplanar(a,b,c,d);
coplanar: 0
Ainsi le résultat est correct.
La question auxilaire peut se traiter comme suit.
> a:=[a1,a2,a3]:
b:=[b1,b2,b3]:
c:=[c1,c2,c3]:
d:=[0,0,0]:
> coplanar(a,b,c,d);
coplanar: a1*b2*c3-a1*c2*b3-a2*b1*c3+a2*c1*b3+a3*b1*c2-a3*c1*b2
> expand(linalg[dotprod](linalg[crossprod](a,b),c));
On notera que le calcul de déterminant n'utilise pas particulièrement le fait que la dimension soit 3. Le raisonnement fonctionnerait tout aussi bien pour n+1 points dans un espace de dimension n. Par contre la dernière question se réfère explicitement à un espace euclidien orienté de dimension 3.