Bonjour,
Dans un but purement académique, j'ai conçu un script LUA qui permet d'évaluer l'intégrale d'une fonction polynomiale entre deux bornes réelles a et b. J'ai eu envie de le partager.
La méthode que j'ai employée est la très connue méthode des trapèzes. Le principe général de mon algorithme est le suivant:
- Suivant un pas, diviser l'intervalle [a-b] et plusieurs sous intervalles.
- Evaluer la surface du trapèze [a-b-f(b)-f(a)] en sommant les sous-surfaces
- Stocker la valeur trouvée et reprendre l'étape 1 avec un pas deux fois plus faible.
- Comparer la nouvelle valeur à la précédente.Si elles sont assez proches, s'arrêter, sinon, reprendre le même calcul en divisant à nouveau le pas par 2.
Cet algorithme fournit d'excellents résultats.Et peut s'implémenter dans n'importe quel language.Avec toutefois une grande possibilité qui fait la particularité dans mon script...La modélisation de la fonction polynomiale.
Imaginez que l'on veuille intégrer f(x) = x^2.
La première idée serait de coder une fonction qui retournerait les valeurs de f pour des valeurs de x, soit
Ensuite employer cette fonction dans l'agorithme général.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function square(x) return x*x end
Si l'on veut ensuite intégrer f(x) = x^3+x^2, il faudrait alors modifier légèrement le script...
J'ai donc voulu aller plus loin en offrant la possiblité pour l'utilisateur d'intégrer n'importe quelle fonction juste en saisissant cette fonction à l'exécution. Pour cela, il m'a fallu passer par une fonction LUA nommée loadstring().
loadstring() retourne une fonction qui, lorsqu'elle est exécutée,traite une chaine de caractères comme s'il s'agissait d'un code LUA.
En utilisant ce principe, on peut exécuter une chaine telle que "x^3+x^2" comme s'il s'agissait de la somme du cube et du carré de la variable x!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 --Ce code affiche 2..Pourtant la commande print(x) est définie comme s'il s'agissait d'une chaine de caractères! x = 2 f = loadstring("print(x)") f()
Voici donc le code source, fait d'une seule fonction et de quelques exemples d'emploi.
Le prototype de la fonction Integral: integral(func,a,b,step,accuracy)
- func : une chaine de caractères représentant la fonction à intégrer
- a, b : des réels correspondant à la borne d'intégration
- step (optionnel): pas d'intégration initial. Par défaut fixé à 0,1
- accuracy: (optionnel) : Critère d'arrêt d'itération de calcul.Représente le niveau de précision.Par défaut fixé à 0,1
Nota: la variable réelle est ici x. Si vous avez une fonction du genre f(z) = z^3, à vous de l'entrer ici sous la forme "x^3". :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 --Computes the requested value function integral(func,a,b,step,accuracy) if a~=b then local p0 = step or 1E-1 local eps = accuracy or 1E-1 local isNeg = (a>b) local s,e = math.min(a,b),math.max(a,b) if p0 > (e-s) then p0 = e-s end p0 = p0*2 local IP,IA = -1,0 repeat IP = IA p0 = p0/2 local n = math.ceil((e-s)/p0) if (s+(n*p0))>e then n = n-1 end IA = 0 local lf,rg local f = assert(loadstring("return " .. func)) for i=0,n-1,1 do x = s+(i*p0) lf = f() x = s+(i+1)*p0 rg = f() IA = IA+((lf+rg)*p0/2) end if isNeg then IA =-IA end until (math.abs(IP-IA)<eps) return 'IA='..IA else return 0 end end --Parameters local func = 'x^3+x^2' --Always Assuming x is the variable local a,b = 0,12 local step = nil local accuracy = nil --Output print('********** Algebra Calculus ***********') print('Function : '..func..' Interval : [ '..a..' - '..b..' ]') print('Result : '..integral(func,a,b,step,accuracy))
Screenshot:
Merci!
Partager