# Using a while loop to check convergence

521 views (last 30 days)
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;
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!
Mary Kisaka on 21 Jun 2018

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
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