From: <me...@fr...> - 2008-03-03 15:33:58
Attachments:
computePolygons.mac
|
Bonjour, J'utilise maxima depuis environ une semaine, il est donc fort possible que j'aie commis une erreur. J'ai un programme dans lequel une application de la fonction 'ratsimp' modifie le résultat. La documentation de cette fonction me laissait croire, en tant que simplification, que le résultat devait être égal à l'argument, exprimé différemment, mais c'est peut-être là que je commets une erreur. Plus en détails je génère un ensemble de droites, par paires parallèles. Je génère ensuite l'ensemble des points d'intersection de ces droites, et je cherche ensuite l'ensemble des points qui sont situés entre les deux droites de chaque paire parallèle. A la base, en fait, j'ai un domaine dont je veux calculer l'aire. Il est défini par un ensemble d'équations (0<=ax + by + c <=1). S'il existe une solution plus imple je suis preneur aussi. Une droite correspondant à l'équation (ax+by+c=0) est codée par ([a,b,c]). Le programme d'intersection de deux droites est intersectDroite(droite1,droite2):= block([result,det,a1,b1,c1,a2,b2,c2], [a1,b1,c1] : droite1, [a2,b2,c2] : droite2, det : a2*b1-a1*b2, if det=0 then return([]) else return([(b2*c1-b1*c2)/det,(a1*c2-a2*c1)/det]) ); Si à la place de la dernière ligne je mets return(ratsimp([(b2*c1-b1*c2)/det,(a1*c2-a2*c1)/det])), le résultat de l'algorithme sera différent. Je vous donne également le détail du calcul ensuite, et je vous joints le fichier .mac Ensuite je réalise l'algo suivant : genIntersectPoints(droites) := block([copydroites,mypoints,tag], copydroites:copylist(droites), /* generation de l'ensemble des points d'intersections, le listify(setify()) est le mieux que j'aie trouvé pour retirer les doublons. Le 1 à la fin des coordonnées du point sert à faire un produit scalaire avec le vecteur de la droite pour calculer le positionnement du point par rapport à la droite */ mypoints:listify(setify(create_list(endcons(1,intersectDroite(d1,d2)),d1,droites,d2,copydroites : rest(copydroites,1)))), /*suppression des solutions invalides, lorsqu'on a intersecté des droites parallèles*/ mypoints : delete([1],mypoints), /*les droites sont dans un ordre qui fait qu'alternativement, on cherche un point tel que p.d <= 0 puis p.d >= 0*/ tag:false, for d in droites do block([tmpoints], tmpoints:[], for p in mypoints do block([test], test : p.d, if tag then test : -test, if test>=0 then tmpoints : cons(p,tmpoints) ), mypoints : copylist(tmpoints), tag : not tag ), mypoints : create_list([p[1],p[2]],p,mypoints), return(mypoints) ); Le retour de cette fonction me donne 5 points, les bons, sans ratsimp, et moins de points lorsque j'utilise ratsimp. merci de votre attention et désolé d'avance si le problème vient de mon novisme. Cordialement, Vincent Nivoliers |
From: laurent c. <l.c...@gm...> - 2008-03-03 17:50:56
|
Je suppose que certain doublons ne sont pas identifié par le listify(setify()) Si les expressions ne sont pas simplifiées. Vous pouvez certainement le vérifié en faisant la différence des solutions avec et sans ratsimp() Quand à une méthode plus simple pour obtenir le même résultat, j'avoue que je n'ai pas très bien compris ce que vous cherchiez à faire. En tous les cas vous pourriez utiliser la fonction solve pour rechercher l'intersection de 2 droite. intersectDroite(droite1,droite2):=solve([equationDroite(droite1),equationDroite(droite2)],[x,y] )$ Laurent > -----Message d'origine----- > De : max...@li... [mailto:maxima-lang-fr- > bo...@li...] De la part de me...@fr... > Envoyé : lundi 3 mars 2008 16:33 > À : max...@li... > Objet : [Maxima-lang-fr] Résultats différents lors de l'utilisation de ratsimp > > > > Bonjour, > J'utilise maxima depuis environ une semaine, il est donc fort possible que > j'aie commis une erreur. J'ai un programme dans lequel une application de la > fonction 'ratsimp' modifie le résultat. La documentation de cette fonction me > laissait croire, en tant que simplification, que le résultat devait être égal à > l'argument, exprimé différemment, mais c'est peut-être là que je commets une > erreur. > > Plus en détails je génère un ensemble de droites, par paires parallèles. Je > génère ensuite l'ensemble des points d'intersection de ces droites, et je > cherche ensuite l'ensemble des points qui sont situés entre les deux droites de > chaque paire parallèle. A la base, en fait, j'ai un domaine dont je veux > calculer l'aire. Il est défini par un ensemble d'équations (0<=ax + by + c <=1). > S'il existe une solution plus imple je suis preneur aussi. > > Une droite correspondant à l'équation (ax+by+c=0) est codée par ([a,b,c]). > Le programme d'intersection de deux droites est > > intersectDroite(droite1,droite2):= > block([result,det,a1,b1,c1,a2,b2,c2], > [a1,b1,c1] : droite1, > [a2,b2,c2] : droite2, > det : a2*b1-a1*b2, > if det=0 > then return([]) > else return([(b2*c1-b1*c2)/det,(a1*c2-a2*c1)/det]) > ); > > Si à la place de la dernière ligne je mets > return(ratsimp([(b2*c1-b1*c2)/det,(a1*c2-a2*c1)/det])), le résultat de > l'algorithme sera différent. Je vous donne également le détail du calcul > ensuite, et je vous joints le fichier .mac > > Ensuite je réalise l'algo suivant : > > genIntersectPoints(droites) := > block([copydroites,mypoints,tag], > copydroites:copylist(droites), > > /* generation de l'ensemble des points d'intersections, le listify(setify()) est > le mieux que j'aie trouvé pour retirer les doublons. Le 1 à la fin des > coordonnées du point sert à faire un produit scalaire avec le vecteur de la > droite pour calculer le positionnement du point par rapport à la droite */ > > mypoints:listify(setify(create_list(endcons(1,intersectDroite(d1,d2)),d1,droites,d2,copydroit > es > : rest(copydroites,1)))), > /*suppression des solutions invalides, lorsqu'on a intersecté des droites > parallèles*/ > mypoints : delete([1],mypoints), > > /*les droites sont dans un ordre qui fait qu'alternativement, on cherche un > point tel que p.d <= 0 puis p.d >= 0*/ > tag:false, > > for d in droites do > block([tmpoints], > tmpoints:[], > for p in mypoints do > block([test], > test : p.d, > if tag then test : -test, > if test>=0 > then > tmpoints : cons(p,tmpoints) > ), > mypoints : copylist(tmpoints), > tag : not tag > ), > > mypoints : create_list([p[1],p[2]],p,mypoints), > return(mypoints) > ); > > Le retour de cette fonction me donne 5 points, les bons, sans ratsimp, et moins > de points lorsque j'utilise ratsimp. > > merci de votre attention et désolé d'avance si le problème vient de mon novisme. > Cordialement, > Vincent Nivoliers |
From: Vincent N. <me...@fr...> - 2008-03-03 18:46:50
|
Merci de votre réponse rapide laurent couraud wrote: > Je suppose que certain doublons ne sont pas identifié par le listify(setify()) > Si les expressions ne sont pas simplifiées. > J'ai en effet peut-être des doublons, mais ce qui est étrange, c'est plus loin que le problème se situe. En fait, dans la boucle for ensuite, je prends les droites une à une, et je supprime les points qui sont du mauvais côté de la droite. L'algo sans le ratsimp me donne le bon résultat, avec le bon nombre de points, et aucun doublons, alors que lorsque je mets le ratsimp, j'ai des points qui sont supprimés alors qu'ils ne le devraient pas. > Vous pouvez certainement le vérifié en faisant la différence des solutions > avec et sans ratsimp() > J'essaierai, merci du conseil > Quand à une méthode plus simple pour obtenir le même résultat, j'avoue que je n'ai > pas très bien compris ce que vous cherchiez à faire. > En entrée, j'ai un domaine défini par des inéquations du type 0 <= ax+by+c <= 1, je cherche à calculer le polygone correspondant à la zone où x et y vérifient l'ensemble de ces inéquations. > En tous les cas vous pourriez utiliser la fonction solve pour rechercher l'intersection de 2 > droite. > > intersectDroite(droite1,droite2):=solve([equationDroite(droite1),equationDroite(droite2)],[x,y] > )$ > C'est ce que je faisais au début, mais il me donnait en résultat une liste de la forme [x=truc,y=machin], et il me fallait [truc,machin], donc je devait rajouter map(rhs,la_solution), et de plus, pour gérer les droites parallèles, je devais faire en sorte de supprimer l'erreur pour les équations inconsistantes. Au final, le programme se révélait plus court de cette façon... Merci beaucoup pour vos conseils, en tout cas Vincent |