Using a while loop to check convergence
40 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
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!
Antworten (1)
arich82
am 3 Mär. 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.
1 Kommentar
Charles Rice
am 3 Mai 2018
Bearbeitet: Charles Rice
am 3 Mai 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
Siehe auch
Kategorien
Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!