Newton Rapson method code question
조회 수: 67 (최근 30일)
이전 댓글 표시
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
Torsten
2024년 10월 26일 9:33
Where is the problem?
We don't know because you didn't supply the inputs to the function.
채택된 답변
John D'Errico
2024년 10월 26일 13:06
편집: John D'Errico
2024년 10월 26일 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
John D'Errico
2024년 10월 28일 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.
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!