Page 1 sur 1

Manque de fonction mathématique,en particulier exponentielle

Publié : sam. 03/sept./2005 17:38
par barnierchristophe
:cry: Personnellement, je trouve le jeu de fonction mathématique trop réduit. Il serait bien d'avoir au moins les fonctions de base d'une petite calculette scientifique. Je sais que ce n'était pas le but premier de PureBasic, Mais ça, c'est la rançon du succès.
:?: Pour ma part, il me manque surtout la fonction exponentielle. :idea:

Publié : sam. 03/sept./2005 18:10
par Dr. Dri
en attendant amuse toi avec ca ;)

Code : Tout sélectionner

Procedure.f Exp(x.f)
  Protected i.f, t.f, e.f
  e = 1.0
  t = 1.0
  While t
    i + 1.0
    t * (x / i)
    e + t
  Wend
  ProcedureReturn e
EndProcedure

Debug Exp(1)
Dri 8)

Publié : sam. 03/sept./2005 19:31
par Dr. Dri
encore un peu 8) cette fois on peut même vérifier ^^

Code : Tout sélectionner

#MinFloat = 0.00000001

Procedure.f Exp(x.f)
  Protected i.f, t.f, e.f
  e = 1.0
  t = 1.0
  While Abs(t) > #MinFloat
    i + 1.0
    t * (x / i)
    e + t
  Wend
  ProcedureReturn e
EndProcedure

Procedure.f Ln(x.f)
  Protected i.f, xx.f, t.f, ln.f
  If x > 0.0
    
    If x > 1.0
      ln = -Ln(1.0 / x)
    ElseIf x < 1.0
      t  =  1.0
      xx = -1.0
      x  -  1.0
      While Abs(t) > #MinFloat
        xx * -x
        i  + 1.0
        t  = xx / i
        ln + t
      Wend
    EndIf
    
  ElseIf x = 0.0
    ln = (-1.0 / x)
  Else ;x négatif
    x  = 0.0
    ln = (0.0 / x)
  EndIf
  ProcedureReturn ln
EndProcedure

Debug Log(-1.0)
Debug Log(0.0)
Debug Log(0.5)
Debug Log(1.0)
Debug Log(2.0)

Debug "------"

Debug Ln(-1.0)
Debug Ln(0.0)
Debug Ln(0.5)
Debug Ln(1.0)
Debug Ln(2.0)
Dri ;)

Publié : sam. 03/sept./2005 19:36
par Dr. Dri
bon une dernière ^^

Code : Tout sélectionner

Procedure.f Puissance(x.f, y.f)
  ProcedureReturn Exp(y*Ln(x))
EndProcedure

Debug Pow      (9.3, 5.2)
Debug Puissance(9.3, 5.2)
Dri :lol:

Publié : dim. 04/sept./2005 0:40
par barnierchristophe
8) Merci vieux, ça marche impec. :lol:

Publié : dim. 04/sept./2005 22:29
par barnierchristophe
Je me suis un peu avancé:
ça donne parfois des temps de calcul trop longs ( vers les valeurs négatives) et puis aussi des erreurs.

par contre, ta vérification avec la fonction pow(x,y) du PureBasic m'a donné une idée : puisque l'on peut déduire la fonction puissance de exp, on peut aussi déduire exp de la fonction puissance

pow(x,y)=exp(y*ln(x))-->exp(y)=pow(e,y) où e est l'exponentielle de 1
( car ln(e)=1 )

d'où la petite procédure :

#e=2.71828183 ;exponentielle de 1

Procedure.f Exp(x.f)
Protected e.f
e=Pow(#e,x)
ProcedureReturn e
EndProcedure

C'est plus précis, et plus rapide.
En tout cas merci de ton aide et à la revoyure.
:roll:

Publié : lun. 05/sept./2005 6:45
par Dr. Dri
Ah bah au moins j'ai pas donné de la confiture à un cochon :D
ce que j'ai codé s'appelle un développement limité, une approximation d'une fonction par un polynome... La plupart des formules qu'on peut trouver sont vraies pour x proche de zéro...

si la fonction est trop lente pour x < 0 tu peux toujours la modifier pour qu'elle renvoie 1 / Exp(-x) je crois...

j'obtiens bien plus de précision en C pour deux raisons...
  • J'utilise des nombres réels double précision
  • Ma Constante #Precision peut s'approcher bien plus de zéro
Dri ;)

Publié : lun. 12/sept./2005 22:05
par fweil
@Dr Dri,

Ton code est très bon en fait pour la manière de simplifier le calcul de factorielle dans el développement en série limitée.

J'ajoute juste une petite retouche pour accélérer le retour de valeur dans le cadre des flottants 32 bits :

Code : Tout sélectionner

Procedure.f Exp(x.f, Precision.l)
i.f
t.f
e.f
  e = 1.0
  t = 1.0
  While t And Precision => 0
    Precision - 1
    i + 1.0
    t * (x / i)
    e + t
    Debug StrF(i, 20) + " " + StrF(t, 20) + " " + StrF(e, 20)
  Wend
  ProcedureReturn e
EndProcedure

Debug StrF(Exp(1, Precision = 10), 20)
En fait une grande partie des soucis de précision dans les flottants vient précisément du manque de précision de la fonction StrF(). Si on regarde de bien près les flottants en eux-mêmes les 32 bits sont déjà assez bons, même si les 64 ou les 80 sont mieux.

Mais le rendu du résultat sous forme de chaine est assez pauvre et l'affectation d'une valeur aussi (limitation du nombre de décimales moins bon que ce que permet le format binaire).

Mais bon, là c'est juste pour jouer, et finalement ce n'est pas tellement grave. J'ai toujours rêvé de pouvoir modéliser l'univers su mon PC, mais je n'ai pas assez de mémoire (enfin moi si, mais pas mon PC).

mdr

Publié : mar. 13/sept./2005 11:10
par Dr. Dri
fweil a écrit :@Dr Dri,
Mais le rendu du résultat sous forme de chaine est assez pauvre et l'affectation d'une valeur aussi (limitation du nombre de décimales moins bon que ce que permet le format binaire).
C'est assez vexant d'ailleurs d'avoir un overflow quand ca n'est pas le cas...

Pour les réels à double précision (64bits) on les attends toujours en PB (autant que les entiers de 64bits d'ailleurs)

Code : Tout sélectionner

double.d
int_64.q
Dri :(