Début en VBA - trouver le zero d'une fonction affine
Bonjour,
Je suis nouveau sur le forum, comme en VBA.
Peut-être que je ne poste pas ma question au bon endroit. Si c'est le cas, je vous présente d'avance mes excuses et j'espère qu'un gentil administrateur pourra m'indiquer le bon chemin.
J'essaye de programmer depuis un petit moment déjà une procédure itérative pour trouver le x qui annule f(x). C'est un peu la fonction "Analyse de scénario" -> "Valeur cible" d'Excel.
Sauf que : je souhaite régler moi-même le critère de précision de la solution ( à 0,1 ou 0,01 prés ou encore moins).
La fonction que j'analyse est affine de la forme f(x)= -a.x + b, ou a et b sont des constantes positives générés aléatoirement avec "Randomize".
Je cherche donc l'intervalle sur lequel le signe des bornes de ma fonction s'oppose.
Le code marche "relativement" bien car il donne souvent la bonne réponse mais quelque fois pour une raison qui m'échappe, il arrive au bout de l'intervalle de recherche que je lui ai fixé et n'a pas trouvé la réponse alors qu'elle y était. Malgré mes recherches, je n'ai pas trouvé la source de ces omissions périodiques.
Est-ce que l'un des honorables membres de ce forum aura la sagacité suffisante pour trouver la réponse à mon problème et la gentillesse pour m'aider ?
Voici le code :
Option Explicit
Sub trouve_zero()
''''''''Dimensionnement des variables pour la fonction '''''''
Dim fonction As Single
Dim a As Single
Dim cst As Single
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''Définition du critére de précision (cdp) '''''''''''''
Dim cdp As Single
cdp = 1 * 10 ^ (-1) 'choisir le degré de précision
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''Dimensionnement des variables de la boucle ''''''''''
Dim x As Single
Dim i As Single
Dim max As Single
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''' Début de la boucle For '''''''''''''''''''''''''''''
max = 10 '''' borne maximale de x
x = 0 '''initialisation de x
For i = 1 To max * (1 / cdp) ''''la plage de x est [cdp ; 1000]
x = cdp * i
fonction = f(a, x, cst)
If Sgn(fonction + cdp) <> Sgn(fonction) Then '''' La boucle tourne tant que le signe de f(x-cdp) est le même que celui de f(x+cdp)
Exit For
End If
Next
'''''''' Fin de la boucle ''''''''''''''''''''''''''''''''
If x = max Then
MsgBox "Il n'y a pas de solution sur l'intervalle [" & cdp & " ; " & max & "] pour f(x) = " & a & " *x + " & cst & " = 0."
'''''Message d'erreur si il n'y a pas de solution dans l'intervalle choisie
Else
MsgBox " La solution pour f(x) = " & a & " * x + " & cst & " = 0 est x = " & x & " à " & cdp & " prés."
''''' Message quand la macro trouve la solution'''''''''''
End If
End Sub
'''''''' Définition de la fonction '''''''''''''''''
Function f(a As Single, x As Single, cst As Single) As Single
a = -Rnd() ''''''' Définition de la pente négative aléatoirement '''''''
cst = Rnd() '''''' Définition de la constante positive aléatoirement ''''''
f = a * x + cst '''''' fonction affine simple '''''
End Function
Merci d'avance pour votre aide,
Bonjour,
toutes les fois ou il n'y a pas de résultat, x=10
voir le test sur ce fichier,
Bonjour,
c'est pour un exercice personnel en vba ? Parce qu'elle s'annule pour x=-b/a
Sinon il faudrait déposer un fichier avec quelques exemple de couples ayant l'anomalie que tu as trouvé.
eric
Bonsoir,
Merci beaucoup pour vos réponses rapides.
@sabV
Merci pour ton tableau de comparaison, on voit bien que la macro trouve plus souvent la bonne solution que l'inverse.
Toutefois lorsque le code a balayé tout l'intervalle de x c-à-d de 0,01 à 10 et qu'il n'a pas trouvé de solution, il affiche le message indiquant x=10 (le max) mais ce n'est pas la bonne réponse.
Si on regarde les équations indiquées avec les erreurs, on trouve en faisant x= -b/a que la solution est bien inférieure à 10.
Le code est donc "passé dessus" sans la voir. Je voudrais savoir d'où viennent ces omissions.
Exemples :
Il n'y a pas de solution sur l'intervalle [0.1 ; 10] pour f(x) = -0.8881072 * x + 0.2823757 = 0. est x = 10 à 0.1 prés." -> la solution est x= 3.2
Il n'y a pas de solution sur l'intervalle [0.1 ; 10] pour f(x) = -0.8274737 * x + 0.9946718 = 0. est x = 10 à 0.1 prés." -> la solution est x = 1.2
Dans les deux précédents exemples, je vois pas pourquoi le code n'a pas affiché le résultat que j'ai calculé moi même en gras.
@eriiic
oui, c'est un exercice personnelle pour tenter de coder une dichotomie. Je souhaiterais ensuite l'adapter sur tout types de fonctions.
Merci encore pour votre aide,
FA
Définit a et b avant ta boucle. Si ils changent tout le temps comment veux-tu trouver.
Bonjour,
@eriiic
Merci beaucoup pour ta réponse.
ça marche beaucoup mieux maintenant.