Je suis d'accord avec tes objections, cependant même en Eiffel on est parfois astreints à des impératifs d'efficacité. Ton code présente bien l'utilisation des assertions mais avec un mauvais exemple.
D'abord la vérification de la non singularité de la matrice par le calcul de son déterminant, ou par la méthode de Gauss implique un volume de calcul du même ordre que l'inversion proprement dite.
La postcondition souffre de quelques lacunes aussi. Déjà avec un x: DOUBLE différent de zéro, x * 1/x = 1 n'est pas toujours vrai. Il va donc plutôt falloir trouver un autre critère comme, par exemple, calculer la norme de la différence entre le produit de la matrice par son inverse et l'identité, et vérifier qu'elle est inférieure à une certaine tolérance.
je propose donc le code suivant comme exemple amélioré (à ne pas considérer comme étant taillé dans le bronze) :
inverse: MATRICE is
require
is_square -- on ne traite pas les pseudo inverses
local
already_tried: BOOLEAN
do
if already_tried then
-- Result := Void ceci est un commentaire
else
--code de tentative d'inversion de la matrice
end
ensure
Current = Void or else (Current * Result).distance (identity) < epsilon -- epsilon attribut de la classe
rescue
already_tried := True
retry
end
En procédant de cette manière on va obtenir une approximation de l'inverse de la matrice si la matrice n'est pas singulière et que le code le permet et un objet vide dans les autres cas. L'avantage c'est que si la matrice n'est pas inversible dans le sens de la routine (ce qui ne veut pas dire qu'elle ne l'est pas mathématiquement), l'objet retourné sera vide, ce qui décharge le client de lourdes vérifications.
Un exemple est donné, tourné autrement, dans Conception et programmation orientées objet de Bertrand Meyer, pages 771 et 772.
[^] # Re: Quelques "coquilles"
Posté par Philip Marlowe . En réponse à la dépêche Sortie de Hercule la version 2 du compilateur SmartEiffel. Évalué à 0.
D'abord la vérification de la non singularité de la matrice par le calcul de son déterminant, ou par la méthode de Gauss implique un volume de calcul du même ordre que l'inversion proprement dite.
La postcondition souffre de quelques lacunes aussi. Déjà avec un x: DOUBLE différent de zéro, x * 1/x = 1 n'est pas toujours vrai. Il va donc plutôt falloir trouver un autre critère comme, par exemple, calculer la norme de la différence entre le produit de la matrice par son inverse et l'identité, et vérifier qu'elle est inférieure à une certaine tolérance.
je propose donc le code suivant comme exemple amélioré (à ne pas considérer comme étant taillé dans le bronze) :
inverse: MATRICE is
require
is_square -- on ne traite pas les pseudo inverses
local
already_tried: BOOLEAN
do
if already_tried then
-- Result := Void ceci est un commentaire
else
--code de tentative d'inversion de la matrice
end
ensure
Current = Void or else (Current * Result).distance (identity) < epsilon -- epsilon attribut de la classe
rescue
already_tried := True
endretry
En procédant de cette manière on va obtenir une approximation de l'inverse de la matrice si la matrice n'est pas singulière et que le code le permet et un objet vide dans les autres cas. L'avantage c'est que si la matrice n'est pas inversible dans le sens de la routine (ce qui ne veut pas dire qu'elle ne l'est pas mathématiquement), l'objet retourné sera vide, ce qui décharge le client de lourdes vérifications.
Un exemple est donné, tourné autrement, dans Conception et programmation orientées objet de Bertrand Meyer, pages 771 et 772.