MATLAB Answers

Using a while loop to check convergence

521 views (last 30 days)
Alan Earl
Alan Earl on 2 Mar 2015
Commented: Mary Kisaka on 21 Jun 2018
I am using the secant method to find the root for a function, my code is as follows:
% code
f=@(x) x^2 - 612;
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))));
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!

Answers (1)

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;
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))));
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);
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.
  1 Comment
Charles Rice
Charles Rice on 3 May 2018
Not to be pedantic, but it isn't necessarily bad practice to use i as a loop variable. Mathworks recommends 1j as the imaginary unit. Mathworks 1j page

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by