Euler method: Difference between revisions

Added Xbasic
m (→‎{{header|Wren}}: Wren-trait -> Wren-iterate)
(Added Xbasic)
 
(29 intermediate revisions by 9 users not shown)
Line 245:
done
</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">euler: function [f, y0, a, b, h][
[t,y]: @[a, y0]
 
while [t < b][
print [to :string .format:".3f" t, to :string .format:".3f" y]
t: t + h
y: y + h * call f @[t,y]
]
]
 
newtoncooling: function [ti, te]->
(neg 0.07) * te - 20
 
euler 'newtoncooling 100.0 0.0 100.0 10.0</syntaxhighlight>
 
{{out}}
 
<pre>0.000 100.000
10.000 44.000
20.000 27.200
30.000 22.160
40.000 20.648
50.000 20.194
60.000 20.058
70.000 20.017
80.000 20.005
90.000 20.002</pre>
 
=={{header|ATS}}==
{{trans|Ol}}
 
The following program's output should be fed to [[Gnuplot]], which will produce a PNG (using either the font that is specified by the ATS program or a fallback substitute). You can run the program with a command such as this: <code>patscc -g -O2 -std=gnu2x -DATS_MEMALLOC_LIBC euler_method_task.dats && ./a.out | gnuplot</code>
 
All data requiring allocation is allocated as linear types, and so is not leaked. That is, roughly speaking: it requires no garbage collection.
 
<syntaxhighlight lang="ats">
#include "share/atspre_staload.hats"
staload UN = "prelude/SATS/unsafe.sats"
 
#define NIL list_vt_nil ()
#define :: list_vt_cons
 
(* Approximate y(t) in dy/dt=f(t,y), y(a)=y0, t going from a to b with
positive step size h. This implementation of euler_method requires
f to be a unboxed linear closure. *)
extern fn {tk : tkind}
euler_method (f : &(g0float tk, g0float tk) -<clo1> g0float tk,
y0 : g0float tk,
a : g0float tk,
b : g0float tk,
h : g0float tk) : List1_vt @(g0float tk, g0float tk)
 
implement {tk}
euler_method (f, y0, a, b, h) =
let
typedef point_pair = @(g0float tk, g0float tk)
 
fun
loop (f : &(g0float tk, g0float tk) -<clo1> g0float tk,
t : g0float tk,
y : g0float tk,
point_pairs : List0_vt point_pair)
: List1_vt point_pair =
let
val point_pairs = @(t, y) :: point_pairs
in
if b <= t then
reverse<point_pair> point_pairs
else
loop (f, t + h, y + (h * f (t, y)), point_pairs)
end
in
loop (f, a, y0, NIL)
end
 
fun {tk : tkind}
write_point_pairs
(outf : FILEref,
point_pairs : !List0_vt @(g0float tk, g0float tk))
: void =
case+ point_pairs of
| NIL => ()
| (@(t, y) :: tl) =>
begin
fprint_val<g0float tk> (outf, t);
fprint! (outf, " ");
fprint_val<g0float tk> (outf, y);
fprintln! (outf);
write_point_pairs (outf, tl)
end
 
implement
main0 () =
let
(* Implement f as a stack-allocated linear closure. *)
var f =
lam@ (t : double, y : double) : double => ~0.07 * (y - 20.0)
 
val data2 = euler_method<dblknd> (f, 100.0, 0.0, 100.0, 2.0)
and data5 = euler_method<dblknd> (f, 100.0, 0.0, 100.0, 5.0)
and data10 = euler_method<dblknd> (f, 100.0, 0.0, 100.0, 10.0)
 
val outf = stdout_ref
in
fprintln! (outf, "set encoding utf8");
fprintln! (outf, "set term png size 1000,750 font 'RTF Amethyst Pro,16'");
fprintln! (outf, "set output 'newton-cooling-ATS.png'");
fprintln! (outf, "set grid");
fprintln! (outf, "set title 'Newton’s Law of Cooling'");
fprintln! (outf, "set xlabel 'Elapsed time (seconds)'");
fprintln! (outf, "set ylabel 'Temperature (Celsius)'");
fprintln! (outf, "set xrange [0:100]");
fprintln! (outf, "set yrange [15:100]");
fprintln! (outf, "y(x) = 20.0 + (80.0 * exp (-0.07 * x))");
fprintln! (outf, "plot y(x) with lines title 'Analytic solution', \\");
fprintln! (outf, " '-' with linespoints title 'Euler method, step size 2s', \\");
fprintln! (outf, " '-' with linespoints title 'Step size 5s', \\");
fprintln! (outf, " '-' with linespoints title 'Step size 10s'");
write_point_pairs (outf, data2);
fprintln! (outf, "e");
write_point_pairs (outf, data5);
fprintln! (outf, "e");
write_point_pairs (outf, data10);
fprintln! (outf, "e");
 
free data2;
free data5;
free data10
end
</syntaxhighlight>
 
{{out}}
[[File:Euler method ATS--newton-cooling.2023.04.26.12.24.43.png|thumb|none|alt=The output of the ATS program, plotted by Gnuplot.]]
 
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
{{trans|GW-BASIC}}
<syntaxhighlight lang="qbasic">100 HOME
110 PRINT "Time ";
120 FOR S = 0 TO 100.1 STEP 10
130 PRINT S; " ";
140 NEXT S
150 PRINT
160 PRINT "Dif eq ";
170 FOR S = 0 TO 100.1 STEP 10
180 LET T = 20+(100-20)*EXP(-.07*S)
190 PRINT LEFT$(STR$(T),5); " ";
200 NEXT S
210 PRINT
220 LET P = 2 : GOSUB 260
230 LET P = 5 : GOSUB 260
240 LET P = 10 : GOSUB 260
250 END
260 REM Euler(paso)
270 LET S = 0
280 LET T = 100
290 PRINT "Step ";P; " ";
300 FOR S = 0 TO 100 STEP P
310 IF S - (S/10) * 10 = 0 THEN PRINT LEFT$(STR$(T),5); " ";
320 LET T = T+(P)*(-.07*(T-20))
330 IF S > 100 THEN GOTO 350
340 NEXT S
350 PRINT
360 RETURN</syntaxhighlight>
 
==={{header|BASIC256}}===
{{trans|XPL0}}
<syntaxhighlight lang="vbnet">print "Time ";
tiempo = 0.0
while tiempo <= 100.1
print rjust(string(tiempo), 5); " ";
tiempo += 10.0
end while
print
 
print "Dif eq ";
tiempo = 0.0
while tiempo <= 100.1
temperatura = 20.0 + (100.0-20.0) * exp(-0.07*tiempo)
print rjust(left(string(temperatura), 5), 5); " ";
tiempo += 10.0
end while
print
 
call Euler(2)
call Euler(5)
call Euler(10)
end
 
subroutine Euler(paso)
tiempo = 0
temperatura = 100.0
print "Step "; rjust(string(paso), 2); " ";
 
while tiempo <= 100
if (tiempo mod 10) = 0 then print rjust(left(string(temperatura), 5), 5); " ";
temperatura += float(paso) * (-0.07*(temperatura-20.0))
tiempo += paso
end while
print
end subroutine</syntaxhighlight>
 
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> PROCeuler("-0.07*(y-20)", 100, 0, 100, 2)
Line 284 ⟶ 487:
100.000 20.000
</pre>
 
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
Same code as [[#GW-BASIC|GW-BASIC]]
 
==={{header|Craft Basic}}===
<syntaxhighlight lang="basic">precision 4
 
let s = 2
gosub euler
 
let s = 5
gosub euler
 
let s = 10
gosub euler
 
end
 
sub euler
 
cls
cursor 1, 1
wait
print "step: ", s
 
let b = 100
let y = 100
 
for t = 0 to b step s
 
print t, " : ", y
 
let y = y + s * (-0.07 * (y - 20))
 
gosub delay
 
next t
 
alert "step ", s, " finished"
 
return
 
sub delay
 
let w = clock
 
do
 
wait
 
loop clock < w + 200
 
return</syntaxhighlight>
{{out| Output}}<pre>step: 2
100 88.8000 79.1680 70.8845 63.7607 57.6342 52.3654 47.8342 43.9374 40.5862 37.7041 35.2255 33.0939 31.2608 29.6843 28.3285 27.1625 26.1597 25.2973 24.5557 23.9179 23.3694 22.8977 22.4920 22.1431 21.8431 21.5851 21.3632 21.1724 21.0083 20.8671 20.7457 20.6413 20.5515 20.4743 20.4079 20.3508 20.3017 20.2595 20.2232 20.1920 20.1651 20.1420 20.1221 20.1050 20.0903 20.0777 20.0668 20.0574 20.0494 20.0425
 
step: 5
100 72 53.8000 41.9700 34.2805 29.2823 26.0335 23.9218 22.5492 21.6570 21.0771 20.7001 20.4551 20.2958 20.1923 20.1250 20.0813 20.0528 20.0343 20.0223 20.0145
 
step: 10
100 44 27.2000 22.1600 20.6480 20.1944 20.0583 20.0175 20.0053 20.0016 20.0005 </pre>
 
==={{header|FreeBASIC}}===
Line 362 ⟶ 627:
 
</pre>
 
==={{header|Gambas}}===
{{trans|XPL0}}
<syntaxhighlight lang="vbnet">Public Sub Main()
Dim tiempo As Float, temperatura As Float
 
Print "Time ";
tiempo = 0.0
While tiempo <= 100.1
Print Format$(tiempo, "#######");
tiempo += 10.0
Wend
Print
Print "Dif eq ";
tiempo = 0.0
While tiempo <= 100.1
temperatura = 20.0 + (100.0 - 20.0) * Exp(-0.07 * tiempo)
Print Format$(temperatura, "####.#0");
tiempo += 10.0
Wend
Print
Euler(2)
Euler(5)
Euler(10)
End
 
Public Sub Euler(paso As Integer)
 
Dim tiempo As Integer = 0
Dim temperatura As Float = 100.0
 
Print "Step "; Format$(paso, "##"); " ";
Do While tiempo <= 100
If (tiempo Mod 10) = 0 Then Print Format$(temperatura, "####.#0");
temperatura += (paso) * (-0.07 * (temperatura - 20.0))
tiempo += paso
Loop
Print
 
End Sub</syntaxhighlight>
 
==={{header|GW-BASIC}}===
{{trans|XPL0}}
{{works with|PC-BASIC|any}}
{{works with|BASICA}}
{{works with|QBasic}}
{{works with|MSX BASIC}}
<syntaxhighlight lang="qbasic">100 CLS
110 PRINT "Time ";
120 FOR TIEMPO = 0 TO 100.1 STEP 10
130 PRINT USING " ###";TIEMPO;
140 NEXT TIEMPO
150 PRINT
160 PRINT "Dif eq ";
170 FOR TIEMPO = 0 TO 100.1 STEP 10
180 TEMPERATURA = 20+(100-20)*EXP(-.07*TIEMPO)
190 PRINT USING "###.##";TEMPERATURA;
200 NEXT TIEMPO
210 PRINT
220 PASO = 2 : GOSUB 260
230 PASO = 5 : GOSUB 260
240 PASO = 10 : GOSUB 260
250 END
260 REM Euler(paso)
270 TIEMPO = 0
280 TEMPERATURA = 100
290 PRINT USING "Step ## ";PASO;
300 FOR TIEMPO = 0 TO 100 STEP PASO
310 IF (TIEMPO MOD 10) = 0 THEN PRINT USING "###.##";TEMPERATURA;
320 TEMPERATURA = TEMPERATURA+(PASO)*(-.07*(TEMPERATURA-20))
330 IF TIEMPO > 100 THEN EXIT FOR
340 NEXT TIEMPO
350 PRINT
360 RETURN</syntaxhighlight>
 
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
Same code as [[#GW-BASIC|GW-BASIC]]
 
==={{header|QBasic}}===
{{trans|XPL0}}
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">DECLARE SUB Euler (paso AS INTEGER)
 
CLS
PRINT "Time ";
tiempo = 0!
WHILE tiempo <= 100.1
PRINT USING "######"; tiempo;
tiempo = tiempo + 10!
WEND
PRINT
 
PRINT "Dif eq ";
tiempo = 0!
WHILE tiempo <= 100.1
temperatura = 20! + (100! - 20!) * EXP(-.07 * tiempo)
PRINT USING "###.##"; temperatura;
tiempo = tiempo + 10!
WEND
PRINT
 
Euler (2)
Euler (5)
Euler (10)
END
 
SUB Euler (paso AS INTEGER)
tiempo = 0
temperatura = 100!
PRINT USING "Step ## "; paso;
DO WHILE tiempo <= 100
IF (tiempo MOD 10) = 0 THEN PRINT USING "###.##"; temperatura;
temperatura = temperatura + paso * (-.07 * (temperatura - 20!))
tiempo = tiempo + paso
LOOP
PRINT
END SUB</syntaxhighlight>
 
==={{header|Run BASIC}}===
Line 398 ⟶ 788:
70 20.017496
80 20.0052488</pre>
 
==={{header|True BASIC}}===
{{trans|QBasic}}
<syntaxhighlight lang="qbasic">SUB euler (paso)
LET tiempo = 0
LET temperatura = 100
PRINT USING "Step ## ": paso;
DO WHILE tiempo <= 100
IF (REMAINDER(tiempo,10)) = 0 THEN PRINT USING "###.##": temperatura;
LET temperatura = temperatura+paso*(-.07*(temperatura-20))
LET tiempo = tiempo+paso
LOOP
PRINT
END SUB
 
PRINT "Time ";
LET tiempo = 0
DO WHILE tiempo <= 100.1
PRINT USING "######": tiempo;
LET tiempo = tiempo+10
LOOP
PRINT
PRINT "Dif eq ";
LET tiempo = 0
DO WHILE tiempo <= 100.1
LET temperatura = 20+(100-20)*EXP(-.07*tiempo)
PRINT USING "###.##": temperatura;
LET tiempo = tiempo+10
LOOP
PRINT
 
CALL Euler (2)
CALL Euler (5)
CALL Euler (10)
END</syntaxhighlight>
{{out}}
<pre>Same as QBasic entry.</pre>
 
==={{header|XBasic}}===
{{trans|BASIC256}}
{{works with|Windows XBasic}}
<syntaxhighlight lang="qbasic">PROGRAM "Euclidean rhythm"
VERSION "0.0001"
IMPORT "xma"
 
DECLARE FUNCTION Entry ()
DECLARE FUNCTION Euler (paso)
 
FUNCTION Entry ()
PRINT "Time ";
tiempo! = 0.0
DO WHILE tiempo! <= 100.1
PRINT FORMAT$ ("#######", tiempo!);
tiempo! = tiempo! + 10.0
LOOP
PRINT
 
PRINT "Dif eq ";
tiempo! = 0.0
DO WHILE tiempo! <= 100.1
temperatura! = 20.0 + (100.0 - 20.0) * EXP(-0.07 * tiempo!)
PRINT FORMAT$ ("####.##", temperatura!);
tiempo! = tiempo! + 10.0
LOOP
PRINT
 
Euler(2)
Euler(5)
Euler(10)
END FUNCTION
 
FUNCTION Euler (paso)
tiempo! = 0
temperatura! = 100.0
PRINT FORMAT$ ("Step ## ", paso);
 
DO WHILE tiempo! <= 100
IF (tiempo! MOD 10) = 0 THEN PRINT FORMAT$ ("####.##", temperatura!);
temperatura! = temperatura! + SINGLE(paso) * (-0.07 * (temperatura! - 20.0))
tiempo! = tiempo! + paso
LOOP
PRINT
END FUNCTION
END PROGRAM</syntaxhighlight>
 
==={{header|Yabasic}}===
{{trans|XPL0}}
<syntaxhighlight lang="vbnet">print "Time ";
tiempo = 0.0
while tiempo <= 100.1
print tiempo using "#######";
tiempo = tiempo + 10.0
wend
print
 
print "Dif eq ";
tiempo = 0.0
while tiempo <= 100.1
temperatura = 20.0 + (100.0-20.0) * exp(-0.07*tiempo)
print temperatura using "####.##";
tiempo = tiempo + 10.0
wend
print
 
Euler_(2)
Euler_(5)
Euler_(10)
end
 
sub Euler_(paso)
local tiempo, temperatura
tiempo = 0
temperatura = 100.0
print "Step ", paso using "##", " ";
while tiempo <= 100
if mod(tiempo, 10) = 0 print temperatura using "####.##";
temperatura = temperatura + (paso) * (-0.07*(temperatura-20.0))
tiempo = tiempo + paso
end while
print
end sub</syntaxhighlight>
 
=={{header|C}}==
Line 774 ⟶ 1,286:
90.000 20.002
done</pre>
 
=={{header|Dart}}==
{{trans|Swift}}
<syntaxhighlight lang="Dart">
import 'dart:math';
import "dart:io";
 
const double k = 0.07;
const double initialTemp = 100.0;
const double finalTemp = 20.0;
const int startTime = 0;
const int endTime = 100;
 
void ivpEuler(double Function(double, double) function, double initialValue, int step) {
stdout.write(' Step ${step.toString().padLeft(2)}: ');
var y = initialValue;
for (int t = startTime; t <= endTime; t += step) {
if (t % 10 == 0) {
stdout.write(y.toStringAsFixed(3).padLeft(7));
}
y += step * function(t.toDouble(), y);
}
print('');
}
 
void analytic() {
stdout.write(' Time: ');
for (int t = startTime; t <= endTime; t += 10) {
stdout.write(t.toString().padLeft(7));
}
stdout.write('\nAnalytic: ');
for (int t = startTime; t <= endTime; t += 10) {
var temp = finalTemp + (initialTemp - finalTemp) * exp(-k * t);
stdout.write(temp.toStringAsFixed(3).padLeft(7));
}
print('');
}
 
double cooling(double t, double temp) {
return -k * (temp - finalTemp);
}
 
void main() {
analytic();
ivpEuler(cooling, initialTemp, 2);
ivpEuler(cooling, initialTemp, 5);
ivpEuler(cooling, initialTemp, 10);
}
</syntaxhighlight>
{{out}}
<pre>
Time: 0 10 20 30 40 50 60 70 80 90 100
Analytic: 100.000 59.727 39.728 29.797 24.865 22.416 21.200 20.596 20.296 20.147 20.073
Step 2: 100.000 57.634 37.704 28.328 23.918 21.843 20.867 20.408 20.192 20.090 20.042
Step 5: 100.000 53.800 34.280 26.034 22.549 21.077 20.455 20.192 20.081 20.034 20.014
Step 10: 100.000 44.000 27.200 22.160 20.648 20.194 20.058 20.017 20.005 20.002 20.000
 
</pre>
 
=={{header|Delphi}}==
 
[[Euler_method#Pascal | Pascal]]
 
=={{header|EasyLang}}==
[https://easylang.online/show/#cod=jZDNbsIwEITv+xQjKlX8CGsJiiBV8wTcUO4oBAORQhyZpSF9+moNpYA49ObZn/HOly2RImJaIMWYDc9oe6oL5HVedVIWyBgCQwC8lZOvkS0xQj9jjJEtBxiicS0iM5vMozn6CwwhAzLUyVmQIomp8a7Axuft6maaYw1zcS1c5TyYExUH92UxZ+iy6mAyThGrEHsW9H49elraOg/9JYc4rLUCoCprC/lLMGFGcDNkSO/Y+XJDOtWWG9mDzZTU+1h+W0zp8VLWdXrDhUptW3H1qnCuKusdxB6aBzaavh+qAQ6Zu/D2VFmPjkP4o9hGoz9SKFz1Twq6/4Ee3oNTqCuGMI0UHeur3ZeVkvh8RtNdpWCU3gzC6lVj+By1uwd4zaJgAx9MGAnz616MOI5ftyJwwkQ/ Run it]
 
<syntaxhighlight>
TR = 20
K = -0.07
func analytic T0 t .
return TR + (T0 - TR) * pow 2.71828 (K * t)
.
ytxt = 95
proc draw_analytic a b . .
color 009
move 80 ytxt
ytxt -= 5
text "analytic"
for t = a to b
line t analytic 100 t
.
.
drawgrid
linewidth 0.3
textsize 3
draw_analytic 0 100
#
func newton_cooling temp .
return K * (temp - TR)
.
proc draw_euler y0 a b step col . .
color col
move 80 ytxt
ytxt -= 5
text "step: " & step
t = a
y = y0
while t < b
line t y
t += step
y += step * newton_cooling y
.
.
draw_euler 100 0 100 10 900
draw_euler 100 0 100 5 555
draw_euler 100 0 100 2 090
</syntaxhighlight>
 
=={{header|Elixir}}==
Line 1,922 ⟶ 2,537:
euler[10, 100]
20.0005</pre>
 
=={{header|MATLAB}}==
{{trans|Julia}}
<syntaxhighlight lang="MATLAB}}">
clear all;close all;clc;
format longG;
 
% Main Script
for h = [5, 10]
fprintf('Step %d:\n\n', h);
tabular(15, 'Time', 'Euler', 'Analytic');
T0 = 100.0;
t0 = 0;
t1 = 100;
T = euler(@(T) -0.07 * (T - 20.0), T0, t0, t1, h);
for i = 1:length(T)
t = (i-1) * h;
analytic = 20.0 + 80.0 * exp(-0.07 * t);
tabular(15, t, round(T(i), 6), round(analytic, 6));
end
fprintf('\n');
end
 
function T = euler(f, T0, t0, t1, h)
% EULER A simple implementation of Euler's method for solving ODEs
% f - function handle for the derivative
% T0 - initial temperature
% t0, t1 - start and end times
% h - step size
T = T0;
for t = t0:h:t1
T(end+1) = T(end) + h * f(T(end));
end
end
 
function tabular(width, varargin)
% TABULAR Prints a series of values in a tabular form
% width - cell width
% varargin - variable number of arguments representing cells
for i = 1:length(varargin)
fprintf('%-*s', width, num2str(varargin{i}));
end
fprintf('\n');
end
</syntaxhighlight>
{{out}}
<pre>
Step 5:
 
Time Euler Analytic
0 100 100
5 72 76.375
10 53.8 59.7268
15 41.97 47.995
20 34.2805 39.7278
25 29.2823 33.9019
30 26.0335 29.7965
35 23.9218 26.9035
40 22.5492 24.8648
45 21.657 23.4282
50 21.077 22.4158
55 20.7001 21.7024
60 20.455 21.1996
65 20.2958 20.8454
70 20.1923 20.5957
75 20.125 20.4198
80 20.0812 20.2958
85 20.0528 20.2085
90 20.0343 20.1469
95 20.0223 20.1035
100 20.0145 20.073
105 20.0094 20.0514
 
Step 10:
 
Time Euler Analytic
0 100 100
10 44 59.7268
20 27.2 39.7278
30 22.16 29.7965
40 20.648 24.8648
50 20.1944 22.4158
60 20.0583 21.1996
70 20.0175 20.5957
80 20.0052 20.2958
90 20.0016 20.1469
100 20.0005 20.073
110 20.0001 20.0362
</pre>
 
=={{header|Maxima}}==
Line 2,053 ⟶ 2,757:
40 20.648
</pre>
 
=={{header|ObjectIcon}}==
 
Output is a PNG produced by [[Gnuplot]], which is run as a child process. The program demonstrates both UTF-8 support and <code>ipl.functional</code>.
 
Note the string written with <code>u"</code> because it contains a non-ASCII character (the apostrophe).
 
<syntaxhighlight lang="objecticon">
import
io(open),
ipl.functional(_a, lambda)
 
$encoding UTF-8
 
procedure main ()
local f, plot, ty
local data2, data5, data10
 
# Newton's cooling law, f(t,Temp) = -0.07*(Temp-20)
f := lambda { -0.07 * (_a[2] - 20.0) }
 
data2 := euler_method (f, 100, 0, 100, 2)
data5 := euler_method (f, 100, 0, 100, 5)
data10 := euler_method (f, 100, 0, 100, 10)
 
plot := open ("gnuplot", "pw")
plot.write ("set encoding utf8")
plot.write ("set term png size 1000,750 font 'Fanwood Text,18'")
plot.write ("set output 'newton-cooling-OI.png'")
plot.write ("set grid")
plot.write (u"set title 'Newton’s Law of Cooling'")
plot.write ("set xlabel 'Elapsed time (seconds)'")
plot.write ("set ylabel 'Temperature (Celsius)'")
plot.write ("set xrange [0:100]")
plot.write ("set yrange [15:100]")
plot.write ("y(x) = 20.0 + (80.0 * exp (-0.07 * x))")
plot.write ("plot y(x) with lines title 'Analytic solution', \\")
plot.write (" '-' with linespoints title 'Euler method, step size 2s', \\")
plot.write (" '-' with linespoints title 'Step size 5s', \\")
plot.write (" '-' with linespoints title 'Step size 10s'")
every plot.write (ty := !data2 & ty[1] || " " || ty[2])
plot.write ("e")
every plot.write (ty := !data5 & ty[1] || " " || ty[2])
plot.write ("e")
every plot.write (ty := !data10 & ty[1] || " " || ty[2])
plot.write ("e")
plot.close()
end
 
# Approximate y(t) in dy/dt=f(t,y), y(a)=y0, t going from a to b with
# positive step size h.
procedure euler_method (f, y0, a, b, h)
local t, y, results
 
t := a
y := y0
results := [[t, y]]
while t + h <= b do
{
y +:= h * f(t, y)
t +:= h
put (results, [t, y])
}
return results
end
</syntaxhighlight>
 
{{out}}
[[File:Euler method OI--newton-cooling.2023.04.26.09.17.33.png|thumb|none|alt=A plot of the curves of the Euler method task.]]
 
=={{header|OCaml}}==
Line 2,145 ⟶ 2,918:
100 : 20.000472392
</pre>
 
=={{header|Ol}}==
{{trans|ObjectIcon}}
See also [[#Scheme|Scheme]].
 
The output is meant to be fed into [[Gnuplot]]. You can run the program like this: <code>ol name-you-saved-the-program-as.scm | gnuplot</code>
 
(Gnuplot may substitute a different font.)
 
<syntaxhighlight lang="Scheme">
(define (euler-method f y0 a b h)
;; Approximate y(t) in dy/dt=f(t,y), y(a)=y0, t going from a to b
;; with positive step size h. Produce a list of point pairs as
;; output.
(let loop ((t a)
(y y0)
(point-pairs '()))
(let ((point-pairs (cons (cons t y) point-pairs)))
(if (<= b t)
(reverse point-pairs)
(loop (+ t h) (+ y (* h (f t y))) point-pairs)))))
 
(define (newton-cooling-step t Temperature)
;; Newton's cooling law, with temperature in Celsius:
;;
;; f(t, Temperature) = -0.07*(Temperature - 20)
;;
(* -0.07 (- Temperature 20)))
 
(define data-for-stepsize=2
(euler-method newton-cooling-step 100.0 0.0 100.0 2.0))
 
(define data-for-stepsize=5
(euler-method newton-cooling-step 100.0 0.0 100.0 5.0))
 
(define data-for-stepsize=10
(euler-method newton-cooling-step 100.0 0.0 100.0 10.0))
 
(define (display-point-pairs point-pairs)
(let loop ((p point-pairs))
(if (pair? p)
(begin
(display (inexact (caar p)))
(display " ")
(display (inexact (cdar p)))
(newline)
(loop (cdr p))))))
 
(display "set encoding utf8") (newline)
(display "set term png size 1000,750 font 'Farao Book,16'") (newline)
(display "set output 'newton-cooling-Scheme.png'") (newline)
(display "set grid") (newline)
(display "set title 'Newton’s Law of Cooling'") (newline)
(display "set xlabel 'Elapsed time (seconds)'") (newline)
(display "set ylabel 'Temperature (Celsius)'") (newline)
(display "set xrange [0:100]") (newline)
(display "set yrange [15:100]") (newline)
(display "y(x) = 20.0 + (80.0 * exp (-0.07 * x))") (newline)
(display "plot y(x) with lines title 'Analytic solution', \\") (newline)
(display " '-' with linespoints title 'Euler method, step size 2s', \\") (newline)
(display " '-' with linespoints title 'Step size 5s', \\") (newline)
(display " '-' with linespoints title 'Step size 10s'") (newline)
(display-point-pairs data-for-stepsize=2)
(display "e") (newline)
(display-point-pairs data-for-stepsize=5)
(display "e") (newline)
(display-point-pairs data-for-stepsize=10)
(display "e") (newline)
</syntaxhighlight>
 
{{out}}
[[File:Euler method Scheme--newton-cooling.2023.04.26.10.30.19.png|thumb|none|alt=A plot of the cooling data, for all the cases.]]
 
=={{header|Pascal}}==
Line 3,068 ⟶ 3,913:
10 57.634
</pre>
 
=={{header|RPL}}==
This is a typical task for which RPL was designed.
(t<sub>n</sub>,y<sub>n</sub>) are handled as complex numbers. This makes the iterations easier to calculate and facilitates the eventual display of the resulting curve, as RPL uses this data format to designate the pixels.
≪ → t temp '-'''K'''*(temp-'''TR''')' ≫ ‘'''F'''’ STO
≪ → h fn
≪ 1 10 '''START'''
DUP h OVER C→R fn EVAL h * R→C +
'''NEXT''' 10 →LIST
≫ ≫ ‘'''EULER'''’ STO
0.07 ''''K'''' STO 20 ''''TR'''' STO
 
(0,100) 2 ''''F'''' '''EULER'''
{{out}}
<pre>
1: { (2,88.8) (4,79.168) (6,70.88448) (8,63.7606528) (10,57.634161408) (12,52.3653788109) (14,47.8342257774) (16,43.9374341685) (18,40.5861933849) (20,37.704126311) }
</pre>
===Analytical solution===
≪ { } 2 20 '''FOR''' t t ''''TR'''+(100-'''TR''')*EXP(-'''K'''*t)' EVAL R→C + '''NEXT''' ≫
{{out}}
<pre>
1: { (2,89.5486588319) (3,84.8467396776) (4,80.4626993165) (5,76.3750471775) (6,72.5637455852) (7,69.0101115348) (8,65.6967251079) (9,62.6073440806) (10,59.7268243033) (11,57.0410454649) (12,54.5368418743) (13,52.2019379227) (14,50.0248879081) (15,47.9950199289) (16,46.1023835698) (17,44.3377011253) (18,42.69232212) (19,41.158180904) (20,39.7277571153) }
</pre>
Accuracy to the degree for the first seconds of cooling needs h to be set at 0.2 s or below
 
=={{header|Ruby}}==
Line 3,267 ⟶ 4,138:
DONE
</pre>
 
=={{header|Scheme}}==
See [[#Ol|Ol]]. That implementation is valid Scheme.
 
In many Scheme implementations (Chez Scheme, Gauche Scheme, Gambit Scheme, CHICKEN Scheme if run with "-R r7rs", etc.), the program will run without modification. For some other implementations, the call to <code>inexact</code> must be either removed or changed to <code>exact->inexact</code>. (The call is necessary for ol, which otherwise would have written fractions that gnuplot does not understand.)
 
=={{header|SequenceL}}==
Line 3,392 ⟶ 4,268:
90 20.002
</pre>
 
=={{header|Standard ML}}==
{{trans|Ol}}
{{works with|Poly/ML|5.9}}
{{works with|MLton|20210117}}
 
This program outputs commands for [[Gnuplot]], which will produce a PNG. Run the program with a command such as <code>poly --script name_you_gave_the_file.sml | gnuplot</code>.
 
<syntaxhighlight lang="sml">
(* Approximate y(t) in dy/dt=f(t,y), y(a)=y0, t going from a to b with
positive step size h. Produce a list of point pairs as output. *)
fun eulerMethod (f, y0, a, b, h) =
let
fun loop (t, y, pointPairs) =
let
val pointPairs = (t, y) :: pointPairs
in
if b <= t then
rev pointPairs
else
loop (t + h, y + (h * f (t, y)), pointPairs)
end
in
loop (a, y0, nil)
end
 
(* How to step temperature according to Newton's law of cooling. *)
fun f (t, temp) = ~0.07 * (temp - 20.0)
 
val data2 = eulerMethod (f, 100.0, 0.0, 100.0, 2.0)
and data5 = eulerMethod (f, 100.0, 0.0, 100.0, 5.0)
and data10 = eulerMethod (f, 100.0, 0.0, 100.0, 10.0)
 
fun printPointPairs pointPairs =
app (fn (t, y) => (print (Real.toString t);
print " ";
print (Real.toString y);
print "\n"))
pointPairs
 
;
 
print ("set encoding utf8\n");
print ("set term png size 1000,750 font 'Brioso Pro,16'\n");
print ("set output 'newton-cooling-SML.png'\n");
print ("set grid\n");
print ("set title 'Newton\\U+2019s Law of Cooling'\n");
print ("set xlabel 'Elapsed time (seconds)'\n");
print ("set ylabel 'Temperature (Celsius)'\n");
print ("set xrange [0:100]\n");
print ("set yrange [15:100]\n");
print ("y(x) = 20.0 + (80.0 * exp (-0.07 * x))\n");
print ("plot y(x) with lines title 'Analytic solution', \\\n");
print (" '-' with linespoints title 'Euler method, step size 2s', \\\n");
print (" '-' with linespoints title 'Step size 5s', \\\n");
print (" '-' with linespoints title 'Step size 10s'\n");
printPointPairs data2;
print ("e\n");
printPointPairs data5;
print ("e\n");
printPointPairs data10;
print ("e\n");
</syntaxhighlight>
 
{{out}}
[[File:Euler method SML--newton-cooling.2023.04.26.14.07.02.png|thumb|none|alt=The output of the Standard ML program, as plotted by Gnuplot.]]
 
=={{header|Swift}}==
Line 3,481 ⟶ 4,423:
90.000 20.002
done
</pre>
 
=={{header|Uiua}}==
'''Solution:'''
<syntaxhighlight lang="Uiua">
"Euler Solution"
T ← 100 # initial starting temp
TR ← 20 # room temp
TMINUSTR ← - TR T
h ← 10 # step size
k ← 0.07 # coefficent
TEND ← 100 # end time
n ← ÷ h 100 # steps
# inital starting point
T
.
# .. clone the top of stack and take if for next step
# repeat the steps n times with ⍥
Solution ← [⍥(.. - × h × k - TR)]+ n 1
⇌ ⊂ Solution T
 
# analytical solution
"Analytical Solution"
# apply function to LIST
List ← × k × h ⇡n
# Analytical solution applied
+ TR × TMINUSTR ⁿ ¯List e
 
</syntaxhighlight>
'''Example:'''
<pre>
"Euler Solution"
[100 43.99999999999999 27.199999999999996 22.159999999999997 20.648 20.194399999999998 20.05832 20.017496 20.0052488 20.00157464 20.000472392 20.0001417176 20.0001417176 20.0001417176]
 
"Analytical Solution"
[100 59.72682430331276 39.727757115328515 29.796514260238553 24.864805010017434 22.41579067378548 21.199646145638216 20.59572664567395 20.295829097318634 20.14690438216231]
</pre>
 
Line 3,665 ⟶ 4,643:
{{libheader|Wren-fmt}}
{{libheader|Wren-iterate}}
<syntaxhighlight lang="ecmascriptwren">import "./fmt" for Fmt
import "./iterate" for Stepped
 
var euler = Fn.new { |f, y, step, end|
2,122

edits