My code has a problem where if I use the condition of while n >= 1 it goes on forever, this happens because it never actually satisfies the if condition that breaks the loop.
This is the code itself:
#define x, y e T
x = @(t) t;
y = @(t) t*exp(-t/4);
T = (0:0.5:15);
#definir x' e y'
x_deriv = 1;
y_deriv = @(t) ((-(t-4)/4) * e^(t/4))^2;
#definir a e b
a = 0;
b = 15;
#Definir a função
F = @(z) (sqrt(x_deriv^2 y_deriv(z)));
#Define os pesos segundo regra de simpson
A1 = (b-a)/6;
A2 = 2*(b-a)/3;
A3 = (b-a)/6;
#começa o contador
n = 1;
while n >= 1
#fazer a quadratura mudando-a consoante n
#break quando qn - q2n <= 10^-6
h = (b-a)/n;
i = 0;
k = 0;
valor_1_final = [];
valor_2_final = [];
valor_3_final = [];
xk_final = [];
while k <= n-1
for l = 1:length(T)
xk = a h*k;
xi_1 = xk (h*(1 0)/2);
xi_2 = xk h/2;
xi_3 = xk (h*(1 T(l))/2);
valor_1 = F(xi_1);
valor_2 = F(xi_2);
valor_3 = F(xi_2);
valor_1_final = [valor_1_final, valor_1];
valor_2_final = [valor_2_final, valor_2];
valor_3_final = [valor_3_final, valor_3];
k = k 1;
xk_final = [xk_final, xk];
sum1 = sum(valor_1_final);
sum2 = sum(valor_2_final);
sum3 = sum(valor_3_final);
Qn = ((b-a)/2*n) * (A1*sum1 A2*sum2 A3*sum3);
Q2n = ((b-a)/4*n) * (A1*sum1 A2*sum2 A3*sum3);
endfor
endwhile
if abs(Qn - Q2n) <= 10e-6
n_escolhido = n;
break
endif
n = n 1;
endwhile
disp(n_escolhido);
If I change the while statment so it is something of finite lenght it actually stops, everything works normally, execpt the if statement is never run, and as such the n_escolhido stays undefined.
CodePudding user response:
The loop never ends because Qn
is about I*n^2
where I
is the exact value of the integral, and Q2n
is always Qn/2
, so their difference never becomes small.
The first error could be repaired by replacing ((b-a)/2*n)
with ((b-a)/(2*n))
.
To get the correct value for Q2n
you would have to repeat the computation with a refined subdivision. To avoid repeating code, make it a function simpson(f,a,b,n)
.
In total the main loop could look like
n=15;
do
n *= 2;
Qn = simpson(f,a,b,n);
Q2n = simpson(f,a,b,2*n);
until abs(Qn-Q2n) < eps;
The Simpson quadrature can be as short as
function S = simpson(f,a,b,n)
x = linspace(a,b,2*n 1);
S = f(a) f(b);
S = 2*sum( f(x(3:2:2*n-1)) );
S = 4*sum( f(x(2:2:2*n)) )
S *= (b-a)/(6*n);
end%function
CodePudding user response:
You have a while loop with while n >= 1
and at the same time you set n = n 1;
(n starts as 1). It is never false.
CodePudding user response:
1.- The outer while
loop does not break because outside the loop you set n=1
, then you tell the while
loop to do things but n
is not brought down at any point inside the loop, not a single time, anywhere inside this outer loop.
As posted, k
is not n
.
2.- Then you nest another while
loop inside the 1st while
loop where a single loop would be more efficient.
3.- Replace the outer while
condition
while (n>=1)
with
while (abs(Qn - Q2n) <= 10e-6)
and remove the if
clause inside the while
loop.
4.- Also, it's highly probable that for the task at hand, it all can be solved with just 1 for
loop, the one you nested inside the nested while
loop.