Calculate integral trapezoid mode

Asked

Viewed 641 times

5

I need to calculate integral with the trapezoid method. I believe the error may be in the for. They had tested them step by step and it worked.

    function integratrapezio(){         
    var elmbasea = document.getElementById("valoresdex").value;
    var elemb = document.getElementById("valoresdey").value;
    var elemquant = document.getElementById("valoresden").value;
    var elemfuncao = document.getElementById("valordafuncao").value;

    var k = (elmbasea-elemb)/elemquant;

    var n = +elemquant+1;   
    var elemk = +k/2;

    var f = "x+2";

    var cont = 0;

    for (j=1;j<n; j++){

        var i=+j-1;
                if ((i == 0)){c=1;}else{c=2;}
                var x=+elmbasea+i*+k;   

                var funcao = eval(elemfuncao);

                var calculodafuncao=cont+c*funcao;
                var cont = calculodafuncao;

        alert(calculodafuncao);             

    }



    var total=+elemk*+calculodafuncao;

    /*qualcular a função f = (x)       https://www1.univap.br/spilling/CN/CN_Capt6.pdf*/                
    if(document.getElementById('resultFunc').style.visibility = 'Visible'){document.getElementById('resultFunc').style.visibility = 'hidden';}

    if(document.getElementById('resultFunc').style.visibility = 'hidden'){document.getElementById('resultFunc').style.visibility = 'visible';}

    document.getElementById('resultFunc').innerHTML = total;

}
  • Welcome. What is your problem? It can explain better what does not work in the code?

  • Tip: In Javascript and other C descending languages, do not confuse = with ==.

  • Instead of posting answers that don’t answer the question, edit the question. I already put the content of what you posted as an answer here, but the tip is for next time.

  • The PDF of the function you want "qualcular" won’t open for me.

  • Victor, I didn’t quite understand your answer.

  • Leonardo, I don’t know yet what doesn’t work, but it must be in the......

  • Your two codes have a lot of errors. But I don’t understand which calculation process you are trying to use. The problem is that when you do if (c = 0) you are not verifying if c is zero, is making it zero. What you wanted is if (c == 0). However, there are still several other errors, such as trying to use a variable before it was declared or initialized.

  • Valew, this one "if (c = 0) " had already changed. how much, "a variable before it was declared or initialized."..

  • I sincerely recommend using an external library to perform such complex tasks, such as the http://mathjs.org library

Show 4 more comments

1 answer

7

In particular, I found it very odd what you did to calculate the integral in the manner of the trapezoids. You don’t have a lot of secrets from doing the whole thing with that method. The only thing questionable is whether you define the size of the trapezoids or how many trapezoids divide the interval. The following is an example defining the size of each trapeze:

function trapezio(lbda, ini, fim, delta) {
  let integral = 0.0;
  let last_lbda = lbda(ini);
  for (let i = ini + delta; i <= fim; i += delta) {
    let now_lbda = lbda(i);
    integral += delta*(now_lbda+last_lbda)/2;
    last_lbda = now_lbda;
  }
  return integral;
}

function info_trapezio_quadrado(ini, fim, delta) {
  let result = trapezio((i) => i*i, ini, fim, delta);
  console.log("função quadrada, de " + ini + " a " + fim +", delta = " + delta);
  console.log(">integral = " + result);
}

info_trapezio_quadrado(0, 2, 1);
info_trapezio_quadrado(0, 2, 0.5);
info_trapezio_quadrado(0, 2, 0.1);
info_trapezio_quadrado(0, 2, 0.01);
info_trapezio_quadrado(0, 2, 0.001);

Explaining the code:

  • the arguments are a function of any of the real ones in the real ones lbda, the interval [ini, fim) and the size of the base of the trapezoids delta
  • the calculation of the area of a rectangular trapeze is base * (altura1 + altura2)/2
  • the integral is the sum of the area of all trapezoids, starting at ini and ending in fim

A version that makes fewer operations, but less readable, is:

function trapezio_menos_operacoes(lbda, ini, fim, delta) {
  let lbda_ini = lbda(ini);
  let somas = lbda_ini;
  let last_lbda = lbda_ini;
  for (let i = ini + delta; i <= fim; i += delta) {
    last_lbda = lbda(i)
    somas += last_lbda;
  }
  let integral = delta*(somas - (lbda_ini + last_lbda)/2.0);
  return integral;
}

In this version, I am availing myself that each height of the trapezoids is taken into account twice in the original version (except the first and the last). For example, for the square function with delta = 0.5 (integrating 0 to 2):

iteração | i    | f(i) | área do trapézio              | área acumulada
---------+------+------+-------------------------------+----------------
0        | 0    | 0    | 0                             | 0
1        | 0.50 | 0.25 | 0.5*(0.00 + 0.25)/2 = 0.0625  | 0.0625
2        | 1.00 | 1.00 | 0.5*(0.25 + 1.00)/2 = 0.3125  | 0.3750
3        | 1.50 | 2.25 | 0.5*(1.00 + 2.25)/2 = 0.8125  | 1.1875
4        | 2.00 | 4.00 | 0.5*(2.25 + 4.00)/2 = 1.5625  | 2.7500

Noted as value of f(0.5) repeated in two moments? In the trapezoid area of iteration 1 and iteration 2? And the same happened for f(1.0) (iterations 2 and 3) and f(1.5) (iterations 3 and 4)? If I made the sums in hand it would be something like this:

delta*(f(0.0) + f(0.5))/2 + [primeiro trapézio]
delta*(f(0.5) + f(1.0))/2 + [segundo trapézio]
delta*(f(1.0) + f(1.5))/2 + [terceiro trapézio]
delta*(f(1.5) + f(2.0))/2   [quarto trapézio]
-------------------------
delta/2 * (
  f(0.0) +
  f(0.5) + f(0.5) +
  f(1.0) + f(1.0) +
  f(1.5) + f(1.5) +
  f(2.0)
)

The rest were mathematical tricks to minimize the amount of operations.


Apparently, you want to take the formula from somewhere, right? Well, we can take the input, the variable being x:

function faz_leitura(form) {
  let ini = Number(document.getElementById("ini").value);
  let fim = Number(document.getElementById("fim").value);
  let delta = Number(document.getElementById("delta").value);
  let equacao = document.getElementById("equacao").value;
  
  let pre_lambda = "(x) => " + equacao;
  let lbda = eval(pre_lambda);
  
  let result = trapezio_menos_operacoes(lbda, ini, fim, delta);
  document.write("<div>Integral de " + ini + " até " + fim + " (delta " + delta + "), para a função " + pre_lambda + ": " + result + "</div>");
}

function trapezio_menos_operacoes(lbda, ini, fim, delta) {
  let lbda_ini = lbda(ini);
  let somas = lbda_ini;
  let last_lbda = lbda_ini;
  for (let i = ini + delta; i <= fim; i += delta) {
    last_lbda = lbda(i)
    somas += last_lbda;
  }
  let integral = delta*(somas - (lbda_ini + last_lbda)/2.0);
  return integral;
}
<form onsubmit="faz_leitura(this); return false;">
<div>
  <input required type="text" id="equacao"/>
  <label>equação (use 'x' minúsculo para a variável)</label>
</div>
<div>
  <input required type="text" id="ini"/>
  <label>ini</label>
</div>
<div>
  <input required type="text" id="fim"/>
  <label>fim (deve ser maior que ini)</label>
</div>
<div>
  <input required type="text" id="delta">
  <label>delta (deve ser positivo)</label>
</div>
<button type="submit">Integral</button>
</form>

Did you notice that here I have separated the concern of each function? It has the function that deals with the submission of the form, filling the variables (faz_leitura) and the function that actually makes the calculation of the integral in the strategy of the trapezoids (trapezio_menos_operacoes). My separation was not good, I am not the most experienced in Javascript + HTML, but already separates the business logic of the interface.

Gazing another answer, I come across the possible malicious use of eval(). So, avoid the eval(), is easier. I will edit this question to use the new Function(), but now I’m in no condition to test.

References:

Special thanks to the following users for helping me prepare the answer: @Anderson Carlos Woss, @Victor Stafusa, @rray, @pss1support

Observations on the differences between the two summations

On the two versions of the integration function, mathematically they are equal, considering the arithmetic of the real numbers and the rational numbers. However, floating point numbers obey other rules.

When making a floating point sum, you can lose accuracy. This is natural and sometimes even desirable. I disagree more on the subject on one of the points of this answer.

The approach of not multiplying by the base of the trapeze makes the numbers larger, since ideally this value should approach zero. Therefore, possibly the value of the function may be insignificant compared to the accumulated total.

Another point to draw attention to is that if the value of lbda(x) is decreasing (even if decreasing is decreasing) according to x if approaching the final limit, the sum value will not change. This would only be postponed if the base value was multiplied.

A possible measure to avoid this would be to accumulate the numbers as long as they are totally significant in relation to the sum. When there is detection that the summed number will have part of the missed precision, it should start a new summation is so on. In the end, one should order from the smallest to the largest and add in that order. This would be one of the ways to ensure the maximum accuracy of calculations using floating point.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.