Home > Software design >  Infinite while loop using a quadrature
Infinite while loop using a quadrature

Time:01-16

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.

  • Related