Численное интегрирование

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Виртуальная лаборатория > Численное интегрирование

Данное интерактивное приложение позволяет вычислить интеграл заданной с клавиатуры функции с помощью метода прямоугольников.

Можно использовать любые функции и свойства объекта Math языка JavaScript (описание на русском, английском), например:

  • функции: sin(x), exp(x), round(x), abs(x), min(x);
  • свойства: PI, E, SQRT2, LN10.


Важно! Чтобы возвести число в степень, вместо x^3 нужно писать pow(x, 3)

(оператор ^ в JavaScript означает логическую операцию "Исключающее ИЛИ").


Скачать Integrate_v3-6_release.zip.

Текст программы на языке JavaScript (разработчик Цветков Денис): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "Integrate.js"

window.addEventListener("load", Main_Integrate, true);
function Main_Integrate() {

    Integrate_canvas.onselectstart = function () {return false;};     // запрет выделения canvas
    var context = Integrate_canvas.getContext("2d");                  // на context происходит рисование

    var w = Integrate_canvas.width;
    var h = Integrate_canvas.height;

    // функции и переменные, объявленные через this, можно будет вызывать по сокращенному названию (например, sin(x), PI)
    var math_methods = Object.getOwnPropertyNames(Math);
    for (var i in math_methods)
        this[math_methods[i]] = Math[math_methods[i]];

    calculate_button.onclick = get_and_calc;
    function get_and_calc() {
        var script = document.createElement('script');
        script.innerHTML = "function f(x) {return " + function_text.value + "};" +
            "x1 = " + x1_text.value + ";" +
            "x2 = " + x2_text.value + ";";
        document.getElementsByTagName('head')[0].appendChild(script);
        integral(f, x1, x2, accuracy_number.value);
    }

    function on_enter_up(e) {
        e = e || window.event;
        if (e.keyCode === 13) {
            get_and_calc();
        }
        return false;                                                   // отменяем действие по умолчанию
    }

    function_text.onkeyup = on_enter_up;
    x1_text.onkeyup = on_enter_up;
    x2_text.onkeyup = on_enter_up;
    accuracy_number.onkeyup = on_enter_up;

    function calculate(f, x1, x2, n) {
        var integral = {};
        integral.D = {};
        integral.D.x = [];
        integral.D.fx = [];
        var summ = 0;
        var k1 = Math.floor(n / w);         // каждый k1-ый элемент будет отправлен на рисование
        if (k1 < 1) k1 = 1;

        var interval = (x2 - x1) / n;
        for (var i = 0; i < n; i++) {
            var x = x1 + interval * i;
            var fx = f(x);
            if (fx == Number.POSITIVE_INFINITY || fx == Number.NEGATIVE_INFINITY || isNaN(fx)) continue;
            summ += interval * fx;

            if (i % k1 == 0) {
                integral.D.x.push(x);
                integral.D.fx.push(fx);
            }
        }
        integral.summ = summ;
        return integral;
    }

    function integral(f, x1, x2, n) {
        var I = calculate(f, x1, x2, n);
        result_span.innerHTML = I.summ.toPrecision(accuracy_number.value.length);
        draw(I.D, x1, x2);
    }

    function draw(D, x1, x2) {
        context.clearRect(0, 0, w, h);
        context.beginPath();

        // найдем минимум и максимум функции (точнее не всей функции, а только точек, отправленных на рисование)
        var len = x2 - x1;
        var f_max = Number.NEGATIVE_INFINITY, f_min = Number.POSITIVE_INFINITY;
        for (var i = 0; i < D.fx.length; i++) {
            f_max = (f_max > D.fx[i]) ? f_max : D.fx[i];
            f_min = (f_min < D.fx[i]) ? f_min : D.fx[i];
        }

        // график
        var h_center = f_max / (f_max - f_min) * h;
        context.moveTo(0, h_center);
        for (var i = 0; i < D.fx.length; i++) {
            var x = D.x[i];
            context.lineTo((x - x1) / len * w, h_center - D.fx[i] / (f_max - f_min) * h);
        }
        context.lineTo(w, h_center);
        context.fill();

        // интерфейс
        context.beginPath();
        context.moveTo(0, h_center);
        context.lineTo(w, h_center);
        context.moveTo(-x1 / (x2 - x1) * w, 0);
        context.lineTo(-x1 / (x2 - x1) * w, h);
        context.stroke();
    }

    context.fillStyle = "#888888";
    get_and_calc();
}

Файл "Integrate.html"

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Integrate</title>
    <script src="Integrate.js"></script>
</head>
<body>
    <canvas id="Integrate_canvas" width="600" height="600" style="border:1px solid #000000;"></canvas><br>
    f(x) = <input type="text" id="function_text" style="width: 80ex;" value="sin(sqrt(x)) * sin(x * x)"/><br>
    x1 = <input type="text" id="x1_text" style="width: 25ex;" value="0"/><br>
    x2 = <input type="text" id="x2_text" style="width: 25ex;" value="PI * 3"/><br><br>
    Точность: <input type="number" id="accuracy_number" min=2 style="width: 12ex;" value="100000"/><br>
    <input type="button" id="calculate_button" value="Посчитать"/><br><br>
    Результат: <span id="result_span"></span>
</body>
</html>

</toggledisplay>

Предлагаемые направления развития стенда

  • Применить другие методы численного интегрирования (например, метод трапеций или метод Монте-Карло)
  • Научиться определять сходимость функции, и в случае, если функция не сходится - выдавать предупреждение.
  • Математически определять и выводить погрешность результата.

Заметка разработчику

В данной программе использована возможность языка JavaScript создавать и запускать программный код "на лету", без перезапуска программы. Это очень важная особенность, которая позволяет разработчику без особых усилий создавать максимально гибкий интерфейс. Например, можно дать пользователю возможность быстро задать специфические граничные условия, или позволить исследовать полученную систему, просматривать данные и выводить нужные графики прямо в окне браузера.