521 views (last 30 days)

Show older comments

I am using the secant method to find the root for a function, my code is as follows:

% code

f=@(x) x^2 - 612;

x(1)=10;

x(2)=30;

for i=3:7

x(i) = x(i-1) - (f(x(i-1)))*((x(i-1) - x(i-2))/(f(x(i-1)) - f(x(i-2))));

end

root=x(7)

In the example above there is a finite number of iterations to be carried out, however instead of giving matlab a number of iterations to carry out, I want the loop to run until a convergence criteria is met, for example f(x(i))<0.005 .

Is this possible with a while loop, I have tried but I can't find a way to run loop infinite times until the criteria is met. Any help is greatly appreciated. Thanks!

arich82
on 3 Mar 2015

This looks like homework, but it also looks like you've got a good start...

Note that i is generally regarded as a bad choice for an index in Matlab, as it overwrites the builtin variable for the imaginary unit sqrt(-1).

That said, it's nearly trivial to modify your code with a while loop, though it would be terribly wasteful to do so:

f=@(x) x^2 - 612;

x(1)=10;

x(2)=30;

i = 2;

while abs(f(x(i))) > 0.005

i = i + 1;

x(i) = x(i-1) - (f(x(i-1)))*((x(i-1) - x(i-2))/(f(x(i-1)) - f(x(i-2))));

end

root=x(end)

There are several no-no's with the above code:

1) You should always have a fail-safe on your while-loop so it exits after a certain number of attempts, just in case you make a codiing mistake, or find a pathological case that creates an infinite loop.

2) You're growing the vector x inside the loop, meaning at every iteration, length(x) keeps increasing by one; this is bad because Matlab has to allocate a new x variable for each iteration, and copy all of the old x values into the new one. Look up "preallocation" on how and why to avoid this.

3) If f(x) were a very expensive function to compute, you'd be wasting a lot of time re-computing f(x(i-2)), since you already computed it the step before.

The following is far from a stellar coding example, but it incorporates some of the above suggestions:

f=@(x) x^2 - 612;

tol = 0.005;

count_max = 100;

count = 0;

x0 = 10;

f0 = f(x0);

x1 = 30;

f1 = f(x1);

while (abs(f1) > tol) && (count < count_max)

count = count + 1;

df = f1 - f0;

dx = x1 - x0;

x0 = x1;

f0 = f1;

x1 = x1 - f1*dx/df;

f1 = f(x1);

end

x1

count

Note that if you wanted to track the convergence of your routine, you could preallocate X = NaN(count_max, 1); before the while loop, and put X(count) = x1; inside the while loop.

Charles Rice
on 3 May 2018

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

Start Hunting!