Численное интегрирование
Данное интерактивное приложение позволяет вычислить интеграл заданной с клавиатуры функции с помощью метода прямоугольников.
Можно использовать любые функции и свойства объекта 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" <syntaxhighlight lang="javascript" line start="1" enclose="div"> 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();
} </syntaxhighligh> Файл "Integrate.html" <syntaxhighlight lang="html" line start="1" enclose="div"> <!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>
f(x) = <input type="text" id="function_text" style="width: 80ex;" value="sin(sqrt(x)) * sin(x * x)"/>
x1 = <input type="text" id="x1_text" style="width: 25ex;" value="0"/>
x2 = <input type="text" id="x2_text" style="width: 25ex;" value="PI * 3"/>
Точность: <input type="number" id="accuracy_number" min=2 style="width: 12ex;" value="100000"/>
<input type="button" id="calculate_button" value="Посчитать"/>
Результат:
</body> </html> </syntaxhighligh> </toggledisplay>
Предлагаемые направления развития стенда
- Применить другие методы численного интегрирования (например, метод трапеций или метод Монте-Карло)
- Научиться определять сходимость функции, и в случае, если функция не сходится - выдавать предупреждение.
- Математически определять и выводить погрешность результата.
Заметка разработчику
В данной программе использована возможность языка JavaScript создавать и запускать программный код "на лету", без перезапуска программы. Это очень важная возможность (которую достаточно трудно, а, порой, невозможно применить в других языках), которая позволяет разработчику без особых усилий создавать максимально гибкий интерфейс. Например, можно дать пользователю возможность быстро задать специфические граничные условия, или позволить исследовать полученную систему, просматривать данные и выводить нужные графики прямо в окне браузера.