Newton method root finding: School project help.

2 views (last 30 days)
Hello, I am working on a project for school, that requires I use a newton root finding method. While trying to write the code for this, I keep getting the error shown below. Any suggestions? The code, and error are below.Thanks in advance.
Code:
function [root,ea,iter]=newtraph(func,dfunc,xr,es,maxit,varargin)
if nargin<3,error('at least 3 input arguments required'),end
if nargin<4|isempty(es),es=0.0001;end
if nargin<5|isempty(maxit),maxit=50;end
iter = 0;
while (1)
xrold = xr;
xr = xr - func(xr)/dfunc(xr);
iter = iter + 1;
if xr ~= 0, ea = abs((xr - xrold)/xr) * 100; end
if ea <= es | iter >= maxit, break, end
end
root = xr;
When I try to use the function, I get the following error message:
>> newtraph(func,dfunc,xr,1.0E-12)
??? Attempted to access func(1.21526); index must be a positive integer or logical.
Error in ==> newtraph at 22
xr = xr - func(xr)/dfunc(xr);
  2 Comments
Eric
Eric on 10 Mar 2015
First, thanks for asking for help in an appropriate fashion. You were honest that this is an assignment for a class and provided your initial attempt. That's surprisingly rare. All too often people post questions that are obviously homework assignments in the hopes they'll get the community to do it for them.
The use of function handles as described by John D'Errico below is the answer you're looking for, I believe. I thought I'd also chime in and mention that you might look at the documentation for the inputParser object. It lets you handle optional inputs and named parameters elegantly. Alternatively you might look at the documentation for narginchk and nargoutchk. Your code currently checks the minimum number of inputs but not the maximum (indeed, 6 or more inputs are allowed because you use varargin but these extra inputs would not be used for anything).
-Eric
Daniel Platt
Daniel Platt on 10 Mar 2015
Thank you for the additional input. With this I was able to clear up the errors, and continue with the project.

Sign in to comment.

Accepted Answer

John D'Errico
John D'Errico on 10 Mar 2015
Edited: John D'Errico on 10 Mar 2015
Sorry. Your belief is ill-founded that you can just slip in func asd dfunc in as you have tried. Actually, your approach to how to write a function is the real problem.
Once you have defined the variables as you have...
k=1;
c=sqrt(2);
xr=1;
func = exp(k*(xr-c))-cos(k*(xr-c))-(k*(xr-c));
dfunc = k*exp(k*(xr-c))+sin(k*(xr-c))-k;
then func and dfunc are not functions. They are just scalars. Just numbers. MATLAB does not care that YOU think of them as apparently a function of xr. xr was defined by you as a scalar numeric value, that here takes on the value 1.
You might want to learn about function handles, and how to define a function that takes an input parameter.
func = @(xr) exp(k*(xr-c))-cos(k*(xr-c))-(k*(xr-c));
dfunc = @(xr) k*exp(k*(xr-c))+sin(k*(xr-c))-k;
As I wrote those functions, it is presumed that c and k are previously defined, and that xr is passed in. So I suppose you were pretty close, as all I needed to do was to slightly modify how you wrote func and dfunc to create them as function handles.
Once they are defined as function handles as I have done, there is no longer a need to then use an @ symbol in front when you call newtraph.
To be honest, I'd just use the existing tool fzero rather than writing a root finder myself, but you did say this was homework. The point is to use existing tools wherever possible, rather than recreate the wheel. And since tools like fzero were written by professionals, they tend to be more stable than home grown code. But again, it is homework.
  2 Comments
Daniel Platt
Daniel Platt on 10 Mar 2015
Thank you for the help, this seemed to clear up the error. My programming skills are subpar, and I agree fzero is an easier way to accomplish this, however the exercise is to analyze several ways of root finding. It is not a course on programming, or Matlab, rather numerical methods. That is why we are using these programs.
John D'Errico
John D'Errico on 10 Mar 2015
I did not say your programming was subpar. Actually, the code looked good for a couple of reasons. Mainly your knowledge of how to write a function that needed some work. :)
It is good that you learn to understand tools like Newton-Raphson and other solvers, why/when they will work, when they will fail. That understanding will help you when you need to use a numerical method in the future.
What I wanted to point out is that too often I end up seeing people writing their own code for real work, when better code was given to them already. Maybe writing a thesis teaches some people to be reliant only on themselves. After all, how hard can it be to write a root finder or solve a linear system of equations? The point is that there are indeed subtle issues that are best addressed by professionally written code for these things. And if you can use existing tools to solve a problem, then your own coding time goes down dramatically.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 10 Mar 2015
How did you define func? It thinks it's an array and that you're trying to access the 1.21526'th element of it, which of course there is no such element. Maybe if func is a function you need to call it like this:
newtraph(@func,dfunc,xr,1.0E-12)
  1 Comment
Daniel Platt
Daniel Platt on 10 Mar 2015
Sorry, parameters defined are:
>> k=1;
>> c=sqrt(2);
>> xr=1;
func = exp(k*(xr-c))-cos(k*(xr-c))-(k*(xr-c));
>> dfunc = k*exp(k*(xr-c))+sin(k*(xr-c))-k;
I had previously called the function and derivative of the function in the program specifically, but I believe I can use this method without issues related to it.

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!