Initiation au Lua avec Scribunto/Fonctions mathématiques
Nous allons, dans ce chapitre, étudier quelques fonctions préprogrammées dans le domaine des mathématiques. Comme dans le chapitre précédent, nous ne rangerons pas les fonctions dans l’ordre alphabétique, mais nous essaierons de classer les fonctions de la plus simple à la plus compliqué ou de la plus utile à la moins utile.
Tous les exemples de ce chapitre seront rangés dans le Module:Maths.
Fonctions simples
[modifier | modifier le wikicode]Nous avons pas mal de fonctions mathématiques à étudier. Pour simplifier l'étude nous allons étudier, dans ce paragraphe, en même temps, toutes les fonctions mathématiques classiques qui acceptent en entrée un nombre réel quelconque et qui retourne un seul nombre réel. Ce sont les fonctions :
- math.abs ; Retourne la valeur absolue d'un nombre réel.
- math.exp ; Retourne l'exponentielle d'un nombre réel.
- math.cos ; Retourne le cosinus d'un nombre réel.
- math.sin ; Retourne le sinus d'un nombre réel.
- math.cosh ; Retourne le cosinus hyperbolique d'un nombre réel.
- math.sinh ; Retourne le sinus hyperbolique d'un nombre réel.
- math.tanh ; Retourne la tangente hyperbolique d'un nombre réel.
- math.atan ; Retourne l'arc tangente d'un nombre réel.
- math.deg ; Traduit en degré, un nombre donné en radian.
- math.rad ; Traduit en radian, un nombre donné en degré.
- math.ceil ; Retourne le plus petit entier supérieur ou égal à un nombre réel donné.
- math.floor ; Retourne le plus grand entier inférieur ou égal à un nombre réel donné.
Pour tester toutes ces fonctions, nous allons écrire une fonction diverse qui accepte un nombre réel en argument et qui nous retourne l'image de ce nombre réel par toutes les fonctions précédentes :
local p = {}
function p.diverse(frame)
local x = tonumber(frame.args[1])
local reponse = " "
reponse = reponse.."<br>La valeur absolu est "..math.abs(x)
reponse = reponse.."<br>L'exponentielle est "..math.exp(x)
reponse = reponse.."<br>Le cosinus est "..math.cos(x)
reponse = reponse.."<br>Le sinus est "..math.sin(x)
reponse = reponse.."<br>Le cosinus hyperbolique est "..math.cosh(x)
reponse = reponse.."<br>Le sinus hyperbolique est "..math.sinh(x)
reponse = reponse.."<br>La tangente hyperbolique est "..math.tanh(x)
reponse = reponse.."<br>L'arc tangente est "..math.atan(x)
reponse = reponse.."<br>La conversion en degrés est "..math.deg(x)
reponse = reponse.."<br>La conversion en radian est "..math.rad(x)
reponse = reponse.."<br>L'entier immédiatement supérieur est "..math.ceil(x)
reponse = reponse.."<br>L'entier immédiatement inférieur est "..math.floor(x)
return reponse
end
return p
{{#invoke:Maths|diverse|5.2713}} nous indique :
La valeur absolu est 5.2713
L'exponentielle est 194.66886754927
Le cosinus est 0.53026323894546
Le sinus est -0.84783305987857
Le cosinus hyperbolique est 97.337002238748
Le sinus hyperbolique est 97.331865310524
La tangente hyperbolique est 0.99994722532947
L'arc tangente est 1.3833176461628
La conversion en degrés est 302.02324254731
La conversion en radian est 0.092001540860377
L'entier immédiatement supérieur est 6
L'entier immédiatement inférieur est 5
{{#invoke:Maths|diverse|0.13}} nous indique :
La valeur absolu est 0.13
L'exponentielle est 1.1388283833246
Le cosinus est 0.99156189371479
Le sinus est 0.12963414261969
Le cosinus hyperbolique est 1.0084619071226
Le sinus hyperbolique est 0.13036647620203
La tangente hyperbolique est 0.12927258360606
L'arc tangente est 0.12927500404814
La conversion en degrés est 7.4484513367007
La conversion en radian est 0.0022689280275926
L'entier immédiatement supérieur est 1
L'entier immédiatement inférieur est 0
{{#invoke:Maths|diverse|-0.5}} nous indique :
La valeur absolu est 0.5
L'exponentielle est 0.60653065971263
Le cosinus est 0.87758256189037
Le sinus est -0.4794255386042
Le cosinus hyperbolique est 1.1276259652064
Le sinus hyperbolique est -0.52109530549375
La tangente hyperbolique est -0.46211715726001
L'arc tangente est -0.46364760900081
La conversion en degrés est -28.647889756541
La conversion en radian est -0.0087266462599716
L'entier immédiatement supérieur est -0
L'entier immédiatement inférieur est -1
{{#invoke:Maths|diverse|-7.333}} nous indique :
La valeur absolu est 7.333
L'exponentielle est 0.00065360981349759
Le cosinus est 0.49773177909927
Le sinus est -0.8673310072139
Le cosinus hyperbolique est 764.98272100184
Le sinus hyperbolique est -764.98206739203
La tangente hyperbolique est -0.99999914558879
L'arc tangente est -1.4352625273451
La conversion en degrés est -420.14995116943
La conversion en radian est -0.12798499404874
L'entier immédiatement supérieur est -7
L'entier immédiatement inférieur est -8
Fonction simple avec domaine de définition limité
[modifier | modifier le wikicode]Dans ce paragraphe, nous allons étudier les fonctions mathématiques qui ne sont pas définie sur la totalité de l’ensemble des nombres réels et qui nous retourne un seul réel. Ces fonctions sont :
- math.log ; Retourne le logarithme népérien d'un nombre réel.
- math.log10 ; Retourne le logarithme décimal d'un nombre réel.
- math.tan ; Retourne la tangente d'un nombre réel.
- math.acos ; Retourne l'arc cosinus d'un nombre réel.
- math.asin ; Retourne l'arc sinus d'un nombre réel.
- math.sqrt ; Retourne la racine carrée d'un nombre réel.
Toutes ces fonctions ne sont pas définies sur la totalité de l’ensemble des nombres réels. Si on leur donne en argument, un nombre réel qui n'appartient pas à leur domaine de définition, ces fonctions retourneront nan ou -nan. On remarque qu'elle ne retourne pas nil comme on aurait pu le croire à priori.
Écrivons une fonction diverse2 qui, comme le paragraphe précédent permet d’avoir le retour de toutes ces fonctions à un nombre donné :
local p = {}
function p.diverse2(frame)
local x = tonumber(frame.args[1])
local reponse = " "
reponse = reponse.."<br>Le logarithme népérien est "..math.log(x)
reponse = reponse.."<br>Le logarithme décimal est "..math.log10(x)
reponse = reponse.."<br>La tangente est "..math.tan(x)
reponse = reponse.."<br>L'arc cosinus est "..math.acos(x)
reponse = reponse.."<br>L'arc sinus est "..math.asin(x)
reponse = reponse.."<br>La racine carré est "..math.sqrt(x)
return reponse
end
return p
{{#invoke:Maths|diverse2|1.570796326794896}} nous indique :
Le logarithme népérien est 0.45158270528945
Le logarithme décimal est 0.19611987703015
La tangente est 1.3748233863972e+15
L'arc cosinus est nan
L'arc sinus est nan
La racine carré est 1.2533141373155
{{#invoke:Maths|diverse2|0.13}} nous indique :
Le logarithme népérien est -2.0402208285266
Le logarithme décimal est -0.88605664769316
La tangente est 0.13073731800446
L'arc cosinus est 1.4404273470918
L'arc sinus est 0.13036897970315
La racine carré est 0.3605551275464
{{#invoke:Maths|diverse2|-0.5}} nous indique :
Le logarithme népérien est nan
Le logarithme décimal est nan
La tangente est -0.54630248984379
L'arc cosinus est 2.0943951023932
L'arc sinus est -0.5235987755983
La racine carré est -nan
{{#invoke:Maths|diverse2|-7.333}} nous indique :
Le logarithme népérien est nan
Le logarithme décimal est nan
La tangente est -1.7425670685193
L'arc cosinus est nan
L'arc sinus est nan
La racine carré est -nan
La valeur 1.570796326794896 est une valeur approchée de π/2 qui n'appartient pas au domaine de définition de la fonction tangente. Pour cette valeur, nous avons malgré tout obtenu 1.3748233863972e+15 et non pas nan. On peut simuler la constante π à l'aide de la fonction préprogrammée math.pi. Essayons d'écrire une fonction tanpi qui calcule la tangente de π/2 en utilisant math.pi :
local p = {}
function p.tanpi()
return math.tan(math.pi/2)
end
return p
{{#invoke:Maths|tanpi}} nous donne : 1.6331239353195e+16
Nous constatons que nous obtenons une valeur encore plus grande que précédemment, mais nous n'obtenons toujours pas nan. Bien que la fonction math.tan soit à domaine de définition limité, il semblerait qu’il soit impossible de lui donner, en argument, un nombre réel tel qu'elle nous retourne nan.
math.max
[modifier | modifier le wikicode]Cette fonction retourne le plus grand de ses paramètres.
math.min
[modifier | modifier le wikicode]Cette fonction retourne le plus petit de ses paramètres.
math.modf
[modifier | modifier le wikicode]Cette fonction mathématiques permet d'obtenir la partie entière et la partie fractionnaire d'un nombre donné. Elle retourne donc deux valeurs. À titre d'exemple, nous écrirons une fonction p.separation qui nous indiquera, sous forme rédigée, la partie entière et la partie fractionnaire d'un nombre décimal entré en argument :
local p = {}
function p.separation(frame)
local a,b = math.modf(frame.args[1])
return "La partie entière est "..a.." et la partie fractionnaire est "..b
end
return p
{{#invoke:Maths|separation|5.2713}} nous indique : La partie entière est 5 et la partie fractionnaire est 0.2713
math.fmod
[modifier | modifier le wikicode]Cette fonction admet deux paramètres, math.fmod(n,d). Elle retourne le reste de la division de n par d. Une autre façon de voir serait de dire qu'elle nous donne la classe de congruence de n modulo d.
math.random et math.randomseed
[modifier | modifier le wikicode]math.random est une fonction qui retourne un nombre pseudo-aléatoire. Si l’on ne met pas de paramètre, ce nombre pseudo aléatoire sera dans l'intervalle [0;1[. Si l’on y met un paramètre n entier, le nombre pseudo-aléatoire sera un entier dans l'intervalle [1;n]. Si l’on y met deux paramètres entiers m et n, le nombre pseudo-aléatoire sera un entier dans l'intervalle [m;n].
Si la fonction est utilisée plusieurs fois dans un programme, elle donnera une liste de nombres pseudos aléatoires qui seront toujours les mêmes à chaque exécution du programme. Si l’on veut une liste de nombres différentes, il faut utiliser la fonction math.randomseed. La fonction math.randomseed admet un paramètre et selon la valeur de ce paramètre, la fonction math.random fournira une liste de nombres aléatoires qui sera différentes.
Seule la partie entière du paramètre passée à la fonction math.randomseed sera utilisée. La fonction math.randomseed ne fera pas la différence, par exemple, entre 47.3 et 47.8. Autant se contenter de lui transmettre un nombre entier ! |
Bien sûr, si l’on fournit toujours le même paramètre à la fonction math.randomseed, on obtiendra toujours la même liste. Si on veut une liste de nombre qui semble vraiment aléatoire et différente à chaque utilisation du programme, il faut trouver un moyen de fournir à la fonction math.randomseed un paramètre différent à chaque utilisation du programme. La première méthode est que l'utilisateur du programme choisisse lui-même un paramètre différent à chaque exécution du programme. Ici, cela risque d’être difficile à réaliser compte tenu que l’on ne peut pas rentrer un paramètre en temps réel à chaque utilisation du programme.
La seconde méthode consiste à utiliser une fonction qui fasse appel à une donnée extérieure au programme et qui soit susceptible de varier d'une exécution à l'autre comme par exemple l’heure à laquelle démarre le programme. Nous approfondirons cette idée en exercice.
Pour le moment, écrivons, dans le Module:maths, une fonction p.alea qui teste ce que l’on vient de dire. C'est-à-dire qui utilise la fonction math.randomseed, auquel on aura transmit un paramètre grâce à #invoke, suivi de la fonction math.random qui fournira une vingtaine de nombres aléatoires grâce à une boucle for..do. Pour être complet, nous pourrons aussi transmettre au programme les deux paramètres m et n décrit dans la présentation de la fonction math.random.
local p = {}
function p.alea(frame)
math.randomseed(frame.args[1])
local m,n = frame.args[2],frame.args[3]
local reponse = ""
for x = 1, 20 do
if m ~= nil and n ~= nil then
reponse = reponse..math.random(m,n).." "
elseif m ~= nil then
reponse = reponse..math.random(m).." "
else
reponse = reponse..math.random().." "
end
end
return reponse
end
return p
{{#invoke:Maths|alea|3|5|15}} nous donne : 12 5 5 13 13 9 15 8 8 11 7 7 7 5 15 9 14 12 6 15