Manque de fonction mathématique,en particulier exponentielle

Vous avez une idée pour améliorer ou modifier PureBasic ? N'hésitez pas à la proposer.
barnierchristophe
Messages : 64
Inscription : lun. 07/févr./2005 11:18

Manque de fonction mathématique,en particulier exponentielle

Message 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:
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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:
barnierchristophe
Messages : 64
Inscription : lun. 07/févr./2005 11:18

Message par barnierchristophe »

8) Merci vieux, ça marche impec. :lol:
barnierchristophe
Messages : 64
Inscription : lun. 07/févr./2005 11:18

Message 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:
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message 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
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 :(
Répondre