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

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
function square(x)
return x*x
end
Ensuite employer cette fonction dans l'agorithme général.
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.

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()
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!

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!