Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Euler-method/00-META.yaml
Normal file
3
Task/Euler-method/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Euler_method
|
||||
note: Mathematical operations
|
||||
62
Task/Euler-method/00-TASK.txt
Normal file
62
Task/Euler-method/00-TASK.txt
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
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 LHS 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 <big><math>h</math></big> is the step size, the most relevant parameter for accuracy of the solution. 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'''
|
||||
|
||||
Newton's cooling law describes how an object of initial temperature <big><math>T(t_0) = T_0</math></big> cools down in an environment of temperature <big><math>T_R</math></big>:
|
||||
|
||||
::: <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>
|
||||
It says that the cooling rate <big><math>\frac{dT(t)}{dt}</math></big> of the object is proportional to the current temperature difference <big><math>\Delta T = (T(t) - T_R)</math></big> 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>
|
||||
|
||||
|
||||
;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:
|
||||
:::* 2 s
|
||||
:::* 5 s and
|
||||
:::* 10 s
|
||||
and to compare with the analytical solution.
|
||||
|
||||
|
||||
;Initial values:
|
||||
:::* initial temperature <big><math>T_0</math></big> shall be 100 °C
|
||||
:::* room temperature <big><math>T_R</math></big> shall be 20 °C
|
||||
:::* cooling constant <big><math>k</math></big> shall be 0.07
|
||||
:::* time interval to calculate shall be from 0 s ──► 100 s
|
||||
|
||||
<br>
|
||||
A reference solution ([[#Common Lisp|Common Lisp]]) can be seen below. We see that bigger step sizes lead to reduced approximation accuracy.
|
||||
[[Image:Euler_Method_Newton_Cooling.png|center|750px]]
|
||||
|
||||
11
Task/Euler-method/11l/euler-method.11l
Normal file
11
Task/Euler-method/11l/euler-method.11l
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
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)
|
||||
24
Task/Euler-method/ALGOL-68/euler-method.alg
Normal file
24
Task/Euler-method/ALGOL-68/euler-method.alg
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
Approximates y(t) in y'(t)=f(t,y) with y(a)=y0 and
|
||||
t=a..b and the step size h.
|
||||
#
|
||||
PROC euler = (PROC(REAL,REAL)REAL f, REAL y0, a, b, h)REAL: (
|
||||
REAL y := y0,
|
||||
t := a;
|
||||
WHILE t < b DO
|
||||
printf(($g(-6,3)": "g(-7,3)l$, t, y));
|
||||
y +:= h * f(t, y);
|
||||
t +:= h
|
||||
OD;
|
||||
printf($"done"l$);
|
||||
y
|
||||
);
|
||||
|
||||
# Example: Newton's cooling law #
|
||||
PROC newton cooling law = (REAL time, t)REAL: (
|
||||
-0.07 * (t - 20)
|
||||
);
|
||||
|
||||
main: (
|
||||
euler(newton cooling law, 100, 0, 100, 10)
|
||||
)
|
||||
21
Task/Euler-method/ALGOL-W/euler-method.alg
Normal file
21
Task/Euler-method/ALGOL-W/euler-method.alg
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
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.
|
||||
93
Task/Euler-method/ATS/euler-method.ats
Normal file
93
Task/Euler-method/ATS/euler-method.ats
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#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
|
||||
11
Task/Euler-method/Ada/euler-method-1.ada
Normal file
11
Task/Euler-method/Ada/euler-method-1.ada
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
generic
|
||||
type Number is digits <>;
|
||||
package Euler is
|
||||
type Waveform is array (Integer range <>) of Number;
|
||||
function Solve
|
||||
( F : not null access function (T, Y : Number) return Number;
|
||||
Y0 : Number;
|
||||
T0, T1 : Number;
|
||||
N : Positive
|
||||
) return Waveform;
|
||||
end Euler;
|
||||
17
Task/Euler-method/Ada/euler-method-2.ada
Normal file
17
Task/Euler-method/Ada/euler-method-2.ada
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package body Euler is
|
||||
function Solve
|
||||
( F : not null access function (T, Y : Number) return Number;
|
||||
Y0 : Number;
|
||||
T0, T1 : Number;
|
||||
N : Positive
|
||||
) return Waveform is
|
||||
dT : constant Number := (T1 - T0) / Number (N);
|
||||
begin
|
||||
return Y : Waveform (0..N) do
|
||||
Y (0) := Y0;
|
||||
for I in 1..Y'Last loop
|
||||
Y (I) := Y (I - 1) + dT * F (T0 + dT * Number (I - 1), Y (I - 1));
|
||||
end loop;
|
||||
end return;
|
||||
end Solve;
|
||||
end Euler;
|
||||
18
Task/Euler-method/Ada/euler-method-3.ada
Normal file
18
Task/Euler-method/Ada/euler-method-3.ada
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Euler;
|
||||
|
||||
procedure Test_Euler_Method is
|
||||
package Float_Euler is new Euler (Float);
|
||||
use Float_Euler;
|
||||
|
||||
function Newton_Cooling_Law (T, Y : Float) return Float is
|
||||
begin
|
||||
return -0.07 * (Y - 20.0);
|
||||
end Newton_Cooling_Law;
|
||||
|
||||
Y : Waveform := Solve (Newton_Cooling_Law'Access, 100.0, 0.0, 100.0, 10);
|
||||
begin
|
||||
for I in Y'Range loop
|
||||
Put_Line (Integer'Image (10 * I) & ":" & Float'Image (Y (I)));
|
||||
end loop;
|
||||
end Test_Euler_Method;
|
||||
14
Task/Euler-method/Arturo/euler-method.arturo
Normal file
14
Task/Euler-method/Arturo/euler-method.arturo
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
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
|
||||
15
Task/Euler-method/BBC-BASIC/euler-method.basic
Normal file
15
Task/Euler-method/BBC-BASIC/euler-method.basic
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
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
|
||||
32
Task/Euler-method/C++/euler-method.cpp
Normal file
32
Task/Euler-method/C++/euler-method.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
typedef double F(double,double);
|
||||
|
||||
/*
|
||||
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 f, double y0, double a, double b, double h)
|
||||
{
|
||||
double y = y0;
|
||||
for (double t = a; t < b; t += h)
|
||||
{
|
||||
std::cout << std::fixed << std::setprecision(3) << t << " " << y << "\n";
|
||||
y += h * f(t, y);
|
||||
}
|
||||
std::cout << "done\n";
|
||||
}
|
||||
|
||||
// Example: Newton's cooling law
|
||||
double newtonCoolingLaw(double, double t)
|
||||
{
|
||||
return -0.07 * (t - 20);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
euler(newtonCoolingLaw, 100, 0, 100, 2);
|
||||
euler(newtonCoolingLaw, 100, 0, 100, 5);
|
||||
euler(newtonCoolingLaw, 100, 0, 100, 10);
|
||||
}
|
||||
38
Task/Euler-method/C-sharp/euler-method.cs
Normal file
38
Task/Euler-method/C-sharp/euler-method.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Task/Euler-method/C/euler-method-1.c
Normal file
44
Task/Euler-method/C/euler-method-1.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef double (*deriv_f)(double, double);
|
||||
#define FMT " %7.3f"
|
||||
|
||||
void ivp_euler(deriv_f f, double y, int step, int end_t)
|
||||
{
|
||||
int t = 0;
|
||||
|
||||
printf(" Step %2d: ", (int)step);
|
||||
do {
|
||||
if (t % 10 == 0) printf(FMT, y);
|
||||
y += step * f(t, y);
|
||||
} while ((t += step) <= end_t);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void analytic()
|
||||
{
|
||||
double t;
|
||||
printf(" Time: ");
|
||||
for (t = 0; t <= 100; t += 10) printf(" %7g", t);
|
||||
printf("\nAnalytic: ");
|
||||
|
||||
for (t = 0; t <= 100; t += 10)
|
||||
printf(FMT, 20 + 80 * exp(-0.07 * t));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
double cooling(double t, double temp)
|
||||
{
|
||||
return -0.07 * (temp - 20);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
analytic();
|
||||
ivp_euler(cooling, 100, 2, 100);
|
||||
ivp_euler(cooling, 100, 5, 100);
|
||||
ivp_euler(cooling, 100, 10, 100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
5
Task/Euler-method/C/euler-method-2.c
Normal file
5
Task/Euler-method/C/euler-method-2.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
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
|
||||
45
Task/Euler-method/COBOL/euler-method.cobol
Normal file
45
Task/Euler-method/COBOL/euler-method.cobol
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
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.
|
||||
16
Task/Euler-method/Clay/euler-method.clay
Normal file
16
Task/Euler-method/Clay/euler-method.clay
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import printer.formatter as pf;
|
||||
|
||||
euler(f, y, a, b, h) {
|
||||
while (a < b) {
|
||||
println(pf.rightAligned(2, a), " ", y);
|
||||
a += h;
|
||||
y += h * f(y);
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
for (i in [2.0, 5.0, 10.0]) {
|
||||
println("\nFor delta = ", i, ":");
|
||||
euler((temp) => -0.07 * (temp - 20), 100.0, 0.0, 100.0, i);
|
||||
}
|
||||
}
|
||||
21
Task/Euler-method/Clojure/euler-method.clj
Normal file
21
Task/Euler-method/Clojure/euler-method.clj
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
(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)))
|
||||
26
Task/Euler-method/Common-Lisp/euler-method-1.lisp
Normal file
26
Task/Euler-method/Common-Lisp/euler-method-1.lisp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
;; 't' usually means "true" in CL, but we need 't' here for time/temperature.
|
||||
(defconstant true 'cl:t)
|
||||
(shadow 't)
|
||||
|
||||
|
||||
;; Approximates y(t) in y'(t)=f(t,y) with y(a)=y0 and t=a..b and the step size h.
|
||||
(defun euler (f y0 a b h)
|
||||
|
||||
;; Set the initial values and increments of the iteration variables.
|
||||
(do ((t a (+ t h))
|
||||
(y y0 (+ y (* h (funcall f t y)))))
|
||||
|
||||
;; End the iteration when t reaches the end b of the time interval.
|
||||
((>= t b) 'DONE)
|
||||
|
||||
;; Print t and y(t) at every step of the do loop.
|
||||
(format true "~6,3F ~6,3F~%" t y)))
|
||||
|
||||
|
||||
;; Example: Newton's cooling law, f(t,T) = -0.07*(T-20)
|
||||
(defun newton-cooling (time T) (* -0.07 (- T 20)))
|
||||
|
||||
;; Generate the data for all three step sizes (2,5 and 10).
|
||||
(euler #'newton-cooling 100 0 100 2)
|
||||
(euler #'newton-cooling 100 0 100 5)
|
||||
(euler #'newton-cooling 100 0 100 10)
|
||||
13
Task/Euler-method/Common-Lisp/euler-method-2.lisp
Normal file
13
Task/Euler-method/Common-Lisp/euler-method-2.lisp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
;; 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)))
|
||||
48
Task/Euler-method/Craft-Basic/euler-method.basic
Normal file
48
Task/Euler-method/Craft-Basic/euler-method.basic
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
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
|
||||
22
Task/Euler-method/D/euler-method.d
Normal file
22
Task/Euler-method/D/euler-method.d
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
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
|
||||
if (isCallable!F && __traits(compiles, { real r = f(0.0, 0.0); })) {
|
||||
double y = y0;
|
||||
foreach (immutable t; iota(a, b, h)) {
|
||||
writefln("%.3f %.3f", t, y);
|
||||
y += h * f(t, y);
|
||||
}
|
||||
"done".writeln;
|
||||
}
|
||||
|
||||
void main() {
|
||||
/// Example: Newton's cooling law.
|
||||
enum newtonCoolingLaw = (in double time, in double t)
|
||||
pure 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);
|
||||
}
|
||||
13
Task/Euler-method/Elixir/euler-method.elixir
Normal file
13
Task/Euler-method/Elixir/euler-method.elixir
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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)
|
||||
38
Task/Euler-method/Erlang/euler-method.erl
Normal file
38
Task/Euler-method/Erlang/euler-method.erl
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
-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.
|
||||
21
Task/Euler-method/Euler/euler-method.euler
Normal file
21
Task/Euler-method/Euler/euler-method.euler
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
>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
|
||||
17
Task/Euler-method/F-Sharp/euler-method.fs
Normal file
17
Task/Euler-method/F-Sharp/euler-method.fs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
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
|
||||
17
Task/Euler-method/Factor/euler-method.factor
Normal file
17
Task/Euler-method/Factor/euler-method.factor
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
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
|
||||
14
Task/Euler-method/Forth/euler-method.fth
Normal file
14
Task/Euler-method/Forth/euler-method.fth
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
: 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
|
||||
57
Task/Euler-method/Fortran/euler-method.f
Normal file
57
Task/Euler-method/Fortran/euler-method.f
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
program euler_method
|
||||
use iso_fortran_env, only: real64
|
||||
implicit none
|
||||
|
||||
abstract interface
|
||||
! a derivative dy/dt as function of y and t
|
||||
function derivative(y, t)
|
||||
use iso_fortran_env, only: real64
|
||||
real(real64) :: derivative
|
||||
real(real64), intent(in) :: t, y
|
||||
end function
|
||||
end interface
|
||||
|
||||
real(real64), parameter :: T_0 = 100, T_room = 20, k = 0.07, a = 0, b = 100, &
|
||||
h(3) = [2.0, 5.0, 10.0]
|
||||
|
||||
integer :: i
|
||||
|
||||
! loop over all step sizes
|
||||
do i = 1, 3
|
||||
call euler(newton_cooling, T_0, a, b, h(i))
|
||||
end do
|
||||
|
||||
contains
|
||||
|
||||
! Approximates y(t) in y'(t) = f(y, t) with y(a) = y0 and t = a..b and the
|
||||
! step size h.
|
||||
subroutine euler(f, y0, a, b, h)
|
||||
procedure(derivative) :: f
|
||||
real(real64), intent(in) :: y0, a, b, h
|
||||
real(real64) :: t, y
|
||||
|
||||
if (a > b) return
|
||||
if (h <= 0) stop "negative step size"
|
||||
|
||||
print '("# h = ", F0.3)', h
|
||||
|
||||
y = y0
|
||||
t = a
|
||||
|
||||
do
|
||||
print *, t, y
|
||||
t = t + h
|
||||
if (t > b) return
|
||||
y = y + h * f(y, t)
|
||||
end do
|
||||
end subroutine
|
||||
|
||||
|
||||
! Example: Newton's cooling law, f(T, _) = -k*(T - T_room)
|
||||
function newton_cooling(T, unused) result(dTdt)
|
||||
real(real64) :: dTdt
|
||||
real(real64), intent(in) :: T, unused
|
||||
dTdt = -k * (T - T_room)
|
||||
end function
|
||||
|
||||
end program
|
||||
24
Task/Euler-method/FreeBASIC/euler-method.basic
Normal file
24
Task/Euler-method/FreeBASIC/euler-method.basic
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
'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
|
||||
15
Task/Euler-method/Futhark/euler-method.futhark
Normal file
15
Task/Euler-method/Futhark/euler-method.futhark
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
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
|
||||
68
Task/Euler-method/Go/euler-method.go
Normal file
68
Task/Euler-method/Go/euler-method.go
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// fdy is a type for function f used in Euler's method.
|
||||
type fdy func(float64, float64) float64
|
||||
|
||||
// eulerStep 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.
|
||||
func eulerStep(f fdy, x, y, h float64) float64 {
|
||||
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.
|
||||
|
||||
// newCoolingRate returns a function that computes cooling rate
|
||||
// for a given cooling rate constant k.
|
||||
func newCoolingRate(k float64) func(float64) float64 {
|
||||
return func(deltaTemp float64) float64 {
|
||||
return -k * deltaTemp
|
||||
}
|
||||
}
|
||||
|
||||
// newTempFunc returns a function that computes the analytical solution
|
||||
// of cooling rate integrated over time.
|
||||
func newTempFunc(k, ambientTemp, initialTemp float64) func(float64) float64 {
|
||||
return func(time float64) float64 {
|
||||
return ambientTemp + (initialTemp-ambientTemp)*math.Exp(-k*time)
|
||||
}
|
||||
}
|
||||
|
||||
// newCoolingRateDy returns a function of the kind needed for Euler's method.
|
||||
// That is, a function representing dy(x, y(x)).
|
||||
//
|
||||
// Parameters to newCoolingRateDy are cooling constant k and ambient
|
||||
// temperature.
|
||||
func newCoolingRateDy(k, ambientTemp float64) fdy {
|
||||
crf := newCoolingRate(k)
|
||||
// note that result is dependent only on the object temperature.
|
||||
// there are no additional dependencies on time, so the x parameter
|
||||
// provided by eulerStep is unused.
|
||||
return func(_, objectTemp float64) float64 {
|
||||
return crf(objectTemp - ambientTemp)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
k := .07
|
||||
tempRoom := 20.
|
||||
tempObject := 100.
|
||||
fcr := newCoolingRateDy(k, tempRoom)
|
||||
analytic := newTempFunc(k, tempRoom, tempObject)
|
||||
for _, deltaTime := range []float64{2, 5, 10} {
|
||||
fmt.Printf("Step size = %.1f\n", deltaTime)
|
||||
fmt.Println(" Time Euler's Analytic")
|
||||
temp := tempObject
|
||||
for time := 0.; time <= 100; time += deltaTime {
|
||||
fmt.Printf("%5.1f %7.3f %7.3f\n", time, temp, analytic(time))
|
||||
temp = eulerStep(fcr, time, temp, deltaTime)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
15
Task/Euler-method/Groovy/euler-method-1.groovy
Normal file
15
Task/Euler-method/Groovy/euler-method-1.groovy
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
def eulerStep = { xn, yn, h, dydx ->
|
||||
(yn + h * dydx(xn, yn)) as BigDecimal
|
||||
}
|
||||
|
||||
Map eulerMapping = { x0, y0, h, dydx, stopCond = { xx, yy, hh, xx0 -> abs(xx - xx0) > (hh * 100) }.rcurry(h, x0) ->
|
||||
Map yMap = [:]
|
||||
yMap[x0] = y0 as BigDecimal
|
||||
def x = x0
|
||||
while (!stopCond(x, yMap[x])) {
|
||||
yMap[x + h] = eulerStep(x, yMap[x], h, dydx)
|
||||
x += h
|
||||
}
|
||||
yMap
|
||||
}
|
||||
assert eulerMapping.maximumNumberOfParameters == 5
|
||||
8
Task/Euler-method/Groovy/euler-method-2.groovy
Normal file
8
Task/Euler-method/Groovy/euler-method-2.groovy
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
def dtdsNewton = { s, t, tR, k -> k * (tR - t) }
|
||||
assert dtdsNewton.maximumNumberOfParameters == 4
|
||||
|
||||
def dtds = dtdsNewton.rcurry(20, 0.07)
|
||||
assert dtds.maximumNumberOfParameters == 2
|
||||
|
||||
def tEulerH = eulerMapping.rcurry(dtds) { s, t -> s >= 100 }
|
||||
assert tEulerH.maximumNumberOfParameters == 3
|
||||
7
Task/Euler-method/Groovy/euler-method-3.groovy
Normal file
7
Task/Euler-method/Groovy/euler-method-3.groovy
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
def tNewton = { s, s0, t0, tR, k ->
|
||||
tR + (t0 - tR) * Math.exp(k * (s0 - s))
|
||||
}
|
||||
assert tNewton.maximumNumberOfParameters == 5
|
||||
|
||||
def tAnalytic = tNewton.rcurry(0, 100, 20, 0.07)
|
||||
assert tAnalytic.maximumNumberOfParameters == 1
|
||||
14
Task/Euler-method/Groovy/euler-method-4.groovy
Normal file
14
Task/Euler-method/Groovy/euler-method-4.groovy
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[10, 5, 2].each { h ->
|
||||
def tEuler = tEulerH.rcurry(h)
|
||||
assert tEuler.maximumNumberOfParameters == 2
|
||||
println """
|
||||
STEP SIZE == ${h}
|
||||
time analytic euler relative
|
||||
(seconds) (°C) (°C) error
|
||||
-------- -------- -------- ---------"""
|
||||
tEuler(0, 100).each { BigDecimal s, tE ->
|
||||
def tA = tAnalytic(s)
|
||||
def relError = ((tE - tA)/(tA - 20)).abs()
|
||||
printf('%5.0f %8.4f %8.4f %9.6f\n', s, tA, tE, relError)
|
||||
}
|
||||
}
|
||||
5
Task/Euler-method/Haskell/euler-method-1.hs
Normal file
5
Task/Euler-method/Haskell/euler-method-1.hs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
-- 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)
|
||||
14
Task/Euler-method/Haskell/euler-method-2.hs
Normal file
14
Task/Euler-method/Haskell/euler-method-2.hs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
-- 1-st order Euler
|
||||
euler f x (t1,t2) = x + (t2 - t1) * f t1 x
|
||||
|
||||
-- 2-nd order Runge-Kutta
|
||||
rk2 f x (t1,t2) = x + h * f (t1 + h/2) (x + h/2*f t1 x)
|
||||
where h = t2 - t1
|
||||
|
||||
-- 4-th order Runge-Kutta
|
||||
rk4 f x (t1,t2) = x + h/6 * (k1 + 2*k2 + 2*k3 + k4)
|
||||
where k1 = f t1 x
|
||||
k2 = f (t1 + h/2) (x + h/2*k1)
|
||||
k3 = f (t1 + h/2) (x + h/2*k2)
|
||||
k4 = f (t1 + h) (x + h*k3)
|
||||
h = t2 - t1
|
||||
23
Task/Euler-method/Haskell/euler-method-3.hs
Normal file
23
Task/Euler-method/Haskell/euler-method-3.hs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import Graphics.EasyPlot
|
||||
|
||||
newton t temp = -0.07 * (temp - 20)
|
||||
|
||||
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
|
||||
22
Task/Euler-method/Icon/euler-method.icon
Normal file
22
Task/Euler-method/Icon/euler-method.icon
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
invocable "newton_cooling" # needed to use the 'proc' procedure
|
||||
|
||||
procedure euler (f, y0, a, b, h)
|
||||
t := a
|
||||
y := y0
|
||||
until (t >= b) do {
|
||||
write (right(t, 4) || " " || left(y, 7))
|
||||
t +:= h
|
||||
y +:= h * (proc(f) (t, y)) # 'proc' applies procedure named in f to (t, y)
|
||||
}
|
||||
write ("DONE")
|
||||
end
|
||||
|
||||
procedure newton_cooling (time, T)
|
||||
return -0.07 * (T - 20)
|
||||
end
|
||||
|
||||
procedure main ()
|
||||
# generate data for all three step sizes [2, 5, 10]
|
||||
every (step_size := ![2,5,10]) do
|
||||
euler ("newton_cooling", 100, 0, 100, step_size)
|
||||
end
|
||||
9
Task/Euler-method/J/euler-method-1.j
Normal file
9
Task/Euler-method/J/euler-method-1.j
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
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
|
||||
t=. i.@>:&.(%&h) b - a
|
||||
Y=. (+ h * u)^:(<#t) Y0
|
||||
t,.Y
|
||||
)
|
||||
|
||||
ncl=: _0.07 * -&20 NB. Newton's Cooling Law
|
||||
16
Task/Euler-method/J/euler-method-2.j
Normal file
16
Task/Euler-method/J/euler-method-2.j
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
ncl euler 100 0 100 2
|
||||
... NB. output redacted for brevity
|
||||
ncl euler 100 0 100 5
|
||||
... NB. output redacted for brevity
|
||||
ncl euler 100 0 100 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
|
||||
33
Task/Euler-method/Java/euler-method.java
Normal file
33
Task/Euler-method/Java/euler-method.java
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
public class Euler {
|
||||
private static void euler (Callable f, double y0, int a, int b, int h) {
|
||||
int t = a;
|
||||
double y = y0;
|
||||
while (t < b) {
|
||||
System.out.println ("" + t + " " + y);
|
||||
t += h;
|
||||
y += h * f.compute (t, y);
|
||||
}
|
||||
System.out.println ("DONE");
|
||||
}
|
||||
|
||||
public static void main (String[] args) {
|
||||
Callable cooling = new Cooling ();
|
||||
int[] steps = {2, 5, 10};
|
||||
for (int stepSize : steps) {
|
||||
System.out.println ("Step size: " + stepSize);
|
||||
euler (cooling, 100.0, 0, 100, stepSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// interface used so we can plug in alternative functions to Euler
|
||||
interface Callable {
|
||||
public double compute (int time, double t);
|
||||
}
|
||||
|
||||
// class to implement the newton cooling equation
|
||||
class Cooling implements Callable {
|
||||
public double compute (int time, double t) {
|
||||
return -0.07 * (t - 20);
|
||||
}
|
||||
}
|
||||
29
Task/Euler-method/JavaScript/euler-method.js
Normal file
29
Task/Euler-method/JavaScript/euler-method.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// 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);
|
||||
24
Task/Euler-method/Jq/euler-method-1.jq
Normal file
24
Task/Euler-method/Jq/euler-method-1.jq
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# 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; .) ] ]
|
||||
10
Task/Euler-method/Jq/euler-method-2.jq
Normal file
10
Task/Euler-method/Jq/euler-method-2.jq
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
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] ;
|
||||
1
Task/Euler-method/Jq/euler-method-3.jq
Normal file
1
Task/Euler-method/Jq/euler-method-3.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
(1,2,5,10,20) | [., [ euler_solution(cooling; 0; 100; 100; .) ] ]
|
||||
6
Task/Euler-method/Jq/euler-method-4.jq
Normal file
6
Task/Euler-method/Jq/euler-method-4.jq
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
$ jq -M -n -c -f Euler_method.jq
|
||||
[1,[20.05641373347389]]
|
||||
[2,[20.0424631833732]]
|
||||
[5,[20.01449963666907]]
|
||||
[10,[20.000472392]]
|
||||
[20,[19.180799999999998]]
|
||||
16
Task/Euler-method/Julia/euler-method.julia
Normal file
16
Task/Euler-method/Julia/euler-method.julia
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
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
|
||||
32
Task/Euler-method/Kotlin/euler-method.kotlin
Normal file
32
Task/Euler-method/Kotlin/euler-method.kotlin
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// 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)
|
||||
}
|
||||
27
Task/Euler-method/Lambdatalk/euler-method.lambdatalk
Normal file
27
Task/Euler-method/Lambdatalk/euler-method.lambdatalk
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{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
|
||||
22
Task/Euler-method/Lua/euler-method.lua
Normal file
22
Task/Euler-method/Lua/euler-method.lua
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
T0 = 100
|
||||
TR = 20
|
||||
k = 0.07
|
||||
delta_t = { 2, 5, 10 }
|
||||
n = 100
|
||||
|
||||
NewtonCooling = function( t ) return -k * ( t - TR ) end
|
||||
|
||||
|
||||
function Euler( f, y0, n, h )
|
||||
local y = y0
|
||||
for x = 0, n, h do
|
||||
print( "", x, y )
|
||||
y = y + h * f( y )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
for i = 1, #delta_t do
|
||||
print( "delta_t = ", delta_t[i] )
|
||||
Euler( NewtonCooling, T0, n, delta_t[i] )
|
||||
end
|
||||
6
Task/Euler-method/Maple/euler-method-1.maple
Normal file
6
Task/Euler-method/Maple/euler-method-1.maple
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
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
|
||||
26
Task/Euler-method/Maple/euler-method-2.maple
Normal file
26
Task/Euler-method/Maple/euler-method-2.maple
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
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);
|
||||
6
Task/Euler-method/Mathematica/euler-method.math
Normal file
6
Task/Euler-method/Mathematica/euler-method.math
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
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]
|
||||
38
Task/Euler-method/Maxima/euler-method.maxima
Normal file
38
Task/Euler-method/Maxima/euler-method.maxima
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
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"]);
|
||||
13
Task/Euler-method/Nim/euler-method.nim
Normal file
13
Task/Euler-method/Nim/euler-method.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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)
|
||||
10
Task/Euler-method/OCaml/euler-method-1.ocaml
Normal file
10
Task/Euler-method/OCaml/euler-method-1.ocaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
(* 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)
|
||||
24
Task/Euler-method/OCaml/euler-method-2.ocaml
Normal file
24
Task/Euler-method/OCaml/euler-method-2.ocaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
(* 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.)
|
||||
32
Task/Euler-method/Objeck/euler-method.objeck
Normal file
32
Task/Euler-method/Objeck/euler-method.objeck
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
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);
|
||||
};
|
||||
}
|
||||
}
|
||||
57
Task/Euler-method/ObjectIcon/euler-method.oi
Normal file
57
Task/Euler-method/ObjectIcon/euler-method.oi
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
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
|
||||
6
Task/Euler-method/Oforth/euler-method-1.fth
Normal file
6
Task/Euler-method/Oforth/euler-method-1.fth
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
: 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
|
||||
] ;
|
||||
7
Task/Euler-method/Oforth/euler-method-2.fth
Normal file
7
Task/Euler-method/Oforth/euler-method-2.fth
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
: 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) ;
|
||||
58
Task/Euler-method/Ol/euler-method.ol
Normal file
58
Task/Euler-method/Ol/euler-method.ol
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
(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)
|
||||
44
Task/Euler-method/PL-I/euler-method.pli
Normal file
44
Task/Euler-method/PL-I/euler-method.pli
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
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;
|
||||
49
Task/Euler-method/Pascal/euler-method.pas
Normal file
49
Task/Euler-method/Pascal/euler-method.pas
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{$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.
|
||||
32
Task/Euler-method/Perl/euler-method.pl
Normal file
32
Task/Euler-method/Perl/euler-method.pl
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
sub euler_method {
|
||||
my ($t0, $t1, $k, $step_size) = @_;
|
||||
my @results = ( [0, $t0] );
|
||||
|
||||
for (my $s = $step_size; $s <= 100; $s += $step_size) {
|
||||
$t0 -= ($t0 - $t1) * $k * $step_size;
|
||||
push @results, [$s, $t0];
|
||||
}
|
||||
|
||||
return @results;
|
||||
}
|
||||
|
||||
sub analytical {
|
||||
my ($t0, $t1, $k, $time) = @_;
|
||||
return ($t0 - $t1) * exp(-$time * $k) + $t1
|
||||
}
|
||||
|
||||
my ($T0, $T1, $k) = (100, 20, .07);
|
||||
my @r2 = grep { $_->[0] % 10 == 0 } euler_method($T0, $T1, $k, 2);
|
||||
my @r5 = grep { $_->[0] % 10 == 0 } euler_method($T0, $T1, $k, 5);
|
||||
my @r10 = grep { $_->[0] % 10 == 0 } euler_method($T0, $T1, $k, 10);
|
||||
|
||||
print "Time\t 2 err(%) 5 err(%) 10 err(%) Analytic\n", "-" x 76, "\n";
|
||||
for (0 .. $#r2) {
|
||||
my $an = analytical($T0, $T1, $k, $r2[$_][0]);
|
||||
printf "%4d\t".("%9.3f" x 7)."\n",
|
||||
$r2 [$_][0],
|
||||
$r2 [$_][1], ($r2 [$_][1] / $an) * 100 - 100,
|
||||
$r5 [$_][1], ($r5 [$_][1] / $an) * 100 - 100,
|
||||
$r10[$_][1], ($r10[$_][1] / $an) * 100 - 100,
|
||||
$an;
|
||||
}
|
||||
57
Task/Euler-method/Phix/euler-method.phix
Normal file
57
Task/Euler-method/Phix/euler-method.phix
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- demo\rosetta\Euler_method.exw
|
||||
-- =============================
|
||||
--</span>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- and a simple plot</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #7060A8;">IupGraph</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<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>
|
||||
<!--
|
||||
14
Task/Euler-method/PicoLisp/euler-method.l
Normal file
14
Task/Euler-method/PicoLisp/euler-method.l
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
(load "@lib/math.l")
|
||||
|
||||
(de euler (F Y A B H)
|
||||
(while (> B A)
|
||||
(prinl (round A) " " (round Y))
|
||||
(inc 'Y (*/ H (F A Y) 1.0))
|
||||
(inc 'A H) ) )
|
||||
|
||||
(de newtonCoolingLaw (A B)
|
||||
(*/ -0.07 (- B 20.) 1.0) )
|
||||
|
||||
(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)
|
||||
43
Task/Euler-method/PowerShell/euler-method.psh
Normal file
43
Task/Euler-method/PowerShell/euler-method.psh
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
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
|
||||
25
Task/Euler-method/PureBasic/euler-method.basic
Normal file
25
Task/Euler-method/PureBasic/euler-method.basic
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Define.d
|
||||
Prototype.d Func(Time, t)
|
||||
|
||||
Procedure.d Euler(*F.Func, y0, a, b, h)
|
||||
Protected y=y0, t=a
|
||||
While t<=b
|
||||
PrintN(RSet(StrF(t,3),7)+" "+RSet(StrF(y,3),7))
|
||||
y + h * *F(t,y)
|
||||
t + h
|
||||
Wend
|
||||
EndProcedure
|
||||
|
||||
Procedure.d newtonCoolingLaw(Time, t)
|
||||
ProcedureReturn -0.07*(t-20)
|
||||
EndProcedure
|
||||
|
||||
|
||||
If OpenConsole()
|
||||
Euler(@newtonCoolingLaw(), 100, 0, 100, 2)
|
||||
Euler(@newtonCoolingLaw(), 100, 0, 100, 5)
|
||||
Euler(@newtonCoolingLaw(), 100, 0, 100,10)
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
11
Task/Euler-method/Python/euler-method.py
Normal file
11
Task/Euler-method/Python/euler-method.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
def euler(f,y0,a,b,h):
|
||||
t,y = a,y0
|
||||
while t <= b:
|
||||
print "%6.3f %6.3f" % (t,y)
|
||||
t += h
|
||||
y += h * f(t,y)
|
||||
|
||||
def newtoncooling(time, temp):
|
||||
return -0.07 * (temp - 20)
|
||||
|
||||
euler(newtoncooling,100,0,100,10)
|
||||
18
Task/Euler-method/R/euler-method.r
Normal file
18
Task/Euler-method/R/euler-method.r
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
euler <- function(f, y0, a, b, h)
|
||||
{
|
||||
t <- a
|
||||
y <- y0
|
||||
|
||||
while (t < b)
|
||||
{
|
||||
cat(sprintf("%6.3f %6.3f\n", t, y))
|
||||
t <- t + h
|
||||
y <- y + h*f(t, y)
|
||||
}
|
||||
}
|
||||
|
||||
newtoncooling <- function(time, temp){
|
||||
return(-0.07*(temp-20))
|
||||
}
|
||||
|
||||
euler(newtoncooling, 100, 0, 100, 10)
|
||||
72
Task/Euler-method/REXX/euler-method-1.rexx
Normal file
72
Task/Euler-method/REXX/euler-method-1.rexx
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/* 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
|
||||
25
Task/Euler-method/REXX/euler-method-2.rexx
Normal file
25
Task/Euler-method/REXX/euler-method-2.rexx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*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
|
||||
6
Task/Euler-method/Racket/euler-method-1.rkt
Normal file
6
Task/Euler-method/Racket/euler-method-1.rkt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
(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)))
|
||||
2
Task/Euler-method/Racket/euler-method-2.rkt
Normal file
2
Task/Euler-method/Racket/euler-method-2.rkt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
(define (euler F h)
|
||||
(λ (x y) (list (+ x h) (+ y (* h (F x y))))))
|
||||
6
Task/Euler-method/Racket/euler-method-3.rkt
Normal file
6
Task/Euler-method/Racket/euler-method-3.rkt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
(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)))
|
||||
14
Task/Euler-method/Racket/euler-method-4.rkt
Normal file
14
Task/Euler-method/Racket/euler-method-4.rkt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
> (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))
|
||||
9
Task/Euler-method/Racket/euler-method-5.rkt
Normal file
9
Task/Euler-method/Racket/euler-method-5.rkt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
> (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)
|
||||
4
Task/Euler-method/Racket/euler-method-6.rkt
Normal file
4
Task/Euler-method/Racket/euler-method-6.rkt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
(define (RK2 F h)
|
||||
(λ (x y)
|
||||
(list (+ x h) (+ y (* h (F (+ x (* 1/2 h))
|
||||
(+ y (* 1/2 h (F x y)))))))))
|
||||
7
Task/Euler-method/Racket/euler-method-7.rkt
Normal file
7
Task/Euler-method/Racket/euler-method-7.rkt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
(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))]))
|
||||
10
Task/Euler-method/Racket/euler-method-8.rkt
Normal file
10
Task/Euler-method/Racket/euler-method-8.rkt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
(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′)))]))
|
||||
18
Task/Euler-method/Racket/euler-method-9.rkt
Normal file
18
Task/Euler-method/Racket/euler-method-9.rkt
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
> (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)
|
||||
37
Task/Euler-method/Raku/euler-method.raku
Normal file
37
Task/Euler-method/Raku/euler-method.raku
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
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%%');
|
||||
}
|
||||
13
Task/Euler-method/Ring/euler-method.ring
Normal file
13
Task/Euler-method/Ring/euler-method.ring
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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
|
||||
12
Task/Euler-method/Ruby/euler-method.rb
Normal file
12
Task/Euler-method/Ruby/euler-method.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
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
|
||||
14
Task/Euler-method/Run-BASIC/euler-method.basic
Normal file
14
Task/Euler-method/Run-BASIC/euler-method.basic
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
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
|
||||
34
Task/Euler-method/Rust/euler-method.rust
Normal file
34
Task/Euler-method/Rust/euler-method.rust
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
29
Task/Euler-method/Scala/euler-method.scala
Normal file
29
Task/Euler-method/Scala/euler-method.scala
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
object App{
|
||||
|
||||
def main(args : Array[String]) = {
|
||||
|
||||
def cooling( step : Int ) = {
|
||||
eulerStep( (step , y) => {-0.07 * (y - 20)} ,
|
||||
100.0,0,100,step)
|
||||
}
|
||||
cooling(10)
|
||||
cooling(5)
|
||||
cooling(2)
|
||||
}
|
||||
def eulerStep( func : (Int,Double) => Double,y0 : Double,
|
||||
begin : Int, end : Int , step : Int) = {
|
||||
|
||||
println("Step size: %s".format(step))
|
||||
|
||||
var current : Int = begin
|
||||
var y : Double = y0
|
||||
while( current <= end){
|
||||
println( "%d %.5f".format(current,y))
|
||||
current += step
|
||||
y += step * func(current,y)
|
||||
}
|
||||
|
||||
println("DONE")
|
||||
}
|
||||
|
||||
}
|
||||
25
Task/Euler-method/SequenceL/euler-method.sequencel
Normal file
25
Task/Euler-method/SequenceL/euler-method.sequencel
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
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);
|
||||
30
Task/Euler-method/Sidef/euler-method.sidef
Normal file
30
Task/Euler-method/Sidef/euler-method.sidef
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
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)
|
||||
}
|
||||
13
Task/Euler-method/Smalltalk/euler-method.st
Normal file
13
Task/Euler-method/Smalltalk/euler-method.st
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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
|
||||
53
Task/Euler-method/Standard-ML/euler-method.ml
Normal file
53
Task/Euler-method/Standard-ML/euler-method.ml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
(* 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");
|
||||
42
Task/Euler-method/Swift/euler-method.swift
Normal file
42
Task/Euler-method/Swift/euler-method.swift
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
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)
|
||||
9
Task/Euler-method/Tcl/euler-method-1.tcl
Normal file
9
Task/Euler-method/Tcl/euler-method-1.tcl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
proc euler {f y0 a b h} {
|
||||
puts "computing $f over \[$a..$b\], step $h"
|
||||
set y [expr {double($y0)}]
|
||||
for {set t [expr {double($a)}]} {$t < $b} {set t [expr {$t + $h}]} {
|
||||
puts [format "%.3f\t%.3f" $t $y]
|
||||
set y [expr {$y + $h * double([$f $t $y])}]
|
||||
}
|
||||
puts "done"
|
||||
}
|
||||
7
Task/Euler-method/Tcl/euler-method-2.tcl
Normal file
7
Task/Euler-method/Tcl/euler-method-2.tcl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
proc newtonCoolingLaw {time temp} {
|
||||
expr {-0.07 * ($temp - 20)}
|
||||
}
|
||||
|
||||
euler newtonCoolingLaw 100 0 100 2
|
||||
euler newtonCoolingLaw 100 0 100 5
|
||||
euler newtonCoolingLaw 100 0 100 10
|
||||
61
Task/Euler-method/V-(Vlang)/euler-method.v
Normal file
61
Task/Euler-method/V-(Vlang)/euler-method.v
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
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('')
|
||||
}
|
||||
}
|
||||
36
Task/Euler-method/VBA/euler-method.vba
Normal file
36
Task/Euler-method/VBA/euler-method.vba
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
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
|
||||
25
Task/Euler-method/Wren/euler-method.wren
Normal file
25
Task/Euler-method/Wren/euler-method.wren
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
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)
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue