Euler method: Difference between revisions

115,786 bytes added ,  1 month ago
Added Xbasic
(Added Xbasic)
 
(153 intermediate revisions by 74 users not shown)
Line 1:
{{Task|Mathematical operations}}
 
Euler's method numerically approximates solutions of first-order ordinary differential equations (ODEs) with a given initial value. It is an explicit method for solving initial value problems (IVPs), as described in [[wp:Euler method|the wikipedia page]].
Euler's method numerically approximates solutions of first-order ordinary differential equations (ODEs) with a given initial value.   It is an explicit method for solving initial value problems (IVPs), as described in [[wp:Euler method|the wikipedia page]].
 
The ODE has to be provided in the following form:
 
::: <big><math>\frac{dy(t)}{dt} = f(t,y(t))</math></big>
 
with an initial value
 
::: <big><math>y(t_0) = y_0</math></big>
 
To get a numeric solution, we replace the derivative on the &nbsp; LHS &nbsp; with a finite difference approximation:
 
::: <big><math>\frac{dy(t)}{dt} \approx \frac{y(t+h)-y(t)}{h}</math></big>
 
then solve for <math>y(t+h)</math>:
 
::: <big><math>y(t+h) \approx y(t) + h \, \frac{dy(t)}{dt}</math></big>
 
which is the same as
 
::: <big><math>y(t+h) \approx y(t) + h \, f(t,y(t))</math></big>
 
The iterative solution rule is then:
 
::: <big><math>y_{n+1} = y_n + h \, f(t_n, y_n)</math></big>
 
where &nbsp; <big><math>h</math></big> &nbsp; is the step size, the most relevant parameter for accuracy of the solution. &nbsp; A smaller step size increases accuracy but also the computation cost, so it has always has to be hand-picked according to the problem at hand.
 
'''Example: Newton's Cooling Law'''
 
'''Example: Newton's Cooling Law'''
Newton's cooling law describes how an object of initial temperature <math>T(t_0) = T_0</math> cools down in an environment of temperature <math>T_R </math>:
 
Newton's cooling law describes how an object of initial temperature &nbsp; <big><math>T(t_0) = T_0</math></big> &nbsp; cools down in an environment of temperature &nbsp; <big><math>T_R</math></big>:
:<math>\frac{dT(t)}{dt} = -k \, \Delta T</math>
 
::: <big><math>\frac{dT(t)}{dt} = -k \, \Delta T</math></big>
or
::: <big><math>\frac{dT(t)}{dt} = -k \, (T(t) - T_R)</math></big>
 
<br>
:<math>\frac{dT(t)}{dt} = -k \, (T(t) - T_R)</math>
It says that the cooling rate &nbsp; <big><math>\frac{dT(t)}{dt}</math></big> &nbsp; of the object is proportional to the current temperature difference &nbsp; <big><math>\Delta T = (T(t) - T_R)</math></big> &nbsp; to the surrounding environment.
 
It says that the cooling rate <math>\frac{dT(t)}{dt}</math> of the object is proportional to the current temperature difference <math>\Delta T = (T(t) - T_R)</math> to the surrounding environment.
 
The analytical solution, which we will compare to the numerical approximation, is
::: <big><math>T(t) = T_R + (T_0 - T_R) \; e^{-k t}</math></big>
 
:<math>T(t) = T_R + (T_0 - T_R) \; e^{-k t}</math>
 
''';Task''':
Implement a routine of Euler's method and then to use it to solve the given example of Newton's cooling law with it for three different step sizes of:
:::* &nbsp; 2 s
:::* &nbsp; 5 s &nbsp; &nbsp; &nbsp; and
:::* &nbsp; 10 s
and to compare with the analytical solution.
 
The task is to implement a routine of Euler's method and then to use it to solve the given example of Newton's cooling law with it for three different step sizes of 2 s, 5 s and 10 s and to compare with the analytical solution.
The initial temperature <math>T_0</math> shall be 100 °C, the room temperature <math>T_R</math> 20 °C, and the cooling constant <math>k</math> 0.07. The time interval to calculate shall be from 0 s to 100 s.
 
;Initial values:
A reference solution ([[#Common Lisp|Common Lisp]]) can be seen below. We see that bigger step sizes lead to reduced approximation accuracy.
:::* &nbsp; initial temperature &nbsp; <big><math>T_0</math></big> &nbsp; shall be &nbsp; 100 °C
:::* &nbsp; room temperature &nbsp; <big><math>T_R</math></big> &nbsp; shall be &nbsp; 20 °C
:::* &nbsp; cooling constant &nbsp; &nbsp; <big><math>k</math></big> &nbsp; &nbsp; shall be &nbsp; 0.07
:::* &nbsp; time interval to calculate shall be from &nbsp; 0 s &nbsp; ──► &nbsp; 100 s
 
<br>
A reference solution ([[#Common Lisp|Common Lisp]]) can be seen below. &nbsp; We see that bigger step sizes lead to reduced approximation accuracy.
[[Image:Euler_Method_Newton_Cooling.png|center|750px]]
 
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">F euler(f, y0, a, b, h)
V t = a
V y = y0
L t <= b
print(‘#2.3 #2.3’.format(t, y))
t += h
y += h * f(t, y)
 
V newtoncooling = (time, temp) -> -0.07 * (temp - 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
100.000 20.000
</pre>
 
=={{header|Ada}}==
The solution is generic, usable for any floating point type. The package specification:
<syntaxhighlight lang="ada">
<lang Ada>
generic
type Number is digits <>;
Line 65 ⟶ 105:
) return Waveform;
end Euler;
</syntaxhighlight>
</lang>
The function Solve returns the solution of the differential equation for each of N+1 points, starting from the point T0. The implementation:
<syntaxhighlight lang="ada">
<lang Ada>
package body Euler is
function Solve
Line 85 ⟶ 125:
end Solve;
end Euler;
</syntaxhighlight>
</lang>
The test program:
<syntaxhighlight lang="ada">
<lang Ada>
with Ada.Text_IO; use Ada.Text_IO;
with Euler;
Line 106 ⟶ 146:
end loop;
end Test_Euler_Method;
</syntaxhighlight>
</lang>
Sample output:
<pre>
Line 121 ⟶ 161:
100: 2.00005E+01
</pre>
 
=={{header|ALGOL 68}}==
{{trans|D}} Note: This specimen retains the original [[#D|D]] coding style.
Line 126 ⟶ 167:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
<langsyntaxhighlight lang="algol68">#
Approximates y(t) in y'(t)=f(t,y) with y(a)=y0 and
t=a..b and the step size h.
Line 149 ⟶ 190:
main: (
euler(newton cooling law, 100, 0, 100, 10)
)</langsyntaxhighlight>
Ouput:
<pre>
Line 164 ⟶ 205:
done
</pre>
 
=={{header|ALGOL W}}==
{{Trans|ALGOL 68}}
Which is
{{Trans|D}}
<syntaxhighlight lang="algolw">begin % Euler's method %
% Approximates y(t) in y'(t)=f(t,y) with y(a)=y0 and t=a..b and the step size h. %
real procedure euler ( real procedure f; real value y0, a, b, h ) ;
begin
real y, t;
y := y0;
t := a;
while t < b do begin
write( r_format := "A", r_w := 8, r_d := 4, s_w := 0, t, ": ", y );
y := y + ( h * f(t, y) );
t := t + h
end while_t_lt_b ;
write( "done" );
y
end euler ;
 
% Example: Newton's cooling law %
real procedure newtonCoolingLaw ( real value time, t ) ; -0.07 * (t - 20);
 
euler( newtonCoolingLaw, 100, 0, 100, 10 )
end.</syntaxhighlight>
{{out}}
<pre>
0.0000: 100.0000
10.0000: 44.0000
20.0000: 27.2000
30.0000: 22.1600
40.0000: 20.6480
50.0000: 20.1944
60.0000: 20.0583
70.0000: 20.0175
80.0000: 20.0052
90.0000: 20.0015
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)
PROCeuler("-0.07*(y-20)", 100, 0, 100, 5)
PROCeuler("-0.07*(y-20)", 100, 0, 100, 10)
END
DEF PROCeuler(df$, y, a, b, s)
LOCAL t, @%
@% = &2030A
t = a
WHILE t <= b
PRINT t, y
y += s * EVAL(df$)
t += s
ENDWHILE
ENDPROC</syntaxhighlight>
'''Output:'''
<pre>
0.000 100.000
2.000 88.800
4.000 79.168
6.000 70.884
8.000 63.761
10.000 57.634
...
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
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}}===
<syntaxhighlight lang="freebasic">'Freebasic .9
'Custom rounding
#define round(x,N) Rtrim(Rtrim(Left(Str((x)+(.5*Sgn((x)))/(10^(N))),Instr(Str((x)+(.5*Sgn((x)))/(10^(N))),".")+(N)),"0"),".")
 
#macro Euler(fn,_y,min,max,h,printoption)
Print "Step ";#h;":":Print
Print "time","Euler"," Analytic"
If printoption<>"print" Then Print "Data omitted ..."
Scope
Dim As Double temp=(min),y=(_y)
Do
If printoption="print" Then Print temp,round(y,3),20+80*Exp(-0.07*temp)
y=y+(h)*(fn)
temp=temp+(h)
Loop Until temp>(max)
Print"________________"
Print
End Scope
#endmacro
 
Euler(-.07*(y-20),100,0,100,2,"don't print")
Euler(-.07*(y-20),100,0,100,5,"print")
Euler(-.07*(y-20),100,0,100,10,"print")
Sleep
</syntaxhighlight>
outputs (steps 5 and 10)
<pre>
Step 2:
 
time Euler Analytic
Data omitted ...
________________
 
Step 5:
 
time Euler Analytic
0 100 100
5 72 76.37504717749707
10 53.8 59.72682430331276
15 41.97 47.99501992889243
20 34.281 39.72775711532852
25 29.282 33.90191547603561
30 26.034 29.79651426023855
35 23.922 26.90348691994964
40 22.549 24.86480501001743
45 21.657 23.42817014936322
50 21.077 22.41579067378548
55 20.7 21.70237891507017
60 20.455 21.19964614563822
65 20.296 20.84537635070821
70 20.192 20.59572664567395
75 20.125 20.41980147193451
80 20.081 20.29582909731863
85 20.053 20.20846724147268
90 20.034 20.14690438216231
95 20.022 20.10352176843727
100 20.014 20.07295055724436
________________
 
Step 10:
 
time Euler Analytic
0 100 100
10 44 59.72682430331276
20 27.2 39.72775711532852
30 22.16 29.79651426023855
40 20.648 24.86480501001743
50 20.194 22.41579067378548
60 20.058 21.19964614563822
70 20.017 20.59572664567395
80 20.005 20.29582909731863
90 20.002 20.14690438216231
100 20 20.07295055724436
________________
 
</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}}===
<syntaxhighlight lang="rinbasic">x = euler(-0.07,-20, 100, 0, 100, 2)
x = euler-0.07,-20, 100, 0, 100, 5)
x = euler(-0.07,-20, 100, 0, 100, 10)
end
FUNCTION euler(da,db, y, a, b, s)
print "===== da:";da;" db:";db;" y:";y;" a:";a;" b:";b;" s:";s;" ==================="
t = a
WHILE t <= b
PRINT t;chr$(9);y
y = y + s * (da * (y + db))
t = t + s
WEND
END FUNCTION</syntaxhighlight>
<pre>===== da:-0.07 db:-20 y:100 a:0 b:100 s:2 ===================
0 100
2 88.8
4 79.168
6 70.88448
8 63.7606528
10 57.6341614
12 52.3653788
14 47.8342258
......
===== da:-0.07 db:-20 y:100 a:0 b:100 s:10 ===================
0 100
10 44.0
20 27.2
30 22.16
40 20.648
50 20.1944
60 20.05832
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}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <math.h>
 
Line 209 ⟶ 955:
 
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text"> 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</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
 
namespace prog
{
class MainClass
{
const float T0 = 100f;
const float TR = 20f;
const float k = 0.07f;
readonly static float[] delta_t = {2.0f,5.0f,10.0f};
const int n = 100;
public delegate float func(float t);
static float NewtonCooling(float t)
{
return -k * (t-TR);
}
public static void Main (string[] args)
{
func f = new func(NewtonCooling);
for(int i=0; i<delta_t.Length; i++)
{
Console.WriteLine("delta_t = " + delta_t[i]);
Euler(f,T0,n,delta_t[i]);
}
}
public static void Euler(func f, float y, int n, float h)
{
for(float x=0; x<=n; x+=h)
{
Console.WriteLine("\t" + x + "\t" + y);
y += h * f(y);
}
}
}
}</syntaxhighlight>
 
=={{header|C++}}==
{{trans|D}}
<langsyntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
 
Line 248 ⟶ 1,034:
euler(newtonCoolingLaw, 100, 0, 100, 5);
euler(newtonCoolingLaw, 100, 0, 100, 10);
}</langsyntaxhighlight>
Last part of output:
<pre>
Line 264 ⟶ 1,050:
done
</pre>
=={{header|C sharp}}==
<lang csharp>using System;
 
namespace prog
{
class MainClass
{
const float T0 = 100f;
const float TR = 20f;
const float k = 0.07f;
readonly static float[] delta_t = {2.0f,5.0f,10.0f};
const int n = 100;
public delegate float func(float t);
static float NewtonCooling(float t)
{
return -k * (t-TR);
}
public static void Main (string[] args)
{
func f = new func(NewtonCooling);
for(int i=0; i<delta_t.Length; i++)
{
Console.WriteLine("delta_t = " + delta_t[i]);
Euler(f,T0,n,delta_t[i]);
}
}
public static void Euler(func f, float y, int n, float h)
{
for(float x=0; x<=n; x+=h)
{
Console.WriteLine("\t" + x + "\t" + y);
y += h * f(y);
}
}
}
}</lang>
 
=={{header|Clay}}==
 
<syntaxhighlight lang="clay">
<lang Clay>
import printer.formatter as pf;
 
Line 323 ⟶ 1,070:
}
}
</syntaxhighlight>
</lang>
 
Example output:
Line 338 ⟶ 1,085:
80 20.0052488
90 20.00157464
</pre>
 
=={{header|Clojure}}==
{{trans|Python}}
<syntaxhighlight lang="lisp">(ns newton-cooling
(:gen-class))
 
(defn euler [f y0 a b h]
"Euler's Method.
Approximates y(time) in y'(time)=f(time,y) with y(a)=y0 and t=a..b and the step size h."
(loop [t a
y y0
result []]
(if (<= t b)
(recur (+ t h) (+ y (* (f (+ t h) y) h)) (conj result [(double t) (double y)]))
result)))
 
(defn newton-coolling [t temp]
"Newton's cooling law, f(t,T) = -0.07*(T-20)"
(* -0.07 (- temp 20)))
 
; Run for case h = 10
(println "Example output")
(doseq [q (euler newton-coolling 100 0 100 10)]
(println (apply format "%.3f %.3f" q)))
</syntaxhighlight>
{{Output}}
<pre>
Example output
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
100.000 20.000
</pre>
 
=={{header|COBOL}}==
 
{{trans|C#}}
{{works with|Visual COBOL}}
The following is in the Managed COBOL dialect:
<syntaxhighlight lang="cobol"> DELEGATE-ID func.
PROCEDURE DIVISION USING VALUE t AS FLOAT-LONG
RETURNING ret AS FLOAT-LONG.
END DELEGATE.
CLASS-ID. MainClass.
78 T0 VALUE 100.0.
78 TR VALUE 20.0.
78 k VALUE 0.07.
01 delta-t INITIALIZE ONLY STATIC
FLOAT-LONG OCCURS 3 VALUES 2.0, 5.0, 10.0.
78 n VALUE 100.
METHOD-ID NewtonCooling STATIC.
PROCEDURE DIVISION USING VALUE t AS FLOAT-LONG
RETURNING ret AS FLOAT-LONG.
COMPUTE ret = - k * (t - TR)
END METHOD.
METHOD-ID Main STATIC.
DECLARE f AS TYPE func
SET f TO METHOD self::NewtonCooling
DECLARE delta-t-len AS BINARY-LONG
MOVE delta-t::Length TO delta-t-len
PERFORM VARYING i AS BINARY-LONG FROM 1 BY 1
UNTIL i > delta-t-len
DECLARE elt AS FLOAT-LONG = delta-t (i)
INVOKE TYPE Console::WriteLine("delta-t = {0:F4}", elt)
INVOKE self::Euler(f, T0, n, elt)
END-PERFORM
END METHOD.
METHOD-ID Euler STATIC.
PROCEDURE DIVISION USING VALUE f AS TYPE func, y AS FLOAT-LONG,
n AS BINARY-LONG, h AS FLOAT-LONG.
PERFORM VARYING x AS BINARY-LONG FROM 0 BY h UNTIL x >= n
INVOKE TYPE Console::WriteLine("x = {0:F4}, y = {1:F4}", x, y)
COMPUTE y = y + h * RUN f(y)
END-PERFORM
END METHOD.
END CLASS.</syntaxhighlight>
 
Example output:
<pre>
delta-t = 10.0000
x = 0.0000, y = 100.0000
x = 10.0000, y = 44.0000
x = 20.0000, y = 27.2000
x = 30.0000, y = 22.1600
x = 40.0000, y = 20.6480
x = 50.0000, y = 20.1944
x = 60.0000, y = 20.0583
x = 70.0000, y = 20.0175
x = 80.0000, y = 20.0052
x = 90.0000, y = 20.0016
</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">;; 't' usually means "true" in CL, but we need 't' here for time/temperature.
(defconstant true 'cl:t)
(shadow 't)
Line 350 ⟶ 1,203:
 
;; Set the initial values and increments of the iteration variables.
(do ((t a (incf+ t h))
(y y0 (incf+ y (* h (funcall f t y)))))
 
;; End the iteration when t reaches the end b of the time interval.
Line 366 ⟶ 1,219:
(euler #'newton-cooling 100 0 100 2)
(euler #'newton-cooling 100 0 100 5)
(euler #'newton-cooling 100 0 100 10)</langsyntaxhighlight>
 
<syntaxhighlight lang="lisp">;; slightly more idiomatic Common Lisp version
 
(defun newton-cooling (time temperature)
"Newton's cooling law, f(t,T) = -0.07*(T-20)"
(declare (ignore time))
(* -0.07 (- temperature 20)))
 
(defun euler (f y0 a b h)
"Euler's Method.
Approximates y(time) in y'(time)=f(time,y) with y(a)=y0 and t=a..b and the step size h."
(loop for time from a below b by h
for y = y0 then (+ y (* h (funcall f time y)))
do (format t "~6,3F ~6,3F~%" time y)))</syntaxhighlight>
 
<pre>
Line 384 ⟶ 1,251:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.range, std.traits;
 
/// Approximates y(t) in y'(t)=f(t,y) with y(a)=y0 and t=a..b and the step size h.
/**
void euler(F)(in F f, in double y0, in double a, in double b, in double h) @safe
Approximates y(t) in y'(t)=f(t,y) with y(a)=y0 and
if (isCallable!F && __traits(compiles, { real r = f(0.0, 0.0); })) {
t=a..b and the step size h.
*/
void euler(F)(in F f, in double y0,
in double a, in double b, in double h) {
double y = y0;
foreach (immutable t; iota(a, b, h)) {
writefln("%.3f %.3f", t, y);
y += h * f(t, y);
}
writeln("done").writeln;
}
 
void main() {
/// Example: Newton's cooling law.
staticenum newtonCoolingLaw = (in double time, in double t) {
returnpure nothrow @safe @nogc => -0.07 * (t - 20);
}
 
euler(&newtonCoolingLaw, 100, 0, 100, 2);
euler(&newtonCoolingLaw, 100, 0, 100, 5);
euler(&newtonCoolingLaw, 100, 0, 100, 10);
}</langsyntaxhighlight>
Last part of the output:
<pre>...
Line 423 ⟶ 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}}==
{{trans|Ruby}}
<syntaxhighlight lang="elixir">defmodule Euler do
def method(_, _, t, b, _) when t>b, do: :ok
def method(f, y, t, b, h) do
:io.format "~7.3f ~7.3f~n", [t,y]
method(f, y + h * f.(t,y), t + h, b, h)
end
end
 
f = fn _time, temp -> -0.07 * (temp - 20) end
Enum.each([10, 5, 2], fn step ->
IO.puts "\nStep = #{step}"
Euler.method(f, 100.0, 0.0, 100.0, step)
end)</syntaxhighlight>
 
{{out}}
<pre style="height: 40ex; overflow: scroll">
Step = 10
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
100.000 20.000
 
Step = 5
0.000 100.000
5.000 72.000
10.000 53.800
15.000 41.970
20.000 34.280
25.000 29.282
30.000 26.034
35.000 23.922
40.000 22.549
45.000 21.657
50.000 21.077
55.000 20.700
60.000 20.455
65.000 20.296
70.000 20.192
75.000 20.125
80.000 20.081
85.000 20.053
90.000 20.034
95.000 20.022
100.000 20.014
 
Step = 2
0.000 100.000
2.000 88.800
4.000 79.168
6.000 70.884
8.000 63.761
10.000 57.634
12.000 52.365
14.000 47.834
16.000 43.937
18.000 40.586
20.000 37.704
22.000 35.226
24.000 33.094
26.000 31.261
28.000 29.684
30.000 28.328
32.000 27.163
34.000 26.160
36.000 25.297
38.000 24.556
40.000 23.918
42.000 23.369
44.000 22.898
46.000 22.492
48.000 22.143
50.000 21.843
52.000 21.585
54.000 21.363
56.000 21.172
58.000 21.008
60.000 20.867
62.000 20.746
64.000 20.641
66.000 20.551
68.000 20.474
70.000 20.408
72.000 20.351
74.000 20.302
76.000 20.259
78.000 20.223
80.000 20.192
82.000 20.165
84.000 20.142
86.000 20.122
88.000 20.105
90.000 20.090
92.000 20.078
94.000 20.067
96.000 20.057
98.000 20.049
100.000 20.042
</pre>
 
=={{header|Erlang}}==
 
<syntaxhighlight lang="erlang">
-module(euler).
-export([main/0, euler/5]).
 
cooling(_Time, Temperature) ->
(-0.07)*(Temperature-20).
 
euler(_, Y, T, _, End) when End == T ->
io:fwrite("\n"),
Y;
 
euler(Func, Y, T, Step, End) ->
if
T rem 10 == 0 ->
io:fwrite("~.3f ",[float(Y)]);
true ->
ok
end,
euler(Func, Y + Step * Func(T, Y), T + Step, Step, End).
 
analytic(T, End) when T == End ->
io:fwrite("\n"),
T;
 
analytic(T, End) ->
Y = (20 + 80 * math:exp(-0.07 * T)),
io:fwrite("~.3f ", [Y]),
analytic(T+10, End).
 
main() ->
io:fwrite("Analytic:\n"),
analytic(0, 100),
io:fwrite("Step 2:\n"),
euler(fun cooling/2, 100, 0, 2, 100),
io:fwrite("Step 5:\n"),
euler(fun cooling/2, 100, 0, 5, 100),
io:fwrite("Step 10:\n"),
euler(fun cooling/2, 100, 0, 10, 100),
ok.
</syntaxhighlight>
{{out}}
<pre>
Analytic:
100.000 59.727 39.728 29.797 24.865 22.416 21.200 20.596 20.296 20.147
Step 2:
100.000 57.634 37.704 28.328 23.918 21.843 20.867 20.408 20.192 20.090
Step 5:
100.000 53.800 34.280 26.034 22.549 21.077 20.455 20.192 20.081 20.034
Step 10:
100.000 44.000 27.200 22.160 20.648 20.194 20.058 20.017 20.005 20.002
ok
</pre>
 
=={{header|Euler Math Toolbox}}==
 
<syntaxhighlight lang="euler math toolbox">
>function dgleuler (f,x,y0) ...
$ y=zeros(size(x)); y[1]=y0;
$ for i=2 to cols(y);
$ y[i]=y[i-1]+f(x[i-1],y[i-1])*(x[i]-x[i-1]);
$ end;
$ return y;
$endfunction
>function f(x,y) := -k*(y-TR)
>k=0.07; TR=20; TS=100;
>x=0:1:100; dgleuler("f",x,TS)[-1]
20.0564137335
>x=0:2:100; dgleuler("f",x,TS)[-1]
20.0424631834
>TR+(TS-TR)*exp(-k*TS)
20.0729505572
>x=0:5:100; plot2d(x,dgleuler("f",x,TS)); ...
> plot2d(x,TR+(TS-TR)*exp(-k*x),>add,color=red);
>ode("f",x,TS)[-1] // Euler default solver LSODA
20.0729505568
>adaptiverunge("f",x,TS)[-1] // Adaptive Runge Method
20.0729505572
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">let euler f (h : float) t0 y0 =
(t0, y0)
|> Seq.unfold (fun (t, y) -> Some((t,y), ((t + h), (y + h * (f t y)))))
 
let newtonCoolíng _ y = -0.07 * (y - 20.0)
 
[<EntryPoint>]
let main argv =
let f = newtonCoolíng
let a = 0.0
let y0 = 100.0
let b = 100.0
let h = 10.0
(euler newtonCoolíng h a y0)
|> Seq.takeWhile (fun (t,_) -> t <= b)
|> Seq.iter (printfn "%A")
0</syntaxhighlight>
Output for the above (step size 10)
<pre>(0.0, 100.0)
(10.0, 44.0)
(20.0, 27.2)
(30.0, 22.16)
(40.0, 20.648)
(50.0, 20.1944)
(60.0, 20.05832)
(70.0, 20.017496)
(80.0, 20.0052488)
(90.0, 20.00157464)
(100.0, 20.00047239)</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: formatting fry io kernel locals math math.ranges
sequences ;
IN: rosetta-code.euler-method
 
:: euler ( quot y! a b h -- )
a b h <range> [
:> t
t y "%7.3f %7.3f\n" printf
t y quot call h * y + y!
] each ; inline
 
: cooling ( t y -- x ) nip 20 - -0.07 * ;
 
: euler-method-demo ( -- )
2 5 10 [ '[ [ cooling ] 100 0 100 _ euler ] call nl ] tri@ ;
 
MAIN: euler-method-demo</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
100.000 20.000
</pre>
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">: newton-cooling-law ( f: temp -- f: temp' )
20e f- -0.07e f* ;
 
: euler ( f: y0 xt step end -- )
1+ 0 do
cr i . fdup f.
fdup over execute
dup s>f f* f+
dup +loop
2drop fdrop ;
 
100e ' newton-cooling-law 2 100 euler cr
100e ' newton-cooling-law 5 100 euler cr
100e ' newton-cooling-law 10 100 euler cr</syntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|2008}}
<langsyntaxhighlight lang="fortran">program euler_method
use iso_fortran_env, only: real64
implicit none
Line 482 ⟶ 1,722:
end function
 
end program</langsyntaxhighlight>
Output for <code>h = 10</code>:
<pre>
Line 498 ⟶ 1,738:
100.00000000000000 20.000472391953071
</pre>
 
=={{header|Futhark}}==
 
Specialised to the cooling function. We produce an array of the
temperature at each step subtracted from the analytically
determined temperature (so we are computing the error).
 
<syntaxhighlight lang="futhark">
let analytic(t0: f64) (time: f64): f64 =
20.0 + (t0 - 20.0) * f64.exp(-0.07*time)
 
let cooling(_time: f64) (temperature: f64): f64 =
-0.07 * (temperature-20.0)
 
let main(t0: f64) (a: f64) (b: f64) (h: f64): []f64 =
let steps = i32.f64 ((b-a)/h)
let temps = replicate steps 0.0
let (_,temps) = loop (t,temps)=(t0,temps) for i < steps do
let x = a + f64.i32 i * h
let temps[i] = f64.abs(t-analytic t0 x)
in (t + h * cooling x t,
temps)
in temps
</syntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 567 ⟶ 1,831:
fmt.Println()
}
}</langsyntaxhighlight>
Output, truncated:
<pre>
Line 601 ⟶ 1,865:
 
The ''eulerMapping'' closure produces an entire approximating sequence, expressed as a Map object. Here, ''x<sub>0</sub>'' and ''y<sub>0</sub>'' together are the first point in the sequence, the ODE initial conditions. ''h'' and ''dydx'' are again the step distance and the derivative closure. ''stopCond'' is a closure representing a "stop condition" that causes the the ''eulerMapping'' closure to stop after a finite number of steps; the given default value causes ''eulerMapping'' to stop after 100 steps.
<langsyntaxhighlight lang="groovy">def eulerStep = { xn, yn, h, dydx ->
(yn + h * dydx(xn, yn)) as BigDecimal
}
Line 615 ⟶ 1,879:
yMap
}
assert eulerMapping.maximumNumberOfParameters == 5</langsyntaxhighlight>
 
 
'''Specific Euler Method Solution for the "Temperature Diffusion" Problem''' (with Newton's derivative formula and constants for environment temperature and object conductivity given)
<langsyntaxhighlight lang="groovy">def dtdsNewton = { s, t, tR, k -> k * (tR - t) }
assert dtdsNewton.maximumNumberOfParameters == 4
 
Line 626 ⟶ 1,890:
 
def tEulerH = eulerMapping.rcurry(dtds) { s, t -> s >= 100 }
assert tEulerH.maximumNumberOfParameters == 3</langsyntaxhighlight>
 
 
'''Newton's Analytic Temperature Diffusion Solution''' (for comparison)
<langsyntaxhighlight lang="groovy">def tNewton = { s, s0, t0, tR, k ->
tR + (t0 - tR) * Math.exp(k * (s0 - s))
}
Line 636 ⟶ 1,900:
 
def tAnalytic = tNewton.rcurry(0, 100, 20, 0.07)
assert tAnalytic.maximumNumberOfParameters == 1</langsyntaxhighlight>
 
 
'''Specific solutions for 3 step sizes''' (and initial time and temperature)
<langsyntaxhighlight lang="groovy">[10, 5, 2].each { h ->
def tEuler = tEulerH.rcurry(h)
assert tEuler.maximumNumberOfParameters == 2
Line 653 ⟶ 1,917:
printf('%5.0f %8.4f %8.4f %9.6f\n', s, tA, tE, relError)
}
}</langsyntaxhighlight>
 
 
Line 694 ⟶ 1,958:
 
=={{header|Haskell}}==
Modular solution which separates the solver and a method. Moreover it works on a given mesh which can be irregular.
<lang Haskell>import Text.Printf
<syntaxhighlight lang="haskell">-- the solver
dsolveBy _ _ [] _ = error "empty solution interval"
dsolveBy method f mesh x0 = zip mesh results
where results = scanl (method f) x0 intervals
intervals = zip mesh (tail mesh)</syntaxhighlight>
 
It is better to use strict <code>Data.List.scanl'</code> in the solver but avoiding highlighting problems we leave lazy <code>scanl</code> function.
type F = Double -> Double -> Double
 
Some possible methods:
euler :: F -> Double -> Double -> Double -> Double -> IO ()
euler f y0 a b h = do
printf "%6.3f %6.3f\n" a y0
if a < b
then euler f (y0 + (f a y0) * h) (a + h) b h
else putStrLn "DONE"
 
<syntaxhighlight lang="haskell">-- 1-st order Euler
newtonCooling :: F
newtonCoolingeuler _f tx (t1,t2) = -0.07x *+ (tt2 - 20t1) * f t1 x
 
-- 2-nd order Runge-Kutta
main = euler newtonCooling 100 0 100 10
rk2 f x (t1,t2) = x + h * f (t1 + h/2) (x + h/2*f t1 x)
</lang>
where h = t2 - t1
Output:
 
<pre>
-- 4-th order Runge-Kutta
0.000 100.000
rk4 f x (t1,t2) = x + h/6 * (k1 + 2*k2 + 2*k3 + k4)
10.000 44.000
where k1 = f t1 x
20.000 27.200
k2 = f (t1 + h/2) (x + h/2*k1)
30.000 22.160
k3 = f (t1 + h/2) (x + h/2*k2)
40.000 20.648
k4 = f (t1 + h) (x + h*k3)
50.000 20.194
h = t2 - t1</syntaxhighlight>
60.000 20.058
 
70.000 20.017
Graphical output, using EasyPlot:
80.000 20.005
 
90.000 20.002
<syntaxhighlight lang="haskell">import Graphics.EasyPlot
100.000 20.000
 
DONE
newton t temp = -0.07 * (temp - 20)
</pre>
 
exactSolution t = 80*exp(-0.07*t)+20
 
test1 = plot (PNG "euler1.png")
[ Data2D [Title "Step 10", Style Lines] [] sol1
, Data2D [Title "Step 5", Style Lines] [] sol2
, Data2D [Title "Step 1", Style Lines] [] sol3
, Function2D [Title "exact solution"] [Range 0 100] exactSolution ]
where sol1 = dsolveBy euler newton [0,10..100] 100
sol2 = dsolveBy euler newton [0,5..100] 100
sol3 = dsolveBy euler newton [0,1..100] 100
 
test2 = plot (PNG "euler2.png")
[ Data2D [Title "Euler"] [] sol1
, Data2D [Title "RK2"] [] sol2
, Data2D [Title "RK4"] [] sol3
, Function2D [Title "exact solution"] [Range 0 100] exactSolution ]
where sol1 = dsolveBy euler newton [0,10..100] 100
sol2 = dsolveBy rk2 newton [0,10..100] 100
sol3 = dsolveBy rk4 newton [0,10..100] 100</syntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
Line 732 ⟶ 2,016:
This solution works in both Icon and Unicon. It takes advantage of the <code>proc</code> procedure, which converts a string naming a procedure into a call to that procedure.
 
<syntaxhighlight lang="icon">
<lang Icon>
invocable "newton_cooling" # needed to use the 'proc' procedure
 
Line 755 ⟶ 2,039:
euler ("newton_cooling", 100, 0, 100, step_size)
end
</syntaxhighlight>
</lang>
 
Sample output:
Line 775 ⟶ 2,059:
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">NB.*euler a Approximates Y(t) in Y'(t)=f(t,Y) with Y(a)=Y0 and t=a..b and step size h.
euler=: adverb define
'Y0 a b h'=. 4{. y
Line 784 ⟶ 2,068:
 
ncl=: _0.07 * -&20 NB. Newton's Cooling Law
</syntaxhighlight>
</lang>
'''Example:'''
<langsyntaxhighlight lang="j"> ncl euler 100 0 100 2
... NB. output redacted for brevity
ncl euler 100 0 100 5
Line 801 ⟶ 2,085:
80 20.0052
90 20.0016
100 20.0005</langsyntaxhighlight>
 
=={{header|Java}}==
 
<langsyntaxhighlight lang="java">
public class Euler {
private static void euler (Callable f, double y0, int a, int b, int h) {
Line 839 ⟶ 2,123:
}
}
</syntaxhighlight>
</lang>
 
Output for step = 10;
Line 856 ⟶ 2,140:
DONE
</pre>
 
=={{header|JavaScript}}==
{{trans|Python}}
<syntaxhighlight lang="javascript">
// Function that takes differential-equation, initial condition,
// ending x, and step size as parameters
function eulersMethod(f, x1, y1, x2, h) {
// Header
console.log("\tX\t|\tY\t");
console.log("------------------------------------");
 
// Initial Variables
var x=x1, y=y1;
 
// While we're not done yet
// Both sides of the OR let you do Euler's Method backwards
while ((x<x2 && x1<x2) || (x>x2 && x1>x2)) {
// Print what we have
console.log("\t" + x + "\t|\t" + y);
 
// Calculate the next values
y += h*f(x, y)
x += h;
}
 
return y;
}
 
function cooling(x, y) {
return -0.07 * (y-20);
}
 
eulersMethod(cooling, 0, 100, 100, 10);
</syntaxhighlight>
 
=={{header|jq}}==
{{works with|jq|1.4}}
<syntaxhighlight lang="jq"># euler_method takes a filter (df), initial condition
# (x1,y1), ending x (x2), and step size as parameters;
# it emits the y values at each iteration.
# df must take [x,y] as its input.
def euler_method(df; x1; y1; x2; h):
h as $h
| [x1, y1]
| recurse( if ((.[0] < x2 and x1 < x2) or
(.[0] > x2 and x1 > x2)) then
[ (.[0] + $h), (.[1] + $h*df) ]
else empty
end )
| .[1] ;
 
 
# We could now solve the task by writing for each step-size, $h
# euler_method(-0.07 * (.[1]-20); 0; 100; 100; $h)
# but for clarity, we shall define a function named "cooling":
 
# [x,y] is input
def cooling: -0.07 * (.[1]-20);
 
# The following solves the task:
# (2,5,10) | [., [ euler_method(cooling; 0; 100; 100; .) ] ]
</syntaxhighlight>
For brevity, we modify euler_method so that it only shows the final value of y:
<syntaxhighlight lang="jq">
def euler_solution(df; x1; y1; x2; h):
def recursion(exp): reduce recurse(exp) as $x (.; $x);
h as $h
| [x1, y1]
| recursion( if ((.[0] < x2 and x1 < x2) or
(.[0] > x2 and x1 > x2)) then
[ (.[0] + $h), (.[1] + $h*df) ]
else empty
end )
| .[1] ;</syntaxhighlight>
'''Example''':
<syntaxhighlight lang="jq">(1,2,5,10,20) | [., [ euler_solution(cooling; 0; 100; 100; .) ] ]</syntaxhighlight>
{{Out}}
<syntaxhighlight lang="sh">$ jq -M -n -c -f Euler_method.jq
[1,[20.05641373347389]]
[2,[20.0424631833732]]
[5,[20.01449963666907]]
[10,[20.000472392]]
[20,[19.180799999999998]]</syntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|1.0.3}}
<syntaxhighlight lang="julia">euler(f::Function, T::Number, t0::Int, t1::Int, h::Int) = collect(begin T += h * f(T); T end for t in t0:h:t1)
 
# Prints a series of arbitrary values in a tabular form, left aligned in cells with a given width
tabular(width, cells...) = println(join(map(s -> rpad(s, width), cells)))
 
# prints the table according to the task description for h=5 and 10 sec
for h in (5, 10)
print("Step $h:\n\n")
tabular(15, "Time", "Euler", "Analytic")
t = 0
for T in euler(y -> -0.07 * (y - 20.0), 100.0, 0, 100, h)
tabular(15, t, round(T,digits=6), round(20.0 + 80.0 * exp(-0.07t), digits=6))
t += h
end
println()
end</syntaxhighlight>
 
{{out}}
<pre>Step 5:
 
Time Euler Analytic
0 72.0 100.0
5 53.8 76.375047
10 41.97 59.726824
15 34.2805 47.99502
20 29.282325 39.727757
25 26.033511 33.901915
30 23.921782 29.796514
35 22.549159 26.903487
40 21.656953 24.864805
45 21.077019 23.42817
50 20.700063 22.415791
55 20.455041 21.702379
60 20.295776 21.199646
65 20.192255 20.845376
70 20.124966 20.595727
75 20.081228 20.419801
80 20.052798 20.295829
85 20.034319 20.208467
90 20.022307 20.146904
95 20.0145 20.103522
100 20.009425 20.072951
 
Step 10:
 
Time Euler Analytic
0 44.0 100.0
10 27.2 59.726824
20 22.16 39.727757
30 20.648 29.796514
40 20.1944 24.864805
50 20.05832 22.415791
60 20.017496 21.199646
70 20.005249 20.595727
80 20.001575 20.295829
90 20.000472 20.146904
100 20.000142 20.072951 </pre>
 
=={{header|Kotlin}}==
{{trans|C}}
<syntaxhighlight lang="scala">// version 1.1.2
 
typealias Deriv = (Double) -> Double // only one parameter needed here
 
const val FMT = " %7.3f"
 
fun euler(f: Deriv, y: Double, step: Int, end: Int) {
var yy = y
print(" Step %2d: ".format(step))
for (t in 0..end step step) {
if (t % 10 == 0) print(FMT.format(yy))
yy += step * f(yy)
}
println()
}
 
fun analytic() {
print(" Time: ")
for (t in 0..100 step 10) print(" %7d".format(t))
print("\nAnalytic: ")
for (t in 0..100 step 10)
print(FMT.format(20.0 + 80.0 * Math.exp(-0.07 * t)))
println()
}
 
fun cooling(temp: Double) = -0.07 * (temp - 20.0)
 
fun main(args: Array<String>) {
analytic()
for (i in listOf(2, 5, 10))
euler(::cooling, 100.0, i, 100)
}</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|Lambdatalk}}==
Translation of Python
<syntaxhighlight lang="scheme">
{def eulersMethod
{def eulersMethod.r
{lambda {:f :b :h :t :y}
{if {<= :t :b}
then {tr {td :t} {td {/ {round {* :y 1000}} 1000}}}
{eulersMethod.r :f :b :h {+ :t :h} {+ :y {* :h {:f :t :y}}}}
else}}}
{lambda {:f :y0 :a :b :h}
{table {eulersMethod.r :f :b :h :a :y0}}}}
 
{def cooling
{lambda {:time :temp}
{* -0.07 {- :temp 20}}}}
 
{eulersMethod cooling 100 0 100 10}
->
0 100
10 44
20 27.2
30 22.16
40 20.648
50 20.194
60 20.058
70 20.017
80 20.005
90 20.002
100 20
</syntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">T0 = 100
TR = 20
k = 0.07
Line 880 ⟶ 2,383:
Euler( NewtonCooling, T0, n, delta_t[i] )
end
</syntaxhighlight>
</lang>
 
=={{header|Maple}}==
Build-in function with Euler:
<syntaxhighlight lang="maple">with(Student[NumericalAnalysis]);
k := 0.07:
TR := 20:
Euler(diff(T(t), t) = -k*(T(t) - TR), T(0) = 100, t = 100, numsteps = 50); # step size = 2
Euler(diff(T(t), t) = -k*(T(t) - TR), T(0) = 100, t = 100, numsteps = 20); # step size = 5
Euler(diff(T(t), t) = -k*(T(t) - TR), T(0) = 100, t = 100, numsteps = 10); # step size = 10</syntaxhighlight>
{{out}}
<pre>
20.04
20.01
20.00
</pre>
Hard-coded procedure:
<syntaxhighlight lang="maple">f := y -> (-0.07) * (y - 20):
 
EulerMethod := proc(f, start_time, end_time, y0, h) # y0: initial value #h: step size
local cur, y, rate:
cur := start_time;
y := y0;
while cur <= end_time do
printf("%g %g\n", cur, y);
cur := cur + h;
rate := f(y);
y := y + h * rate;
end do;
return y;
end proc:
 
# step size = 2
printf("Step Size = %a\n", 2);
EulerMethod(f, 0, 100, 100, 2);
 
# step size = 5
printf("\nStep Size = %a\n", 5);
EulerMethod(f, 0, 100, 100, 5);
 
# step size = 10
printf("\nStep Size = %a\n", 10);
EulerMethod(f, 0, 100, 100, 10);</syntaxhighlight>
{{out}}
<pre style="height: 40ex; overflow: scroll">
Step Size = 2
0 100
2 88.8
4 79.168
6 70.8845
8 63.7607
10 57.6342
12 52.3654
14 47.8342
16 43.9374
18 40.5862
20 37.7041
22 35.2255
24 33.094
26 31.2608
28 29.6843
30 28.3285
32 27.1625
34 26.1598
36 25.2974
38 24.5558
40 23.918
42 23.3694
44 22.8977
46 22.492
48 22.1432
50 21.8431
52 21.5851
54 21.3632
56 21.1723
58 21.0082
60 20.867
62 20.7457
64 20.6413
66 20.5515
68 20.4743
70 20.4079
72 20.3508
74 20.3017
76 20.2594
78 20.2231
80 20.1919
82 20.165
84 20.1419
86 20.122
88 20.105
90 20.0903
92 20.0776
94 20.0668
96 20.0574
98 20.0494
100 20.0425
 
Step Size = 5
0 100
5 72
10 53.8
15 41.97
20 34.2805
25 29.2823
30 26.0335
35 23.9218
40 22.5492
45 21.657
50 21.077
55 20.7001
60 20.455
65 20.2958
70 20.1923
75 20.125
80 20.0812
85 20.0528
90 20.0343
95 20.0223
100 20.0145
 
Step Size = 10
0 100
10 44
20 27.2
30 22.16
40 20.648
50 20.1944
60 20.0583
70 20.0175
80 20.0052
90 20.0016
100 20.0005
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Better methods for differential equation solving are built into Mathematica, so the typical user would omit the Method and StartingStepSize options in the code below. However since the task requests Eulers method, here is the bad solution...
<syntaxhighlight lang="mathematica">
euler[step_, val_] := NDSolve[
{T'[t] == -0.07 (T[t] - 20), T[0] == 100},
T, {t, 0, 100},
Method -> "ExplicitEuler",
StartingStepSize -> step
][[1, 1, 2]][val]
</syntaxhighlight>
{{out}}
<pre>euler[2, 100]
20.0425
 
euler[5, 100]
20.0145
 
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}}==
<syntaxhighlight lang="maxima">euler_method(f, y0, a, b, h):= block(
[t: a, y: y0, tg: [a], yg: [y0]],
unless t>=b do (
t: t + h,
y: y + f(t, y)*h,
tg: endcons(t, tg),
yg: endcons(y, yg)
),
[tg, yg]
);
 
/* initial temperature */
T0: 100;
 
/* environment of temperature */
Tr: 20;
 
/* the cooling constant */
k: 0.07;
 
/* end of integration */
tmax: 100;
 
/* analytical solution */
Tref(t):= Tr + (T0 - Tr)*exp(-k*t);
 
/* cooling rate */
dT(t, T):= -k*(T-Tr);
 
/* get numerical solution */
h: 10;
[tg, yg]: euler_method('dT, T0, 0, tmax, h);
 
/* plot analytical and numerical solution */
plot2d([Tref, [discrete, tg, yg]], ['t, 0, tmax],
[legend, "analytical", concat("h = ", h)],
[xlabel, "t / seconds"],
[ylabel, "Temperature / C"]);
</syntaxhighlight>
 
=={{header|МК-61/52}}==
<syntaxhighlight lang="text">П2 С/П П3 С/П П4 ПП 19 ИП3 * ИП4
+ П4 С/П ИП2 ИП3 + П2 БП 05 ...
... ... ... ... ... ... ... ... ... В/О</syntaxhighlight>
 
Instead of dots typed calculation program equation ''f(u, t)'', where the arguments are ''t'' = Р2, ''u'' = Р4.
 
Input: ''Initial time'' С/П ''Time step'' С/П ''Initial value'' С/П.
 
The result is displayed on the indicator.
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import strutils
 
proc euler(f: proc (x,y: float): float; y0, a, b, h: float) =
var (t,y) = (a,y0)
while t < b:
echo formatFloat(t, ffDecimal, 3), " ", formatFloat(y, ffDecimal, 3)
t += h
y += h * f(t,y)
 
proc newtoncooling(time, temp: float): float =
-0.07 * (temp - 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|Objeck}}==
<syntaxhighlight lang="objeck">
class EulerMethod {
T0 : static : Float;
TR : static : Float;
k : static : Float;
delta_t : static : Float[];
n : static : Float;
function : Main(args : String[]) ~ Nil {
T0 := 100;
TR := 20;
k := 0.07;
delta_t := [2.0, 5.0, 10.0];
n := 100;
f := NewtonCooling(Float) ~ Float;
for(i := 0; i < delta_t->Size(); i+=1;) {
IO.Console->Print("delta_t = ")->PrintLine(delta_t[i]);
Euler(f, T0, n->As(Int), delta_t[i]);
};
}
function : native : NewtonCooling(t : Float) ~ Float {
return -1 * k * (t-TR);
}
function : native : Euler(f : (Float) ~ Float, y : Float, n : Int, h : Float) ~ Nil {
for(x := 0; x<=n; x+=h;) {
IO.Console->Print("\t")->Print(x)->Print("\t")->PrintLine(y);
y += h * f(y);
};
}
}
</syntaxhighlight>
 
Output:
<pre>
delta_t = 2
0 100
2 88.8
4 79.168
6 70.88448
...
delta_t = 10
0 100
10 44
20 27.2
30 22.16
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}}==
 
<syntaxhighlight lang="ocaml">(* Euler integration by recurrence relation.
* Given a function, and stepsize, provides a function of (t,y) which
* returns the next step: (t',y'). *)
let euler f ~step (t,y) = ( t+.step, y +. step *. f t y )
 
(* newton_cooling doesn't use time parameter, so _ is a placeholder *)
let newton_cooling ~k ~tr _ y = -.k *. (y -. tr)
 
(* analytic solution for Newton cooling *)
let analytic_solution ~k ~tr ~t0 t = tr +. (t0 -. tr) *. exp (-.k *. t)</syntaxhighlight>
 
Using the above functions to produce the task results:
<syntaxhighlight lang="ocaml">(* Wrapping up the parameters in a "cool" function: *)
let cool = euler (newton_cooling ~k:0.07 ~tr:20.)
 
(* Similarly for the analytic solution: *)
let analytic = analytic_solution ~k:0.07 ~tr:20. ~t0:100.
 
(* (Just a loop) Apply recurrence function on state, until some condition *)
let recur ~until f state =
let rec loop s =
if until s then ()
else loop (f s)
in loop state
 
(* 'results' generates the specified output starting from initial values t=0, temp=100C; ending at t=100s *)
let results fn =
Printf.printf "\t time\t euler\tanalytic\n%!";
let until (t,y) =
Printf.printf "\t%7.3f\t%7.3f\t%9.5f\n%!" t y (analytic t);
t >= 100.
in recur ~until fn (0.,100.)
 
results (cool ~step:10.)
results (cool ~step:5.)
results (cool ~step:2.)</syntaxhighlight>
 
Example output:
<pre>
# results (cool ~step:10.);;
time euler analytic
0.000 100.000 100.00000
10.000 44.000 59.72682
20.000 27.200 39.72776
30.000 22.160 29.79651
40.000 20.648 24.86481
50.000 20.194 22.41579
60.000 20.058 21.19965
70.000 20.017 20.59573
80.000 20.005 20.29583
90.000 20.002 20.14690
100.000 20.000 20.07295
- : unit = ()
</pre>
 
=={{header|Oforth}}==
 
<syntaxhighlight lang="oforth">: euler(f, y, a, b, h)
| t |
a b h step: t [
System.Out t <<wjp(6, JUSTIFY_RIGHT, 3) " : " << y << cr
t y f perform h * y + ->y
] ;</syntaxhighlight>
 
Usage :
 
<syntaxhighlight lang="oforth">: newtonCoolingLaw(t, y)
y 20 - -0.07 * ;
 
: test
euler(#newtonCoolingLaw, 100.0, 0.0, 100.0, 2)
euler(#newtonCoolingLaw, 100.0, 0.0, 100.0, 5)
euler(#newtonCoolingLaw, 100.0, 0.0, 100.0, 10) ;</syntaxhighlight>
 
{{out}}
<pre>
....
0 : 100
10 : 44
20 : 27.2
30 : 22.16
40 : 20.648
50 : 20.1944
60 : 20.05832
70 : 20.017496
80 : 20.0052488
90 : 20.00157464
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}}==
{{trans|C}}
 
Euler code for Free Pascal - Delphi mode. Apart from the function-pointer calling convention for the NewtonCooling method, this example is ISO-7185 standard Pascal.
 
<syntaxhighlight lang="pascal">
 
{$mode delphi}
PROGRAM Euler;
 
TYPE TNewtonCooling = FUNCTION (t: REAL) : REAL;
 
CONST T0 : REAL = 100.0;
CONST TR : REAL = 20.0;
CONST k : REAL = 0.07;
CONST time : INTEGER = 100;
CONST step : INTEGER = 10;
CONST dt : ARRAY[0..3] of REAL = (1.0,2.0,5.0,10.0);
 
VAR i : INTEGER;
FUNCTION NewtonCooling(t: REAL) : REAL;
BEGIN
NewtonCooling := -k * (t-TR);
END;
PROCEDURE Euler(F: TNewtonCooling; y, h : REAL; n: INTEGER);
VAR i: INTEGER = 0;
BEGIN
WRITE('dt=',trunc(h):2,':');
REPEAT
IF (i mod 10 = 0) THEN WRITE(' ',y:2:3);
INC(i,trunc(h));
y := y + h * F(y);
UNTIL (i >= n);
WRITELN;
END;
 
PROCEDURE Sigma;
VAR t: INTEGER = 0;
BEGIN
WRITE('Sigma:');
REPEAT
WRITE(' ',(20 + 80 * exp(-0.07 * t)):2:3);
INC(t,step);
UNTIL (t>=time);
WRITELN;
END;
 
BEGIN
WRITELN('Newton cooling function: Analytic solution (Sigma) with 3 Euler approximations.');
WRITELN('Time: ',0:7,10:7,20:7,30:7,40:7,50:7,60:7,70:7,80:7,90:7);
Sigma;
FOR i := 1 to 3 DO
Euler(NewtonCooling,T0,dt[i],time);
END.
 
</syntaxhighlight>
 
 
Output:
<pre>
Newton cooling function: Analytic solution (Sigma) with 3 Euler approximations.
Time: 0 10 20 30 40 50 60 70 80 90
Sigma: 100.000 59.727 39.728 29.797 24.865 22.416 21.200 20.596 20.296 20.147
dt= 2: 100.000 57.634 37.704 28.328 23.918 21.843 20.867 20.408 20.192 20.090
dt= 5: 100.000 53.800 34.280 26.034 22.549 21.077 20.455 20.192 20.081 20.034
dt=10: 100.000 44.000 27.200 22.160 20.648 20.194 20.058 20.017 20.005 20.002
 
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">sub euler_method {
my ($t0, $t1, $k, $step_size) = @_;
my @results = ( [0, $t0] );
Line 915 ⟶ 3,095:
$an;
}
</syntaxhighlight>
</lang>
Output:<pre>Time 2 err(%) 5 err(%) 10 err(%) Analytic
----------------------------------------------------------------------------
Line 930 ⟶ 3,110:
100 20.042 -0.152 20.014 -0.291 20.000 -0.361 20.073</pre>
 
=={{header|Perl 6Phix}}==
{{libheader|Phix/pGUI}}
<lang perl6>sub euler ( &f, $y0, $a, $b, $h ) {
{{libheader|Phix/online}}
my $y = $y0;
You can run this online [http://phix.x10.mx/p2js/euler_method.htm here].
my @t_y;
<!--<syntaxhighlight lang="phix">(phixonline)-->
for $a, * + $h ... * > $b -> $t {
<span style="color: #000080;font-style:italic;">--
@t_y[$t] = $y;
-- demo\rosetta\Euler_method.exw
$y += $h * f( $t, $y );
-- =============================
}
--</span>
return @t_y;
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
}
<span style="color: #008080;">function</span> <span style="color: #000000;">ivp_euler</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">end_t</span><span style="color: #0000FF;">)</span>
 
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
my $COOLING_RATE = 0.07;
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">end_t</span> <span style="color: #008080;">by</span> <span style="color: #000000;">step</span> <span style="color: #008080;">do</span>
my $AMBIENT_TEMP = 20;
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">y</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
my $INITIAL_TEMP = 100;
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">step</span> <span style="color: #0000FF;">*</span> <span style="color: #7060A8;">call_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">})</span>
my $INITIAL_TIME = 0;
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
my $FINAL_TIME = 100;
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sub f ( $time, $temp ) {
return -$COOLING_RATE * ( $temp - $AMBIENT_TEMP );
<span style="color: #008080;">function</span> <span style="color: #000000;">analytic</span><span style="color: #0000FF;">()</span>
}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
 
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100</span> <span style="color: #008080;">by</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
my @e;
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">20</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">80</span> <span style="color: #0000FF;">*</span> <span style="color: #7060A8;">exp</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">0.07</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
@e[$_] = euler( &f, $INITIAL_TEMP, $INITIAL_TIME, $FINAL_TIME, $_ ) for 2, 5, 10;
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
say 'Time Analytic Step2 Step5 Step10 Err2 Err5 Err10';
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
for $INITIAL_TIME, * + 10 ... * >= $FINAL_TIME -> $t {
<span style="color: #008080;">function</span> <span style="color: #000000;">cooling</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000080;font-style:italic;">/*t*/</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">temp</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">0.07</span> <span style="color: #0000FF;">*</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">temp</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
my $exact = $AMBIENT_TEMP + ($INITIAL_TEMP - $AMBIENT_TEMP)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
* (-$COOLING_RATE * $t).exp;
 
<span style="color: #008080;">constant</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span>
my $err = sub { @^a.map: { 100 * abs( $_ - $exact ) / $exact } }
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">analytic</span><span style="color: #0000FF;">(),</span>
 
<span style="color: #000000;">e2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ivp_euler</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cooling</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">),</span>
my ( $a, $b, $c ) = map { @e[$_][$t] }, 2, 5, 10;
<span style="color: #000000;">e5</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ivp_euler</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cooling</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">),</span>
 
<span style="color: #000000;">e10</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ivp_euler</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cooling</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)</span>
say $t.fmt('%4d '), ( $exact, $a, $b, $c )».fmt(' %7.3f'),
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" Time: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">:=</span><span style="color: #008000;">"%7d"</span><span style="color: #0000FF;">)})</span>
$err.([$a, $b, $c])».fmt(' %7.3f%%');
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Analytic: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">:=</span><span style="color: #008000;">"%7.3f"</span><span style="color: #0000FF;">)})</span>
}</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" Step 2: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">:=</span><span style="color: #008000;">"%7.3f"</span><span style="color: #0000FF;">)})</span>
 
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" Step 5: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">:=</span><span style="color: #008000;">"%7.3f"</span><span style="color: #0000FF;">)})</span>
Output:<pre>Time Analytic Step2 Step5 Step10 Err2 Err5 Err10
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" Step 10: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">:=</span><span style="color: #008000;">"%7.3f"</span><span style="color: #0000FF;">)})</span>
0 100.000 100.000 100.000 100.000 0.000% 0.000% 0.000%
10 59.727 57.634 53.800 44.000 3.504% 9.923% 26.331%
<span style="color: #000080;font-style:italic;">-- and a simple plot</span>
20 39.728 37.704 34.281 27.200 5.094% 13.711% 31.534%
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
30 29.797 28.328 26.034 22.160 4.927% 12.629% 25.629%
<span style="color: #008080;">include</span> <span style="color: #7060A8;">IupGraph</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
40 24.865 23.918 22.549 20.648 3.808% 9.313% 16.959%
50 22.416 21.843 21.077 20.194 2.555% 5.972% 9.910%
<span style="color: #008080;">function</span> <span style="color: #000000;">get_data</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*graph*/</span><span style="color: #0000FF;">)</span>
60 21.200 20.867 20.455 20.058 1.569% 3.512% 5.384%
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"NAMES"</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"analytical"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"h=2"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"h=5"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"h=10"</span><span style="color: #0000FF;">}},</span>
70 20.596 20.408 20.192 20.017 0.912% 1.959% 2.808%
<span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_BLUE</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e2</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_GREEN</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e5</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_BLACK</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e10</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_RED</span><span style="color: #0000FF;">}}</span>
80 20.296 20.192 20.081 20.005 0.512% 1.057% 1.432%
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
90 20.147 20.090 20.034 20.002 0.281% 0.559% 0.721%
100 20.073 20.042 20.014 20.000 0.152% 0.291% 0.361%</pre>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">graph</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGraph</span><span style="color: #0000FF;">(</span><span style="color: #000000;">get_data</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`RASTERSIZE=340x240,GRID=NO`</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttributes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">graph</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`XTICK=20,XMIN=0,XMAX=100,XMARGIN=25`</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttributes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">graph</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`YTICK=20,YMIN=20,YMAX=100`</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">graph</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="Euler Method",MINSIZE=260x200`</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</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|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/math.l")
 
(de euler (F Y A B H)
Line 996 ⟶ 3,194:
(euler newtonCoolingLaw 100.0 0 100.0 2.0)
(euler newtonCoolingLaw 100.0 0 100.0 5.0)
(euler newtonCoolingLaw 100.0 0 100.0 10.0)</langsyntaxhighlight>
Output:
<pre>...
Line 1,009 ⟶ 3,207:
80.000 20.005
90.000 20.002</pre>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pli">test: procedure options (main); /* 3 December 2012 */
 
declare (x, y, z) float;
declare (T0 initial (100), Tr initial (20)) float;
declare k float initial (0.07);
declare t fixed binary;
declare h fixed binary;
 
x, y, z = T0;
/* Step size is 2 seconds */
h = 2;
put skip data (h);
put skip list (' t By formula', 'By Euler');
do t = 0 to 100 by 2;
put skip edit (t, Tr + (T0 - Tr)/exp(k*t), x) (f(3), 2 f(17,10));
x = x + h*f(t, x);
end;
 
/* Step size is 5 seconds */
h = 5;
put skip data (h);
put skip list (' t By formula', 'By Euler');
do t = 0 to 100 by 5;
put skip edit ( t, Tr + (T0 - Tr)/exp(k*t), y) (f(3), 2 f(17,10));
y = y + h*f(t, y);
end;
 
/* Step size is 10 seconds */
h = 10;
put skip data (h);
put skip list (' t By formula', 'By Euler');
do t = 0 to 100 by 10;
put skip edit (t, Tr + (T0 - Tr)/exp(k*t), z) (f(3), 2 f(17,10));
z = z + h*f(t, z);
end;
 
f: procedure (dummy, T) returns (float);
declare dummy fixed binary;
declare T float;
 
return ( -k*(T - Tr) );
end f;
 
end test;</syntaxhighlight>
 
Only the final two outputs are shown, for brevity.
<pre>
H= 5;
t By formula By Euler
0 100.0000000000 100.0000000000
5 76.3750457764 72.0000000000
10 59.7268257141 53.7999992371
15 47.9950218201 41.9700012207
20 39.7277565002 34.2805023193
25 33.9019165039 29.2823257446
30 29.7965145111 26.0335121155
35 26.9034862518 23.9217834473
40 24.8648052216 22.5491600037
45 23.4281692505 21.6569538116
50 22.4157905579 21.0770206451
55 21.7023792267 20.7000637054
60 21.1996459961 20.4550418854
65 20.8453769684 20.2957763672
70 20.5957260132 20.1922550201
75 20.4198017120 20.1249656677
80 20.2958297729 20.0812282562
85 20.2084674835 20.0527992249
90 20.1469039917 20.0343189240
95 20.1035213470 20.0223064423
100 20.0729503632 20.0144996643
H= 10;
t By formula By Euler
0 100.0000000000 100.0000000000
10 59.7268257141 44.0000000000
20 39.7277565002 27.2000007629
30 29.7965145111 22.1599998474
40 24.8648052216 20.6480007172
50 22.4157905579 20.1944007874
60 21.1996459961 20.0583209991
70 20.5957260132 20.0174961090
80 20.2958297729 20.0052490234
90 20.1469039917 20.0015754700
100 20.0729503632 20.0004730225
</pre>
 
=={{header|PowerShell}}==
{{works with|PowerShell|4.0}}
<syntaxhighlight lang="powershell">
function euler (${f}, ${y}, $y0, $t0, $tEnd) {
function f-euler ($tn, $yn, $h) {
$yn + $h*(f $tn $yn)
}
function time ($t0, $h, $tEnd) {
$end = [MATH]::Floor(($tEnd - $t0)/$h)
foreach ($_ in 0..$end) { $_*$h + $t0 }
}
$time = time $t0 10 $tEnd
$time5 = time $t0 5 $tEnd
$time2 = time $t0 2 $tEnd
$yn10 = $yn5 = $yn2 = $y0
$i2 = $i5 = 0
foreach ($tn10 in $time) {
while($time2[$i2] -ne $tn10) {
$i2++
$yn2 = (f-euler $time2[$i2] $yn2 2)
}
while($time5[$i5] -ne $tn10) {
$i5++
$yn5 = (f-euler $time5[$i5] $yn5 5)
}
[pscustomobject]@{
t = "$tn10"
Analytical = "$("{0:N5}" -f (y $tn10))"
"Euler h = 2" = "$("{0:N5}" -f $yn2)"
"Euler h = 5" = "$("{0:N5}" -f $yn5)"
"Euler h = 10" = "$("{0:N5}" -f $yn10)"
"Error h = 2" = "$("{0:N5}" -f [MATH]::abs($yn2 - (y $tn10)))"
"Error h = 5" = "$("{0:N5}" -f [MATH]::abs($yn5 - (y $tn10)))"
"Error h = 10" = "$("{0:N5}" -f [MATH]::abs($yn10 - (y $tn10)))"
}
$yn10 = (f-euler $tn10 $yn10 10)
}
}
$k, $yr, $y0, $t0, $tEnd = 0.07, 20, 100, 0, 100
function f ($t, $y) {
-$k *($y - $yr)
}
function y ($t) {
$yr + ($y0 - $yr)*[MATH]::Exp(-$k*$t)
}
euler f y $y0 $t0 $tEnd | Format-Table -AutoSize
</syntaxhighlight>
<b>Output:</b>
<pre>
t Analytical Euler h = 2 Euler h = 5 Euler h = 10 Error h = 2 Error h = 5 Error h = 10
- ---------- ----------- ----------- ------------ ----------- ----------- ------------
0 100.00000 100.00000 100.00000 100.00000 0.00000 0.00000 0.00000
10 59.72682 57.63416 53.80000 44.00000 2.09266 5.92682 15.72682
20 39.72776 37.70413 34.28050 27.20000 2.02363 5.44726 12.52776
30 29.79651 28.32850 26.03351 22.16000 1.46801 3.76300 7.63651
40 24.86481 23.91795 22.54916 20.64800 0.94685 2.31565 4.21681
50 22.41579 21.84311 21.07702 20.19440 0.57268 1.33877 2.22139
60 21.19965 20.86705 20.45504 20.05832 0.33260 0.74461 1.14133
70 20.59573 20.40788 20.19225 20.01750 0.18784 0.40347 0.57823
80 20.29583 20.19188 20.08123 20.00525 0.10395 0.21460 0.29058
90 20.14690 20.09027 20.03432 20.00157 0.05664 0.11259 0.14533
100 20.07295 20.04246 20.01450 20.00047 0.03049 0.05845 0.07248
</pre>
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">Define.d
Prototype.d Func(Time, t)
 
Line 1,035 ⟶ 3,383:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
<pre>...
85.000 20.053
Line 1,055 ⟶ 3,403:
=={{header|Python}}==
{{trans|Common Lisp}}
<langsyntaxhighlight lang="python">def euler(f,y0,a,b,h):
t,y = a,y0
while t <= b:
print "%6.3f %6.3f" % (t,y)
t += h
Line 1,066 ⟶ 3,414:
 
euler(newtoncooling,100,0,100,10)
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,079 ⟶ 3,427:
80.000 20.005
90.000 20.002
100.000 20.000
</pre>
 
=={{header|RubyR}}==
{{trans|Python}}
<langsyntaxhighlight rubylang="rsplus">def euler <- function(f, y0, a, b,h, &blockh)
{
t,y = a,y0
while t <- ba
y <- y0
puts "%6.3f %6.3f" % [t,y]
t += h
while (t < b)
y += h * block.call(t,y)
end{
cat(sprintf("%6.3f %6.3f\n", t, y))
end
t <- t + h
y <- y + h*f(t, y)
}
}
 
newtoncooling <- function(time, temp){
return(-0.07*(temp-20))
}
 
euler(newtoncooling, 100, 0, 100, 10) {|time, temp| -0.07 * (temp - 20) } </syntaxhighlight>
</lang>
Output:
<pre> 0.000 100.000
0.000 100.000
10.000 44.000
20.000 27.200
Line 1,105 ⟶ 3,460:
70.000 20.017
80.000 20.005
90.000 20.002</pre>
 
=={{header|Racket}}==
 
The ODE solver:
<syntaxhighlight lang="racket">
(define (ODE-solve f init
#:x-max x-max
#:step h
#:method (method euler))
(reverse
(iterate-while (λ (x . y) (<= x x-max)) (method f h) init)))
</syntaxhighlight>
 
It uses the default integration method <tt>euler</tt>, defined separately.
 
<syntaxhighlight lang="racket">
(define (euler F h)
(λ (x y) (list (+ x h) (+ y (* h (F x y))))))
</syntaxhighlight>
 
A general-purpose procedure which evalutes a given function ''f'' repeatedly starting with argument ''x'', while all results satisfy a predicate ''test''. Returns a list of iterations.
 
<syntaxhighlight lang="racket">
(define (iterate-while test f x)
(let next ([result x]
[list-of-results '()])
(if (apply test result)
(next (apply f result) (cons result list-of-results))
list-of-results)))
</syntaxhighlight>
 
Textual output:
<syntaxhighlight lang="racket">
> (define (newton-cooling t T)
(* -0.07 (- T 20)))
> (ODE-solve newton-cooling '(0 100) #:x-max 100 #:step 10)
'((0 100)
(10 44.)
(20 27.2)
(30 22.16)
(40 20.648)
(50 20.1944)
(60 20.05832)
(70 20.017496)
(80 20.0052488)
(90 20.00157464)
(100 20.000472392))
</syntaxhighlight>
 
Plotting results:
<syntaxhighlight lang="racket">
> (require plot)
> (plot
(map (λ (h c)
(lines
(ODE-solve newton-cooling '(0 100) #:x-max 100 #:step h)
#:color c #:label (format "h=~a" h)))
'(10 5 1)
'(red blue black))
#:legend-anchor 'top-right)
</syntaxhighlight>
[[File:euler1.jpg]]
 
High modularity of the program allows to implement very different solution metods. For example
[http://en.wikipedia.org/wiki/Midpoint_method 2-nd order Runge-Kutta method]:
 
<syntaxhighlight lang="racket">
(define (RK2 F h)
(λ (x y)
(list (+ x h) (+ y (* h (F (+ x (* 1/2 h))
(+ y (* 1/2 h (F x y)))))))))
</syntaxhighlight>
 
[http://en.wikipedia.org/wiki/Adams_method#Two-step_Adams.E2.80.93Bashforth Two-step Adams–Bashforth method]
<syntaxhighlight lang="racket">
(define (adams F h)
(case-lambda
; first step using Runge-Kutta method
[(x y) (append ((RK2 F h) x y) (list (F x y)))]
[(x y f′)
(let ([f (F x y)])
(list (+ x h) (+ y (* 3/2 h f) (* -1/2 h f′)) f))]))
</syntaxhighlight>
 
[http://en.wikipedia.org/wiki/Adaptive_stepsize Adaptive one-step method] modifier using absolute accuracy ''ε''
<syntaxhighlight lang="racket">
(define ((adaptive method ε) F h0)
(case-lambda
[(x y) (((adaptive method ε) F h0) x y h0)]
[(x y h)
(match-let* ([(list x0 y0) ((method F h) x y)]
[(list x1 y1) ((method F (/ h 2)) x y)]
[(list x1 y1) ((method F (/ h 2)) x1 y1)]
[τ (abs (- y1 y0))]
[h′ (if (< τ ε) (min h h0) (* 0.9 h (/ ε τ)))])
(list x1 (+ y1 τ) (* 2 h′)))]))
 
</syntaxhighlight>
 
Comparison of different integration methods
<syntaxhighlight lang="racket">
> (define (solve-newton-cooling-by m)
(ODE-solve newton-cooling '(0 100)
#:x-max 100 #:step 10 #:method m))
> (plot
(list
(function (λ (t) (+ 20 (* 80 (exp (* -0.07 t))))) 0 100
#:color 'black #:label "analytical")
(lines (solve-newton-cooling-by euler)
#:color 'red #:label "Euler")
(lines (solve-newton-cooling-by RK2)
#:color 'blue #:label "Runge-Kutta")
(lines (solve-newton-cooling-by adams)
#:color 'purple #:label "Adams")
(points (solve-newton-cooling-by (adaptive euler 0.5))
#:color 'red #:label "Adaptive Euler")
(points (solve-newton-cooling-by (adaptive RK2 0.5))
#:color 'blue #:label "Adaptive Runge-Kutta"))
#:legend-anchor 'top-right)
</syntaxhighlight>
 
[[File:euler2.jpg]]
 
See also [[Runge-Kutta method#Racket]]
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub euler ( &f, $y0, $a, $b, $h ) {
my $y = $y0;
my @t_y;
for $a, * + $h ... * > $b -> $t {
@t_y[$t] = $y;
$y += $h × f( $t, $y );
}
@t_y
}
 
constant COOLING_RATE = 0.07;
constant AMBIENT_TEMP = 20;
constant INITIAL_TEMP = 100;
constant INITIAL_TIME = 0;
constant FINAL_TIME = 100;
 
sub f ( $time, $temp ) {
-COOLING_RATE × ( $temp - AMBIENT_TEMP )
}
 
my @e;
@e[$_] = euler( &f, INITIAL_TEMP, INITIAL_TIME, FINAL_TIME, $_ ) for 2, 5, 10;
 
say 'Time Analytic Step2 Step5 Step10 Err2 Err5 Err10';
 
for INITIAL_TIME, * + 10 ... * >= FINAL_TIME -> $t {
 
my $exact = AMBIENT_TEMP + (INITIAL_TEMP - AMBIENT_TEMP)
× (-COOLING_RATE × $t).exp;
 
my $err = sub { @^a.map: { 100 × ($_ - $exact).abs / $exact } }
 
my ( $a, $b, $c ) = map { @e[$_][$t] }, 2, 5, 10;
 
say $t.fmt('%4d '), ( $exact, $a, $b, $c )».fmt(' %7.3f'),
$err([$a, $b, $c])».fmt(' %7.3f%%');
}</syntaxhighlight>
 
Output:<pre>Time Analytic Step2 Step5 Step10 Err2 Err5 Err10
0 100.000 100.000 100.000 100.000 0.000% 0.000% 0.000%
10 59.727 57.634 53.800 44.000 3.504% 9.923% 26.331%
20 39.728 37.704 34.281 27.200 5.094% 13.711% 31.534%
30 29.797 28.328 26.034 22.160 4.927% 12.629% 25.629%
40 24.865 23.918 22.549 20.648 3.808% 9.313% 16.959%
50 22.416 21.843 21.077 20.194 2.555% 5.972% 9.910%
60 21.200 20.867 20.455 20.058 1.569% 3.512% 5.384%
70 20.596 20.408 20.192 20.017 0.912% 1.959% 2.808%
80 20.296 20.192 20.081 20.005 0.512% 1.057% 1.432%
90 20.147 20.090 20.034 20.002 0.281% 0.559% 0.721%
100 20.073 20.042 20.014 20.000 0.152% 0.291% 0.361%</pre>
 
=={{header|REXX}}==
===version 1===
{{trans|PLI}}
<syntaxhighlight lang="rexx">/* REXX ***************************************************************
* 24.05.2013 Walter Pachl translated from PL/I
**********************************************************************/
Numeric Digits 100
T0=100
Tr=20
k=0.07
 
h=2
x=t0
Call head
do t=0 to 100 by 2
Select
When t<=4 | t>=96 Then
call o x
When t=8 Then
Say '...'
Otherwise
Nop
End
x=x+h*f(x)
end
 
h=5
y=t0
Call head
do t=0 to 100 by 5
call o y
y=y+h*f(y)
end
 
h=10
z=t0
Call head
do t=0 to 100 by 10
call o z
z=z+h*f(z)
end
Exit
 
f: procedure Expose k Tr
Parse Arg t
return -k*(T-Tr)
 
head:
Say 'h='h
Say ' t By formula By Euler'
Return
 
o:
Parse Arg v
Say right(t,3) format(Tr+(T0-Tr)/exp(k*t),5,10) format(v,5,10)
Return
 
exp: Procedure
Parse Arg x,prec
If prec<9 Then prec=9
Numeric Digits (2*prec)
Numeric Fuzz 3
o=1
u=1
r=1
Do i=1 By 1
ra=r
o=o*x
u=u*i
r=r+(o/u)
If r=ra Then Leave
End
Numeric Digits (prec)
r=r+0
Return r
</syntaxhighlight>
Output:
<pre>
h=2
t By formula By Euler
0 100.0000000000 100.0000000000
2 89.5486587628 88.8000000000
4 80.4626994233 79.1680000000
...
96 20.0965230572 20.0574137147
98 20.0839131147 20.0493757946
100 20.0729505571 20.0424631834
h=5
t By formula By Euler
0 100.0000000000 100.0000000000
5 76.3750471216 72.0000000000
10 59.7268242534 53.8000000000
15 47.9950199099 41.9700000000
20 39.7277571000 34.2805000000
25 33.9019154664 29.2823250000
30 29.7965142633 26.0335112500
35 26.9034869314 23.9217823125
40 24.8648050015 22.5491585031
45 23.4281701466 21.6569530270
50 22.4157906708 21.0770194676
55 21.7023789162 20.7000626539
60 21.1996461464 20.4550407250
65 20.8453763508 20.2957764713
70 20.5957266443 20.1922547063
75 20.4198014729 20.1249655591
80 20.2958290978 20.0812276134
85 20.2084672415 20.0527979487
90 20.1469043822 20.0343186667
95 20.1035217684 20.0223071333
100 20.0729505571 20.0144996367
h=10
t By formula By Euler
0 100.0000000000 100.0000000000
10 59.7268242534 44.0000000000
20 39.7277571000 27.2000000000
30 29.7965142633 22.1600000000
40 24.8648050015 20.6480000000
50 22.4157906708 20.1944000000
60 21.1996461464 20.0583200000
70 20.5957266443 20.0174960000
80 20.2958290978 20.0052488000
90 20.1469043822 20.0015746400
100 20.0729505571 20.0004723920</pre>
 
===version 2===
This REXX version allows values to be specified via the command line (CL).
 
<br>It also shows the percentage difference (analytic vs. Euler's method) for each calculation.
<syntaxhighlight lang="rexx">/*REXX pgm solves example of Newton's cooling law via Euler's method (diff. step sizes).*/
e=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138
numeric digits length(e) - length(.) /*use the number of decimal digits in E*/
parse arg Ti Tr cc tt ss /*obtain optional arguments from the CL*/
if Ti='' | Ti="," then Ti= 100 /*given? Default: initial temp in ºC.*/
if Tr='' | Tr="," then Tr= 20 /* " " room " " " */
if cc='' | cc="," then cc= 0.07 /* " " cooling constant. */
if tt='' | tt="," then tt= 100 /* " " total time seconds. */
if ss='' | ss="," then ss= 2 5 10 /* " " the step sizes. */
@= '═' /*the character used in title separator*/
do sSize=1 for words(ss); say; say; say center('time in' , 11)
say center('seconds' , 11, @) center('Euler method', 16, @) ,
center('analytic', 18, @) center('difference' , 14, @)
$=Ti; inc= word(ss, sSize) /*the 1st value; obtain the increment.*/
do t=0 to Ti by inc /*step through calculations by the inc.*/
a= format(Tr + (Ti-Tr)/exp(cc*t),6,10) /*calculate the analytic (exact) value.*/
say center(t,11) format($,6,3) 'ºC ' a "ºC" format(abs(a-$)/a*100,6,2) '%'
$= $ + inc * cc * (Tr-$) /*calc. next value via Euler's method. */
end /*t*/
end /*sSize*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
exp: procedure expose e; arg x; ix= x%1; if abs(x-ix)>.5 then ix=ix+sign(x); x= x-ix; z=1
_=1; w=1; do j=1; _= _*x/j; z= (z+_)/1; if z==w then leave; w=z
end /*j*/; if z\==0 then z= e**ix * z; return z</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
time in
══seconds══ ══Euler method══ ═════analytic═════ ══difference══
0 100.000 ºC 100.0000000000 ºC 0.00 %
2 88.800 ºC 89.5486588319 ºC 0.84 %
4 79.168 ºC 80.4626993165 ºC 1.61 %
6 70.884 ºC 72.5637455852 ºC 2.31 %
8 63.761 ºC 65.6967251079 ºC 2.95 %
10 57.634 ºC 59.7268243033 ºC 3.50 %
12 52.365 ºC 54.5368418743 ºC 3.98 %
14 47.834 ºC 50.0248879081 ºC 4.38 %
16 43.937 ºC 46.1023835698 ºC 4.70 %
18 40.586 ºC 42.6923221200 ºC 4.93 %
20 37.704 ºC 39.7277571153 ºC 5.09 %
22 35.226 ºC 37.1504881142 ºC 5.18 %
24 33.094 ºC 34.9099180832 ºC 5.20 %
26 31.261 ºC 32.9620600747 ºC 5.16 %
28 29.684 ºC 31.2686736737 ºC 5.07 %
30 28.328 ºC 29.7965142602 ºC 4.93 %
32 27.163 ºC 28.5166803503 ºC 4.75 %
34 26.160 ºC 27.4040462008 ºC 4.54 %
36 25.297 ºC 26.4367685400 ºC 4.31 %
38 24.556 ºC 25.5958577396 ºC 4.06 %
40 23.918 ºC 24.8648050100 ºC 3.81 %
42 23.369 ºC 24.2292582991 ºC 3.55 %
44 22.898 ºC 23.6767405319 ºC 3.29 %
46 22.492 ºC 23.1964046609 ºC 3.04 %
48 22.143 ºC 22.7788207156 ºC 2.79 %
50 21.843 ºC 22.4157906738 ºC 2.55 %
52 21.585 ºC 22.1001875173 ºC 2.33 %
54 21.363 ºC 21.8258153140 ºC 2.12 %
56 21.172 ºC 21.5872875795 ºC 1.92 %
58 21.008 ºC 21.3799215292 ºC 1.74 %
60 20.867 ºC 21.1996461456 ºC 1.57 %
62 20.746 ºC 21.0429222563 ºC 1.41 %
64 20.641 ºC 20.9066730524 ºC 1.27 %
66 20.551 ºC 20.7882236849 ºC 1.14 %
68 20.474 ºC 20.6852487518 ºC 1.02 %
70 20.408 ºC 20.5957266457 ºC 0.91 %
72 20.351 ºC 20.5178998655 ºC 0.81 %
74 20.302 ºC 20.4502405132 ºC 0.73 %
76 20.259 ºC 20.3914202980 ºC 0.65 %
78 20.223 ºC 20.3402844596 ºC 0.58 %
80 20.192 ºC 20.2958290973 ºC 0.51 %
82 20.165 ºC 20.2571814620 ºC 0.45 %
84 20.142 ºC 20.2235828220 ºC 0.40 %
86 20.122 ºC 20.1943735676 ºC 0.36 %
88 20.105 ºC 20.1689802617 ºC 0.32 %
90 20.090 ºC 20.1469043822 ºC 0.28 %
92 20.078 ºC 20.1277125344 ºC 0.25 %
94 20.067 ºC 20.1110279436 ºC 0.22 %
96 20.057 ºC 20.0965230571 ºC 0.19 %
98 20.049 ºC 20.0839131146 ºC 0.17 %
100 20.042 ºC 20.0729505572 ºC 0.15 %
 
 
time in
══seconds══ ══Euler method══ ═════analytic═════ ══difference══
0 100.000 ºC 100.0000000000 ºC 0.00 %
5 72.000 ºC 76.3750471775 ºC 5.73 %
10 53.800 ºC 59.7268243033 ºC 9.92 %
15 41.970 ºC 47.9950199289 ºC 12.55 %
20 34.281 ºC 39.7277571153 ºC 13.71 %
25 29.282 ºC 33.9019154760 ºC 13.63 %
30 26.034 ºC 29.7965142602 ºC 12.63 %
35 23.922 ºC 26.9034869199 ºC 11.08 %
40 22.549 ºC 24.8648050100 ºC 9.31 %
45 21.657 ºC 23.4281701494 ºC 7.56 %
50 21.077 ºC 22.4157906738 ºC 5.97 %
55 20.700 ºC 21.7023789151 ºC 4.62 %
60 20.455 ºC 21.1996461456 ºC 3.51 %
65 20.296 ºC 20.8453763507 ºC 2.64 %
70 20.192 ºC 20.5957266457 ºC 1.96 %
75 20.125 ºC 20.4198014719 ºC 1.44 %
80 20.081 ºC 20.2958290973 ºC 1.06 %
85 20.053 ºC 20.2084672415 ºC 0.77 %
90 20.034 ºC 20.1469043822 ºC 0.56 %
95 20.022 ºC 20.1035217684 ºC 0.40 %
100 20.014 ºC 20.0729505572 ºC 0.29 %
 
 
time in
══seconds══ ══Euler method══ ═════analytic═════ ══difference══
0 100.000 ºC 100.0000000000 ºC 0.00 %
10 44.000 ºC 59.7268243033 ºC 26.33 %
20 27.200 ºC 39.7277571153 ºC 31.53 %
30 22.160 ºC 29.7965142602 ºC 25.63 %
40 20.648 ºC 24.8648050100 ºC 16.96 %
50 20.194 ºC 22.4157906738 ºC 9.91 %
60 20.058 ºC 21.1996461456 ºC 5.38 %
70 20.017 ºC 20.5957266457 ºC 2.81 %
80 20.005 ºC 20.2958290973 ºC 1.43 %
90 20.002 ºC 20.1469043822 ºC 0.72 %
100 20.000 ºC 20.0729505572 ºC 0.36 %
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
decimals(3)
see euler("return -0.07*(y-20)", 100, 0, 100, 2) + nl
see euler("return -0.07*(y-20)", 100, 0, 100, 5) + nl
see euler("return -0.07*(y-20)", 100, 0, 100, 10) + nl
 
func euler df, y, a, b, s
t = a
while t <= b
see "" + t + " " + y + nl
y += s * eval(df)
t += s
end
return y</syntaxhighlight>
Output:
<pre>
0 100
2 88.800
4 79.168
6 70.884
8 63.761
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}}==
{{trans|Python}}
<syntaxhighlight lang="ruby">def euler(y, a, b, h)
a.step(b,h) do |t|
puts "%7.3f %7.3f" % [t,y]
y += h * yield(t,y)
end
end
 
[10, 5, 2].each do |step|
puts "Step = #{step}"
euler(100,0,100,step) {|time, temp| -0.07 * (temp - 20) }
puts
end</syntaxhighlight>
{{out}}
<pre style="height: 40ex; overflow: scroll">
Step = 10
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
100.000 20.000
 
Step = 5
0.000 100.000
5.000 72.000
10.000 53.800
15.000 41.970
20.000 34.280
25.000 29.282
30.000 26.034
35.000 23.922
40.000 22.549
45.000 21.657
50.000 21.077
55.000 20.700
60.000 20.455
65.000 20.296
70.000 20.192
75.000 20.125
80.000 20.081
85.000 20.053
90.000 20.034
95.000 20.022
100.000 20.014
 
Step = 2
0.000 100.000
2.000 88.800
4.000 79.168
6.000 70.884
8.000 63.761
10.000 57.634
12.000 52.365
14.000 47.834
16.000 43.937
18.000 40.586
20.000 37.704
22.000 35.226
24.000 33.094
26.000 31.261
28.000 29.684
30.000 28.328
32.000 27.163
34.000 26.160
36.000 25.297
38.000 24.556
40.000 23.918
42.000 23.369
44.000 22.898
46.000 22.492
48.000 22.143
50.000 21.843
52.000 21.585
54.000 21.363
56.000 21.172
58.000 21.008
60.000 20.867
62.000 20.746
64.000 20.641
66.000 20.551
68.000 20.474
70.000 20.408
72.000 20.351
74.000 20.302
76.000 20.259
78.000 20.223
80.000 20.192
82.000 20.165
84.000 20.142
86.000 20.122
88.000 20.105
90.000 20.090
92.000 20.078
94.000 20.067
96.000 20.057
98.000 20.049
100.000 20.042
</pre>
 
=={{header|Rust}}==
{{trans|Kotlin}}
<syntaxhighlight lang="rust">fn header() {
print!(" Time: ");
for t in (0..100).step_by(10) {
print!(" {:7}", t);
}
println!();
}
 
fn analytic() {
print!("Analytic: ");
for t in (0..=100).step_by(10) {
print!(" {:7.3}", 20.0 + 80.0 * (-0.07 * f64::from(t)).exp());
}
println!();
}
 
fn euler<F: Fn(f64) -> f64>(f: F, mut y: f64, step: usize, end: usize) {
print!(" Step {:2}: ", step);
for t in (0..=end).step_by(step) {
if t % 10 == 0 {
print!(" {:7.3}", y);
}
y += step as f64 * f(y);
}
println!();
}
 
fn main() {
header();
analytic();
for &i in &[2, 5, 10] {
euler(|temp| -0.07 * (temp - 20.0), 100.0, i, 100);
}
}</syntaxhighlight>
{{out}}
<pre> Time: 0 10 20 30 40 50 60 70 80 90
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|Scala}}==
 
<langsyntaxhighlight lang="scala">
object App{
 
Line 1,140 ⟶ 4,121:
 
}
</syntaxhighlight>
</lang>
 
Output for step = 10;
Line 1,158 ⟶ 4,139:
</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}}==
 
<syntaxhighlight lang="sequencel">import <Utilities/Conversion.sl>;
import <Utilities/Sequence.sl>;
 
T0 := 100.0;
TR := 20.0;
k := 0.07;
 
main(args(2)) :=
let
results[i] := euler(newtonCooling, T0, 100, stringToInt(args[i]), 0, "delta_t = " ++ args[i]);
in
delimit(results, '\n');
 
newtonCooling(t) := -k * (t - TR);
 
euler: (float -> float) * float * int * int * int * char(1) -> char(1);
euler(f, y, n, h, x, output(1)) :=
let
newOutput := output ++ "\n\t" ++ intToString(x) ++ "\t" ++ floatToString(y, 3);
newY := y + h * f(y);
newX := x + h;
in
output when x > n
else
euler(f, newY, n, h, newX, newOutput);</syntaxhighlight>
Based on C# version [http://rosettacode.org/wiki/Euler_method#C.23] but using tail recursion instead of looping.
{{out}}
 
For step size 10:
<pre>
main.exe 10
"delta_t = 10
0 100.000
10 44.000
20 27.200
30 22.160
40 20.648
50 20.194
60 20.058
70 20.017
80 20.005
90 20.002
100 20.000"
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">func euler_method(t0, t1, k, step_size) {
var results = [[0, t0]]
for s in (step_size..100 -> by(step_size)) {
t0 -= ((t0 - t1) * k * step_size)
results << [s, t0]
}
return results;
}
 
func analytical(t0, t1, k, time) {
(t0 - t1) * exp(-time * k) + t1
}
 
var (T0, T1, k) = (100, 20, .07)
var r2 = euler_method(T0, T1, k, 2).grep { _[0] %% 10 }
var r5 = euler_method(T0, T1, k, 5).grep { _[0] %% 10 }
var r10 = euler_method(T0, T1, k, 10).grep { _[0] %% 10 }
 
say "Time\t 2 err(%) 5 err(%) 10 err(%) Analytic"
say "-"*76
 
r2.range.each { |i|
var an = analytical(T0, T1, k, r2[i][0])
printf("%4d\t#{'%9.3f' * 7}\n",
r2[i][0],
r2[i][1], ( r2[i][1] / an) * 100 - 100,
r5[i][1], ( r5[i][1] / an) * 100 - 100,
r10[i][1], (r10[i][1] / an) * 100 - 100,
an)
}</syntaxhighlight>
{{out}}
<pre>
Time 2 err(%) 5 err(%) 10 err(%) Analytic
----------------------------------------------------------------------------
0 100.000 0.000 100.000 0.000 100.000 0.000 100.000
10 57.634 -3.504 53.800 -9.923 44.000 -26.331 59.727
20 37.704 -5.094 34.281 -13.711 27.200 -31.534 39.728
30 28.328 -4.927 26.034 -12.629 22.160 -25.629 29.797
40 23.918 -3.808 22.549 -9.313 20.648 -16.959 24.865
50 21.843 -2.555 21.077 -5.972 20.194 -9.910 22.416
60 20.867 -1.569 20.455 -3.512 20.058 -5.384 21.200
70 20.408 -0.912 20.192 -1.959 20.017 -2.808 20.596
80 20.192 -0.512 20.081 -1.057 20.005 -1.432 20.296
90 20.090 -0.281 20.034 -0.559 20.002 -0.721 20.147
100 20.042 -0.152 20.014 -0.291 20.000 -0.361 20.073
</pre>
 
=={{header|Smalltalk}}==
<syntaxhighlight lang="smalltalk">ODESolver>>eulerOf: f init: y0 from: a to: b step: h
| t y |
t := a.
y := y0.
[ t < b ]
whileTrue: [
Transcript
show: t asString, ' ' , (y printShowingDecimalPlaces: 3);
cr.
t := t + h.
y := y + (h * (f value: t value: y)) ]
 
ODESolver new eulerOf: [:time :temp| -0.07 * (temp - 20)] init: 100 from: 0 to: 100 step: 10
</syntaxhighlight>
Transcript:
<pre>
0 100.000
10 44.000
20 27.200
30 22.160
40 20.648
50 20.194
60 20.058
70 20.017
80 20.005
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}}==
{{trans|C}}
<syntaxhighlight lang="swift">import Foundation
 
let numberFormat = " %7.3f"
let k = 0.07
let initialTemp = 100.0
let finalTemp = 20.0
let startTime = 0
let endTime = 100
 
func ivpEuler(function: (Double, Double) -> Double, initialValue: Double, step: Int) {
print(String(format: " Step %2d: ", step), terminator: "")
var y = initialValue
for t in stride(from: startTime, through: endTime, by: step) {
if t % 10 == 0 {
print(String(format: numberFormat, y), terminator: "")
}
y += Double(step) * function(Double(t), y)
}
print()
}
 
func analytic() {
print(" Time: ", terminator: "")
for t in stride(from: startTime, through: endTime, by: 10) {
print(String(format: " %7d", t), terminator: "")
}
print("\nAnalytic: ", terminator: "")
for t in stride(from: startTime, through: endTime, by: 10) {
let temp = finalTemp + (initialTemp - finalTemp) * exp(-k * Double(t))
print(String(format: numberFormat, temp), terminator: "")
}
print()
}
 
func cooling(t: Double, temp: Double) -> Double {
return -k * (temp - finalTemp)
}
 
analytic()
ivpEuler(function: cooling, initialValue: initialTemp, step: 2)
ivpEuler(function: cooling, initialValue: initialTemp, step: 5)
ivpEuler(function: cooling, initialValue: initialTemp, step: 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|Tcl}}==
{{trans|C++}}
<langsyntaxhighlight lang="tcl">proc euler {f y0 a b h} {
puts "computing $f over \[$a..$b\], step $h"
set y [expr {double($y0)}]
Line 1,169 ⟶ 4,399:
}
puts "done"
}</langsyntaxhighlight>
Demonstration with the Newton Cooling Law:
<langsyntaxhighlight lang="tcl">proc newtonCoolingLaw {time temp} {
expr {-0.07 * ($temp - 20)}
}
Line 1,177 ⟶ 4,407:
euler newtonCoolingLaw 100 0 100 2
euler newtonCoolingLaw 100 0 100 5
euler newtonCoolingLaw 100 0 100 10</langsyntaxhighlight>
End of output:
<pre>
Line 1,194 ⟶ 4,424:
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>
 
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Private Sub ivp_euler(f As String, y As Double, step As Integer, end_t As Integer)
Dim t As Integer
Debug.Print " Step "; step; ": ",
Do While t <= end_t
If t Mod 10 = 0 Then Debug.Print Format(y, "0.000"),
y = y + step * Application.Run(f, y)
t = t + step
Loop
Debug.Print
End Sub
Sub analytic()
Debug.Print " Time: ",
For t = 0 To 100 Step 10
Debug.Print " "; t,
Next t
Debug.Print
Debug.Print "Analytic: ",
For t = 0 To 100 Step 10
Debug.Print Format(20 + 80 * Exp(-0.07 * t), "0.000"),
Next t
Debug.Print
End Sub
Private Function cooling(temp As Double) As Double
cooling = -0.07 * (temp - 20)
End Function
 
Public Sub euler_method()
Dim r_cooling As String
r_cooling = "cooling"
analytic
ivp_euler r_cooling, 100, 2, 100
ivp_euler r_cooling, 100, 5, 100
ivp_euler r_cooling, 100, 10, 100
End Sub</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,281 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|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="go">import math
// Fdy is a type for fntion f used in Euler's method.
type Fdy = fn(f64, f64) f64
// euler_step computes a single new value using Euler's method.
// Note that step size h is a parameter, so a variable step size
// could be used.
fn euler_step(f Fdy, x f64, y f64, h f64) f64 {
return y + h*f(x, y)
}
// Definition of cooling rate. Note that this has general utility and
// is not specific to use in Euler's method.
// new_cooling_rate returns a fntion that computes cooling rate
// for a given cooling rate constant k.
fn new_cooling_rate(k f64) fn(f64) f64 {
return fn[k](delta_temp f64) f64 {
return -k * delta_temp
}
}
// new_temp_func returns a fntion that computes the analytical solution
// of cooling rate integrated over time.
fn new_temp_func(k f64, ambient_temp f64, initial_temp f64) fn(f64) f64 {
return fn[ambient_temp,initial_temp,k](time f64) f64 {
return ambient_temp + (initial_temp-ambient_temp)*math.exp(-k*time)
}
}
// new_cooling_rate_dy returns a fntion of the kind needed for Euler's method.
// That is, a fntion representing dy(x, y(x)).
//
// Parameters to new_cooling_rate_dy are cooling constant k and ambient
// temperature.
fn new_cooling_rate_dy(k f64, ambient_temp f64) Fdy {
// note that result is dependent only on the object temperature.
// there are no additional dependencies on time, so the x parameter
// provided by euler_step is unused.
return fn[k,ambient_temp](_ f64, object_temp f64) f64 {
return new_cooling_rate(k)(object_temp - ambient_temp)
}
}
fn main() {
k := .07
temp_room := 20.0
temp_object := 100.0
fcr := new_cooling_rate_dy(k, temp_room)
analytic := new_temp_func(k, temp_room, temp_object)
for delta_time in [2.0, 5, 10] {
println("Step size = ${delta_time:.1f}")
println(" Time Euler's Analytic")
mut temp := temp_object
for time := 0.0; time <= 100; time += delta_time {
println("${time:5.1f} ${temp:7.3f} ${analytic(time):7.3f}")
temp = euler_step(fcr, time, temp, delta_time)
}
println('')
}
}</syntaxhighlight>
Output, truncated:
<pre>
...
85.0 20.053 20.208
90.0 20.034 20.147
95.0 20.022 20.104
100.0 20.014 20.073
 
Step size = 10.0
Time Euler's Analytic
0.0 100.000 100.000
10.0 44.000 59.727
20.0 27.200 39.728
30.0 22.160 29.797
40.0 20.648 24.865
50.0 20.194 22.416
60.0 20.058 21.200
70.0 20.017 20.596
80.0 20.005 20.296
90.0 20.002 20.147
100.0 20.000 20.073
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
proc Euler(Step); \Display cooling temperatures using Euler's method
int Step;
int Time; real Temp;
[Text(0, "Step "); IntOut(0, Step); Text(0, " ");
Time:= 0; Temp:= 100.0;
repeat if rem(Time/10) = 0 then RlOut(0, Temp);
Temp:= Temp + float(Step) * (-0.07*(Temp-20.0));
Time:= Time + Step;
until Time > 100;
CrLf(0);
];
 
real Time, Temp;
[Format(6,0); \display time heading
Text(0, "Time ");
Time:= 0.0;
while Time <= 100.1 do \(.1 avoids possible rounding error)
[RlOut(0, Time);
Time:= Time + 10.0;
];
CrLf(0);
 
Format(3,2); \display cooling temps using differential eqn.
Text(0, "Dif eq "); \ dTemp(time)/dtime = -k*�Temp
Time:= 0.0;
while Time <= 100.1 do
[Temp:= 20.0 + (100.0-20.0) * Exp(-0.07*Time);
RlOut(0, Temp);
Time:= Time + 10.0;
];
CrLf(0);
 
Euler(2); \display cooling temps for various time steps
Euler(5);
Euler(10);
]</syntaxhighlight>
 
Output:
<pre>
Time 0 10 20 30 40 50 60 70 80 90 100
Dif eq 100.00 59.73 39.73 29.80 24.86 22.42 21.20 20.60 20.30 20.15 20.07
Step 2 100.00 57.63 37.70 28.33 23.92 21.84 20.87 20.41 20.19 20.09 20.04
Step 5 100.00 53.80 34.28 26.03 22.55 21.08 20.46 20.19 20.08 20.03 20.01
Step 10 100.00 44.00 27.20 22.16 20.65 20.19 20.06 20.02 20.01 20.00 20.00
</pre>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|Wren-fmt}}
{{libheader|Wren-iterate}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
import "./iterate" for Stepped
 
var euler = Fn.new { |f, y, step, end|
Fmt.write(" Step $2d: ", step)
for (t in Stepped.new(0..end, step)) {
if (t%10 == 0) Fmt.write(" $7.3f", y)
y = y + step * f.call(y)
}
System.print()
}
 
var analytic = Fn.new {
System.write(" Time: ")
for (t in Stepped.new(0..100, 10)) Fmt.write(" $7d", t)
System.write("\nAnalytic: ")
for (t in Stepped.new(0..100, 10)) {
Fmt.write(" $7.3f", 20 + 80 * (-0.07*t).exp)
}
System.print()
}
var cooling = Fn.new { |temp| -0.07 * (temp - 20) }
 
analytic.call()
for (i in [2, 5, 10]) euler.call(cooling, 100, i, 100)</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|zkl}}==
{{trans|C}}
<syntaxhighlight lang="zkl">const FMT=" %7.3f";
fcn ivp_euler(f,y,step,end_t){
print(" Step %2d: ".fmt(step));
foreach t in ([0..end_t,step]){
if (t % 10 == 0) print(FMT.fmt(y));
y += f(t,y) * step;
}
println();
}
fcn analytic{
print(" Time: ");
foreach t in ([0..100,10]){ print(" %7g".fmt(t)) }
print("\nAnalytic: ");
foreach t in ([0..100,10]){ print(FMT.fmt(20.0 + 80.0 * (-0.07 * t).exp())) }
println();
}
fcn cooling(_,temp){ return(-0.07 * (temp - 20)) }
 
analytic();
ivp_euler(cooling, 100.0, 2, 100);
ivp_euler(cooling, 100.0, 5, 100);
ivp_euler(cooling, 100.0, 10, 100);</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|ZX Spectrum Basic}}==
{{trans|BBC_BASIC}}
<syntaxhighlight lang="zxbasic">10 LET d$="-0.07*(y-20)": LET y=100: LET a=0: LET b=100: LET s=10
20 LET t=a
30 IF t<=b THEN PRINT t;TAB 10;y: LET y=y+s*VAL d$: LET t=t+s: GO TO 30</syntaxhighlight>
2,130

edits