Newton Rapson method code question
67 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
jwon
am 26 Okt. 2024 um 9:07
Kommentiert: John D'Errico
am 28 Okt. 2024 um 11:41
I am creating a MATLAB code that takes a function, differential function, initial value, and error tolerance and solves it using Newton-Raphson's method, but it repeats infinitely. Where is the problem?
function [root,iter] = newton_raphson(f,df,x0,tol)
iter=0;
err = 1;
x=x0;
while(err>=tol)
iter=1+iter;
xm=x-(f(x)/df(x));
err=abs(xm-x);
x=xm;
end
root=xm;
end
1 Kommentar
Torsten
am 26 Okt. 2024 um 9:33
Where is the problem?
We don't know because you didn't supply the inputs to the function.
Akzeptierte Antwort
John D'Errico
am 26 Okt. 2024 um 13:06
Bearbeitet: John D'Errico
am 26 Okt. 2024 um 13:15
Actually, this is surprisingly nice looking code. (A true compliment from me, given most of the student codes we see on here!) You should consider adding comments in your work though. My goal is often to have at least one comment line per line of code.
There are some subtle problems though. You start out with err = 1. BAD. What if you supplied a tolerance of 2? Make your code robust to crazy things!
Initially, set
err = inf;
Now your solver will always take at least one step!
Next, it would be better to set up a maximum number of iterations, so have the user pass in a parameter, probably called itermax, that will have the code stop when iter exceeds that max. Good code would probably issue a warning when that happens. I won't add that feature for you, but it should be here.
function [root,iter] = newton_raphson(f,df,x0,tol)
% 1-d Newton-Raphson solver
% [root,iter] = newton_raphson(f,df,x0,tol)
% f = provided function handle
% df = provided derivative function handle
% x0 = start point
% tol = tolerance
% initialize iterations
iter = 0;
err = inf;
x = x0;
% looping until convergence
while(err>=tol)
% update iteration counter
iter = 1 + iter;
% Newton update
xm=x-(f(x)/df(x));
% set err as the step length taken
err=abs(xm-x);
% new estimate for x replacing the old
x=xm;
end
root=xm;
end
We can try it out.
f = @(x) sin(x) - 0.3;
df = @(x) cos(x);
x0 = 0.1;
tol = 1e-12;
disp("Known solution: " + asin(0.3))
[root,iter] = newton_raphson(f,df,x0,tol)
Now I made no changes at all to your code, beyond adding some comments to make it more readable, and some white space. As you can see, it worked with no problems.
So, what did you do wrong? Perhaps you gave it a function that has no root at all. For example:
f = x^2 + 1;
df = 2*x;
Or perhaps you tried to solve a problem where you gave it a starting point that diverges, or something equally silly. (There are actually subtle ways your teacher could have caused this to happen, that I won't get into.) But we cannot know. Your code was actually correct. All I did was change the initial value for err to inf.
5 Kommentare
John D'Errico
am 28 Okt. 2024 um 11:41
I'm sorry. I won't do your assignment for you. But you know exactly what to do. Break large problems down into small ones that you can handle.
- Write a bisection function (if you don't already have one) that will take an error tolerance, just like the one you have for Newton. You already have a Newton code.
- Set up a loop, where you call the codes repeatedly, one for each error tolerance. Save the results in vectors.
- Plot the results as needed. You will need to use the functions loglog and semilogy for those plots as appropriate.
Again. make a big probem into a set of managable small ones. When all the pieces are in place, put it all together.
Weitere Antworten (0)
Siehe auch
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!