Page 1 sur 1

rref gaussjord

Publié : lun. mars 16, 2009 6:21 pm
par mitch
Bonjour, j'ai l'impression qu il'y a des approximations qui sont faites lors de la resolution de matrices par Gauss-Jordan:
Voici le code suivant:

Code : Tout sélectionner

int main(){
  gen res;
  gen g1(string("[[1+7e-16*s,1-7e-16*s,0],[1,0,1]]"),0);
  cout << _rref(g1,0) << endl;
  gen g2(string("[[a1*s+b1,c1-a1*s,0],[1,0,1]]"),0);                                                                                                                                      
  cout << _rref(g2,0) << endl;
  return(0);
}
and here is the result :

Code : Tout sélectionner

[[1.0,-0.0,1.0],[-0.0,1.0,-1]]
[[1,0,1],[0,1,(a1*s+b1)/(a1*s-c1)]]
We can see that I just substituted
a1 by 7e-16
b1 by 1
c1 by 1

But the result is not (7e-16*s+1)/(7e-16-1)
I think an approximation is done :
7e-16+1 ~1
7e-16-1 ~-1
That's why the result is -1
How to avoid that approximation ?
[/list]

Publié : mar. mars 17, 2009 7:41 am
par parisse
Des l'instant ou vos coefficients sont approches (1e-16 par exemple), les calculs se font avec la precision des coefficients, par defaut c'est 53 bits de precision relative avec giac-0.8.2, et 45 avec giac-0.9.0.
De plus, giac utilise la variable epsilon(context *) pour decider de la nullite d'une expression approchee.
Enfin, si vous travaillez avec des variables symboliques, je vous deconseille de melanger avec des valeurs approchees, car giac n'implemente pas pour l'instant de routines de calcul de PGCD, donc les simplifications ne fonctionneront pas (sauf coup de chance).
Je vous conseille donc d'utiliser des valeurs exactes: par exemple 1e-16 -> 10^(-16). Vous pouvez transformer une expression approchee en une expression exacte proche avec la fonction
gen exact(const gen & g,GIAC_CONTEXT);

Publié : mar. mars 17, 2009 11:21 am
par mitch
Tiens ! je suis passé en anglais au milieu de ma question ...
Alors j'ai eu un élément de réponse :
Je pensais que 7e-16 et 7*10^(-16) étaient identiques, alors que ca n'a pas l'air d'etre le cas
Et effectivement, en écrivant :

Code : Tout sélectionner

gen g1(string("[[1+7*10^(-16)*s,1-7*10^(-16)*s,0],[1,0,1]]"),0);
Le résultat retourné est :

[[1,0,1],[0,1,(7000000*s+10000000000000000)/(7*s-10000000000000000)]]

ce qui me plais bien plus