|
| 1 | +/* |
| 2 | +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). |
| 3 | +(description adapted from https://en.wikipedia.org/wiki/Euler_method ) |
| 4 | +(see also: https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ ) |
| 5 | +*/ |
| 6 | + |
| 7 | +/* |
| 8 | +Doctests |
| 9 | +> eulerStep(0, 0.1, 0, function(x, y){return x}) |
| 10 | +0 |
| 11 | +> eulerStep(2, 1, 1, function(x, y){return x * x}) |
| 12 | +5 |
| 13 | +> eulerFull(0, 3, 1, 0, function(x, y){return x}) |
| 14 | +[{"x": 0, "y": 0}, {"x": 1, "y": 0}, {"x": 2, "y": 1}, {"x": 3, "y": 3}] |
| 15 | +> eulerFull(3, 4, 0.5, 1, function(x, y){return x * x}) |
| 16 | +[{"x": 3, "y": 1}, {"x": 3.5, "y": 5.5}, {"x": 4, "y": 11.625}] |
| 17 | +*/ |
| 18 | + |
| 19 | +function eulerStep (xCurrent, stepSize, yCurrent, differentialEquation) { |
| 20 | + // calculates the next y-value based on the current value of x, y and the stepSize |
| 21 | + const yNext = yCurrent + stepSize * differentialEquation(xCurrent, yCurrent) |
| 22 | + return yNext |
| 23 | +} |
| 24 | + |
| 25 | +function eulerFull (xStart, xEnd, stepSize, yStart, differentialEquation) { |
| 26 | + // loops through all the steps until xEnd is reached, adds a point for each step and then returns all the points |
| 27 | + const points = [{ x: xStart, y: yStart }] |
| 28 | + let yCurrent = yStart |
| 29 | + let xCurrent = xStart |
| 30 | + |
| 31 | + while (xCurrent <= xEnd - stepSize) { |
| 32 | + // Euler method for next step |
| 33 | + yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation) |
| 34 | + xCurrent += stepSize |
| 35 | + points.push({ x: xCurrent, y: yCurrent }) |
| 36 | + } |
| 37 | + |
| 38 | + return points |
| 39 | +} |
| 40 | + |
| 41 | +function plotLine (label, points, width, height) { |
| 42 | + // utility function to plot the results |
| 43 | + |
| 44 | + // container needed to control the size of the canvas |
| 45 | + const container = document.createElement('div') |
| 46 | + container.style.width = width + 'px' |
| 47 | + container.style.height = height + 'px' |
| 48 | + document.body.append(container) |
| 49 | + |
| 50 | + // the canvas for plotting |
| 51 | + const canvas = document.createElement('canvas') |
| 52 | + container.append(canvas) |
| 53 | + |
| 54 | + // Chart-class from chartjs |
| 55 | + const chart = new Chart(canvas, { // eslint-disable-line |
| 56 | + type: 'scatter', |
| 57 | + data: { |
| 58 | + datasets: [{ |
| 59 | + label: label, |
| 60 | + data: points, |
| 61 | + showLine: true, |
| 62 | + fill: false, |
| 63 | + tension: 0, |
| 64 | + borderColor: 'black' |
| 65 | + }] |
| 66 | + }, |
| 67 | + options: { |
| 68 | + maintainAspectRatio: false, |
| 69 | + responsive: true |
| 70 | + } |
| 71 | + }) |
| 72 | +} |
| 73 | + |
| 74 | +function exampleEquation1 (x, y) { |
| 75 | + return x |
| 76 | +} |
| 77 | + |
| 78 | +// example from https://en.wikipedia.org/wiki/Euler_method |
| 79 | +function exampleEquation2 (x, y) { |
| 80 | + return y |
| 81 | +} |
| 82 | + |
| 83 | +// example from https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ |
| 84 | +function exampleEquation3 (x, y) { |
| 85 | + return x + y + x * y |
| 86 | +} |
| 87 | + |
| 88 | +const points1 = eulerFull(0, 4, 0.1, 0, exampleEquation1) |
| 89 | +const points2 = eulerFull(0, 4, 1, 1, exampleEquation2) |
| 90 | +const points3 = eulerFull(0, 0.1, 0.025, 1, exampleEquation3) |
| 91 | + |
| 92 | +console.log(points1) |
| 93 | +console.log(points2) |
| 94 | +console.log(points3) |
| 95 | + |
| 96 | +// plot the results if the script is executed in a browser with a window-object |
| 97 | +if (typeof window !== 'undefined') { |
| 98 | + const script = document.createElement('script') |
| 99 | + |
| 100 | + // using chartjs |
| 101 | + script.src = 'https://www.chartjs.org/dist/2.9.4/Chart.min.js' |
| 102 | + script.onload = function () { |
| 103 | + plotLine('example 1: dy/dx = x', points1, 600, 400) |
| 104 | + plotLine('example 2: dy/dx = y', points2, 600, 400) |
| 105 | + plotLine('example 3: dy/dx = x + y + x * y', points3, 600, 400) |
| 106 | + } |
| 107 | + document.body.append(script) |
| 108 | +} |
0 commit comments