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/

Page du Projet Algorithmes | Page de Philippe Dumas | Page Maple de Philippe Dumas

Retour en page principale
Table des matières
Index
Maple V.4 worksheet
Maple V.5 worksheet


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);

[Maple Math]

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);

[Maple Math]

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);

[Maple Math]

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

[Maple Math]

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`);

[Maple Math]

> coplanar(a,b,c,d);

coplanar: 0

[Maple Math]

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

[Maple Math]

> expand(linalg[dotprod](linalg[crossprod](a,b),c));

[Maple Math]

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.

Retour en page principale