Newton-Raphson la Méthode dans Matlab
Je suis nouveau sur matlab et j'ai besoin de créer une fonction qui ne n itérations de Newton-Raphson la méthode à partir de l'approximation x = un. Cette approximation ne compte pas comme une interaction et une autre exigence est que d'une boucle for est nécessaire. J'ai regardé d'autres questions similaires posté, mais dans mon cas, je ne veux pas utiliser une boucle while.
C'est ce que mes entrées sont censés être:
mynewton(f,a,n) which takes three inputs:
f: A function handle for a function of x.
a: A real number.
n: A positive integer.
Et voici mon code jusqu'à présent.
function r=mynewton(f,a,n)
syms x;
z=f(x);
y=a;
for i=1:n
y(i+1)=y(i)-(z(i)/diff(z(i)));
end
r=y
end
Quand j'essaie d'appeler la fonction que j'obtiens un message d'erreur disant:
Error in MuPAD command: DOUBLE cannot convert the input expression into a double array.
If the input expression contains a symbolic variable, use the VPA function instead.
Error in mynewton (line 6)
y(i+1)=y(i)-(z(i)/diff(z(i)));
La question est comment puis-je utiliser cette fonction de l'APV? Accordé le reste de mon code n'est probablement pas correct à 100% non plus, mais toute aide qui traite de l'apv problème ou résout les autres parties de mon code serait grandement apprécié.
Merci!
Cependant j'ai besoin d'utiliser une boucle for pas une boucle while
1) Votre problème avec l'erreur réside peut-être dans la définition de la fonction gérer
f
. Plus fréquemment, les personnes définir des fonctions comme la fonction de poignées, mais vous l'utilisez comme l'expression symbolique (vous avez syms x
). Pourriez-vous fournir votre utilisation sur f
(comment définissez-vous de l'appelant)? 2) Franchement, for
boucle n'est pas bon pour la N-R algo (ou la plupart des méthodes itératives). Mais de toute façon, votre erreur n'est pas sur le for
boucle, mais quelque chose d'autre.Il convient de mentionner
fzero
, que vous pouvez utiliser pour vérifier vos résultats.Aucune idée.... Soyons juste cette question car votre réponse est grand (oublié de +1 il). BTW, je suppose que la raison étrangement à utiliser un
for
boucle est la nécessité de voir la convergence de comportement de la boucle de continuer.
OriginalL'auteur | 2014-08-04
Vous devez vous connecter pour publier un commentaire.
Il y a deux choses qui ne sont pas tout à fait correct avec votre technique de Newton-Raphson... mais certainement réparable! Après nous résoudre ce problème, il n'est pas nécessaire pour le
VPA
erreur dont tu parles.Erreur #1 - L'itération de mise à jour
La première est celle de l'itération lui-même. Rappelons la définition de la technique de Newton-Raphson:
bla http://web.mit.edu/10.001/Web/Course_Notes/NLAE/equation6.gif
Pour la prochaine itération, vous utilisez la précédente itération de la valeur. Ce que vous faites est à l'aide de la compteur de boucle et en substituant ceci dans votre
f(x)
, qui n'est pas correct. Il doit être l'itération précédente est valeur.Erreur #2 - Mélange de valeurs symboliques avec des valeurs numériques
Si vous jetez un oeil à la façon dont vous êtes le codage de votre fonction, vous définissez votre fonction symboliquement, mais vous êtes en essayant de substituer numérique valeurs dans votre fonction. Ce qui malheureusement n'est pas voler avec MATLAB. Si vous voulez vraiment des valeurs de substitution, vous devez utiliser
subs
. Cela permettra de remplacer une valeur réelle pour vous en fonction dex
, quelle que soit la variable indépendante de votre fonction. Une fois que vous faites cela, votre valeur est encore unsym
type. Vous avez besoin de chasser ce que double afin d'être en mesure d'utiliser cette numériquement.Aussi pour l'efficacité, il n'est pas nécessaire de faire
y
un tableau. Juste en faire une valeur unique qui se met à jour à chaque itération. Avec tout cela étant dit, votre code est mis à jour à regarder comme ça. Rappelez-vous, j'ai pris la dérivée de la fonction avant la boucle pour diminuer la quantité de calcul que vous devez prendre. J'ai aussi diviser le numérateur et le dénominateur conditions de Newton-Raphson itérations pour mettre les choses au clair, et de le rendre plus agréable au goût poursubs
. Sans plus tarder:Prendre note que j'ai remplacé
i
avecidx
dans la boucle. La raison en est qu'il est effectivement recommandé de ne pas utiliseri
ouj
que les indices de boucle que ces lettres sont réservées pour représenter les nombres complexes. Si vous jetez un oeil à ce post par Shai, vous verrez qu'en fait c'est plus lent à utiliser ces variables comme les indices de boucle: À l'aide de i et j comme des variables dans MatlabEn tout cas, pour un test, supposons que notre fonction a été
y = sin(x)
, et ma première racine a étéx0 = 2
, avec 5 itérations, nous n':Ceci est en accord avec nos connaissances de
sin(x)
, comme l'interception desin(x)
sont situés à des multiples entiers depi
.x0 = 2
est situé près depi
si cela ne fonctionne pas comme nous l'attendions.Petit bonus pour vous
Votre code d'origine a les valeurs de la racine stockées à chaque itération dans
y
. Si vous voulez vraiment le faire, vous devrez modifier votre code pour qu'il ressemble à quelque chose comme ça. Gardez à l'esprit que je l'ai pré-allouéy
pour rendre les choses plus efficaces:Par l'exécution de ce code en utilisant exactement les mêmes paramètres que ci-dessus, nous obtenons:
Chaque valeur de
r
vous indique l'estimation de la racine à cette itération particulière. Le premier élément du tableau est la supposition initiale (bien sûr). La prochaine valeurs sont les devine à chaque itération de Newton-Raphson racine. Prendre note que le dernier élément de la matrice est notre dernière itération, qui est à peu près égale àpi
.diff(z)
.... Un autre travail extraordinaire de rayryeng! Par le chemin, considérez-vous l'accélération de cette fonction par la conversion dez
etdiff(z)
avant la boucle? mathworks.com/help/symbolic/...Bien sûr. N'est pas pris en compte. Que vais certainement accélérer les choses!... et merci pour les compliments 🙂
Vous êtes les bienvenus 🙂 Bienvenue sur StackOverflow!
Je préfère utiliser une tolérance,
while ( dy>tol ) & ( idx<n )
. Le point est qu'il n'y a rien qui dit que le nombre d'itérations requis est assez, ni quoi que ce soit, confirmant que l'algorithme fait converger. Sinon, bon travail! Everyting est très agréable et propre.qui a de l'allure. Merci!
OriginalL'auteur rayryeng
Vous devez utiliser
eval
Donc
z(x)=f(x)
, puiseval(z(1))
pour évaluer la fonction en x = 1Code complet:
Pas sûr au sujet de l'APV partie de la question, j'ai l'habitude de les ignorer MUPAD erreurs 😛
subs
est créé pour évaluer des expressions symboliques, donc je pense qu'il est préférable d'utiliser d'abordsubs
et puis jeté à la sortie à l'aide d'double
. Si il n'est pas nécessaire, je voudrais éviter deeval
, parce queeval
est évaluée au moment de l'exécution 🙁 (=difficile à déboguer parmi d'autres choses).Génial! De bons conseils, encore beaucoup à apprendre pour moi 🙂
Pour info, l'utilisation de
eval
est considéré comme une mauvaise pratique. Il n'est pas nécessaire pour son utilisation ici. Consulter Loren Shure de MathWorks article sur le sujet: blogs.mathworks.com/loren/2005/12/28/evading-evalOriginalL'auteur legas