From aa52eeee4faa1dd8e2fb02f63a69f3b429c07ebc Mon Sep 17 00:00:00 2001 From: algobytewise Date: Fri, 5 Mar 2021 16:18:07 +0530 Subject: [PATCH] Add algorithm Euler method --- Maths/EulerMethod.js | 108 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 Maths/EulerMethod.js diff --git a/Maths/EulerMethod.js b/Maths/EulerMethod.js new file mode 100644 index 000000000..7f292d777 --- /dev/null +++ b/Maths/EulerMethod.js @@ -0,0 +1,108 @@ +/* +In mathematics and computational science, the Euler method (also called forward Euler method) is a first-order numerical procedure for solving ordinary differential equations (ODEs) with a given initial value. It is the most basic explicit method for numerical integration of ordinary differential equations. The method proceeds in a series of steps. At each step the y-value is calculated by evaluating the differential equation at the previous step, multiplying the result with the step-size and adding it to the last y-value: y_n+1 = y_n + stepSize * f(x_n, y_n). +(description adapted from https://en.wikipedia.org/wiki/Euler_method ) +(see also: https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ ) +*/ + +/* +Doctests +> eulerStep(0, 0.1, 0, function(x, y){return x}) +0 +> eulerStep(2, 1, 1, function(x, y){return x * x}) +5 +> eulerFull(0, 3, 1, 0, function(x, y){return x}) +[{"x": 0, "y": 0}, {"x": 1, "y": 0}, {"x": 2, "y": 1}, {"x": 3, "y": 3}] +> eulerFull(3, 4, 0.5, 1, function(x, y){return x * x}) +[{"x": 3, "y": 1}, {"x": 3.5, "y": 5.5}, {"x": 4, "y": 11.625}] +*/ + +function eulerStep (xCurrent, stepSize, yCurrent, differentialEquation) { + // calculates the next y-value based on the current value of x, y and the stepSize + const yNext = yCurrent + stepSize * differentialEquation(xCurrent, yCurrent) + return yNext +} + +function eulerFull (xStart, xEnd, stepSize, yStart, differentialEquation) { + // loops through all the steps until xEnd is reached, adds a point for each step and then returns all the points + const points = [{ x: xStart, y: yStart }] + let yCurrent = yStart + let xCurrent = xStart + + while (xCurrent <= xEnd - stepSize) { + // Euler method for next step + yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation) + xCurrent += stepSize + points.push({ x: xCurrent, y: yCurrent }) + } + + return points +} + +function plotLine (label, points, width, height) { + // utility function to plot the results + + // container needed to control the size of the canvas + const container = document.createElement('div') + container.style.width = width + 'px' + container.style.height = height + 'px' + document.body.append(container) + + // the canvas for plotting + const canvas = document.createElement('canvas') + container.append(canvas) + + // Chart-class from chartjs + const chart = new Chart(canvas, { // eslint-disable-line + type: 'scatter', + data: { + datasets: [{ + label: label, + data: points, + showLine: true, + fill: false, + tension: 0, + borderColor: 'black' + }] + }, + options: { + maintainAspectRatio: false, + responsive: true + } + }) +} + +function exampleEquation1 (x, y) { + return x +} + +// example from https://en.wikipedia.org/wiki/Euler_method +function exampleEquation2 (x, y) { + return y +} + +// example from https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ +function exampleEquation3 (x, y) { + return x + y + x * y +} + +const points1 = eulerFull(0, 4, 0.1, 0, exampleEquation1) +const points2 = eulerFull(0, 4, 1, 1, exampleEquation2) +const points3 = eulerFull(0, 0.1, 0.025, 1, exampleEquation3) + +console.log(points1) +console.log(points2) +console.log(points3) + +// plot the results if the script is executed in a browser with a window-object +if (typeof window !== 'undefined') { + const script = document.createElement('script') + + // using chartjs + script.src = 'https://www.chartjs.org/dist/2.9.4/Chart.min.js' + script.onload = function () { + plotLine('example 1: dy/dx = x', points1, 600, 400) + plotLine('example 2: dy/dx = y', points2, 600, 400) + plotLine('example 3: dy/dx = x + y + x * y', points3, 600, 400) + } + document.body.append(script) +}