La première version que j'ai proposée utilise en effet un schéma a priori (on teste l'inversibilité avant), simple et clair. Je pense que cette version est correcte si le calcul d'inversion utilise le calcul du déterminant (par exemple avec A-1 = 1/det A * "transposée de la matrice des cofacteurs")
Maintenant, si l'inversion n'utilise pas le déterminant (méthode de Gauss), l'inversibilité est découverte en cours de calcul. Un schéma a priori est alors effectivement dans ce cas plus indiqué (mais en général, le schéma a priori est plus propre). Le principe est le suivant : on tente l'inversion, et on positionne un drapeau selon la réussite ou l'échec de l'inversion. Le test se fait alors après la tentative.
tente_d_inverser isrequire
is_square -- on ne traite pas les pseudo inversesdo -- code qui permet d'inverser la matrice
-- si l'inversion est possible, inversion_reussie vaut True et inverse contient la matrice inverse
-- si l'inversion n'est pas possible, inversion_reussie vaut False et inverse vaut Voidensurenot inversion_reussie or else (Current * inverse).distance (identity) < epsilon -- epsilon attribut de la classeend
inversion_reussie : BOOLEAN
inverse : MATRICE
invariant
inversion_reussie = (inverse /= Void)
Pour utiliser ce code, on ferait :
...
m.tente_d_inverser
if m.inversion_reussie then
x := m.inverse
...
else
... traitement de l'erreur ...
end
...
Remarques :
je préfère ne pas utiliser de rescue, car il n'y a pas d'erreur imprévisible;
on pourrait effectivement ajouter already_tried pour éviter de tenter d'inverser deux fois, mais il faudrait alors mettre à jour ce drapeau dès que l'on modifie une valeur de la matrice (mais le problème est différent);
d'accord pour la post-condition qui spécifie que l'on a une matrice inversée, mais, ceci dit, mon égalité entre deux matrices (avec le signe =) pourrait être calculée comme toi en utilisant une distance et un epsilon.
PT : j'espère que la discussion n'est pas trop technique et que tout le monde peut suivre.
[^] # Re: Quelques "coquilles"
Posté par Guillaume Vauvert . En réponse à la dépêche Sortie de Hercule la version 2 du compilateur SmartEiffel. Évalué à 1.
- je préfère ne pas utiliser de rescue, car il n'y a pas d'erreur imprévisible;
- on pourrait effectivement ajouter already_tried pour éviter de tenter d'inverser deux fois, mais il faudrait alors mettre à jour ce drapeau dès que l'on modifie une valeur de la matrice (mais le problème est différent);
- d'accord pour la post-condition qui spécifie que l'on a une matrice inversée, mais, ceci dit, mon égalité entre deux matrices (avec le signe =) pourrait être calculée comme toi en utilisant une distance et un epsilon.
PT : j'espère que la discussion n'est pas trop technique et que tout le monde peut suivre.