September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View 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

View file

@ -1,16 +1,14 @@
import "futlib/math"
fun analytic(t0: f64) (time: f64): f64 =
let analytic(t0: f64) (time: f64): f64 =
20.0 + (t0 - 20.0) * f64.exp(-0.07*time)
fun cooling(_time: f64) (temperature: f64): f64 =
let cooling(_time: f64) (temperature: f64): f64 =
-0.07 * (temperature-20.0)
fun main(t0: f64) (a: f64) (b: f64) (h: f64): []f64 =
let steps = i32((b-a)/h)
let main(t0: f64) (a: f64) (b: f64) (h: f64): []f64 =
let steps = i32.f64 ((b-a)/h)
let temps = replicate steps 0.0
loop ((t,temps)=(t0,temps)) = for i < steps do
let x = a + f64(i) * h
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)

View file

@ -1,26 +1,25 @@
/*REXX pgm solves example of Newton's cooling law via Euler's method (diff. step sizes).*/
numeric digits length( e() - 1) /*use the number of decimal digits in E*/
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. */
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,9) /*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 /*stepSize*/
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. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
e: return 2.718281828459045235360287471352662497757247093699959574966967627724076630353548
/*──────────────────────────────────────────────────────────────────────────────────────*/
exp: procedure; parse 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
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

View 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);
}
}

View 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