Using a while loop to check convergence

40 次查看(过去 30 天)
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!

回答(1 个)

arich82
arich82 2015-3-3
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.
  1 个评论
Charles Rice
Charles Rice 2018-5-3
编辑:Charles Rice 2018-5-3
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

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Creating and Concatenating Matrices 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by