Overview
-'DIFF' is a directory ( binary file / #55319d / 9713.5
bytes ) that works with an HP48S/SX/G/GX
( In most of the routines, the << >> have been
deleted to save bytes ).
-However, the programs in the 'RkF' subdirectory doesn't work with an HP48S/SX
-'DIFF50' is an ascii file ( #47108d / 9848 bytes ) with the same programs that should be transfered to an HP50G too.
-These functions may solve any differential equation or system of differential
equations ( provided it's not too large ).
-They are also applied to solve the gravitational n-body problem in
an inertial frame of reference.
-However, the effects of general relativity are neglected.
Functions | Description |
RK4
RK8 RK10 GM rk4 rk8 rk10 N h GM G M1, M2 ... RKV8E9 RkF X Y F TOL rkf GM2 T Y TOL G GM rkf M1, M2 InFo IRK12 IRK13 |
Runge-Kutta "classical" 4th order formula
Runge-Kutta 8th order formula Runge-Kutta 10th order formula Directory ( gravitational n-body problem ) Runge-Kutta 4th order formula Runge-Kutta 8th order formula Runge-Kutta 10th order formula Number of steps Stepsize expressed in days Main subroutine ( Gaussian gravit. contant )^2 = ( 0.01720209895 )^2 Mass of the 1st celestial body, 2nd body , ... Runge-Kutta-Verner 8-9 method ( with error estimate ) Directory ( doesn't work with an HP48S/SX ) Independant Variable Y = [ Y1 .... Yn ] = n-vector A program that computes dY/dX = [ Y1' .... Yn' ] Tolerance = small positive number Uses the built-in Runge-Kutta-Fehlberg 4-5 function Subdirectory ( gravitational n-body problem by RKF ) Time Vector [ X1 Y1 Z1 ... Xn Yn Zn X'1 Y'1 Z'1 ... X'n Y'n Z'n ] Tolerance ( Gaussian gravit. Contant )^2 = ( 0.01720209895 )^2 Main subroutine Uses the built-in Runge-Kutta-Fehlberg 4-5 function Mass of the 1st celestial body, 2nd body , ... Info Implicit Runge-Kutta method of order 12 Implicit Runge-Kutta method of order 13 |
Runge-Kutta "classical" 4th order formula
RK4 uses the following formulae:
k1 = h.f(x;y)
k2 = h.f(x+h/2;y+k1/2)
k3 = h.f(x+h/2;y+k2/2)
k4 = h.f(x+h;y+k3)
and then, y(x+h) = y(x) + ( k1 + 2.k2 + 2.k3 + k4 ) / 6
-This formula duplicates the Taylor series up to the term in h4
-In order to save bytes, the equations are written dY/dX = f(Y)
with Y = [ X Y1 , ......... , Yn ]
STACK | INPUTS | OUTPUTS |
Level 4 | << f >> | << f >> |
Level 3 | h | h |
Level 2 | N | N |
Level 1 | [ x y1 ... yn ] | [ x y1 ... yn ]* |
where
<< f >> is a program ( or its name )
that computes the derivative of the (n+1)-vector [ x y1
... yn ] Since dx/dx = 1 the first component is
always 1
h = stepsize
N = number of steps
[ x y1 ... yn ] = initial value
and [ x y1 ... yn ]* is the result with
x* = x + N.h
Example1: y(0) = 1 and dy/dx = 2 x.y Evaluate y(1) ( The exact solution is y = exp ( x2 ) )
-With h = 0.1 & N = 10
<< OBJ-> DROP * 2 *
1 SWAP 2 ->ARRY >> ENTER
.1
ENTER
10
ENTER
[ 0 1 ]
RK4
gives [ 1 2.71827017536
]
-So, y(1) = 2.71827017536
-The exact value is exp(1) = 2.71828182846 rounded
to 12D
-Press RK4 again to get y(2) ... and so on ...
Example2:
dy/dx = -yzu
y(0)=1
dz/dx = x(y+z-u)
z(0)=1
du/dx = xy-zu
u(0)=2
-Evaluate y(1) , z(1) , u(1) with h = 0.1 , N = 10:
<< OBJ-> DROP -> X Y Z U
<< 1 Y Z U * * NEG
Y Z + U - X *
X Y * Z U * - 4 ->ARRY
>>
>>
ENTER
0.1
ENTER
10
ENTER
[ 0 1 1 2 ] RK4
yields [ 1
0.258209385512 1.15761955337 0.842178650981
]
-Press RK4 again to get y(2) z(2) u(2) .....
Notes:
-Since there is no error estimate, the calculations must be performed
with a smaller stepsize, for instance h = 0.05
-To solve, say a 2nd order differential equation like y" = f( x , y
, y' ), replace it by the system
dy/dx = z
dz/dx = f( x , y , z )
-RK8 employs an 8th-order formula that is given in reference [4]
-It duplicates the Taylor series up to the term in h8
-11 evaluations of the function are required at each step.
-RK8 & RK4 are used in the same way.
STACK | INPUTS | OUTPUTS |
Level 4 | << f >> | << f >> |
Level 3 | h | h |
Level 2 | N | N |
Level 1 | [ x y1 ... yn ] | [ x y1 ... yn ]* |
where
<< f >> is a program ( or its name )
that computes the derivative of the (n+1)-vector [ x y1
... yn ] Since dx/dx = 1 the first component is
always 1
h = stepsize
N = number of steps
[ x y1 ... yn ] = initial value
and [ x y1 ... yn ]* is the result with
x* = x + N.h
Example1: y(0) = 1 and dy/dx = 2 x.y Evaluate y(1) ( The exact solution is y = exp ( x2 ) )
-With h = 0.1 & N = 10
<< OBJ-> DROP * 2 *
1 SWAP 2 ->ARRY >> ENTER
.1
ENTER
10
ENTER
[ 0 1 ]
RK8
gives [ 1 2.7182818285
]
-Press RK8 again to get y(2) ... and so on ...
Example2:
dy/dx = -yzu
y(0)=1
dz/dx = x(y+z-u)
z(0)=1
du/dx = xy-zu
u(0)=2
-Evaluate y(1) , z(1) , u(1) with h = 0.1 , N = 10:
<< OBJ-> DROP -> X Y Z U
<< 1 Y Z U * * NEG
Y Z + U - X *
X Y * Z U * - 4 ->ARRY
>>
>>
ENTER
0.1
ENTER
10
ENTER
[ 0 1 1 2 ] RK8
yields [ 1
0.258207906459 1.1576239808 0.842178311686
]
-Press RK8 again to get y(2) z(2) u(2) .....
Note:
-Since there is no error estimate, the calculations must be performed
with a smaller stepsize, for instance h = 0.05
Runge-Kutta 10th order formula
-RK10 duplicates the Taylor series up to the term in h10
-17 evaluations of the function are required at each step.
-RK10 , RK8 & RK4 are used in the same way.
STACK | INPUTS | OUTPUTS |
Level 4 | << f >> | << f >> |
Level 3 | h | h |
Level 2 | N | N |
Level 1 | [ x y1 ... yn ] | [ x y1 ... yn ]* |
where
<< f >> is a program ( or its name )
that computes the derivative of the (n+1)-vector [ x y1
... yn ] Since dx/dx = 1 the first component is
always 1
h = stepsize
N = number of steps
[ x y1 ... yn ] = initial value
and [ x y1 ... yn ]* is the result with
x* = x + N.h
Example1: y(0) = 1 and dy/dx = 2 x.y Evaluate y(1) ( The exact solution is y = exp ( x2 ) )
-With h = 0.1 & N = 10
<< OBJ-> DROP * 2 *
1 SWAP 2 ->ARRY >> ENTER
.1
ENTER
10
ENTER
[ 0 1 ]
RK10
gives [ 1 2.71828182846
]
-Press RK10 again to get y(2) ... and so on ...
Example2:
dy/dx = -yzu
y(0)=1
dz/dx = x(y+z-u)
z(0)=1
du/dx = xy-zu
u(0)=2
-Evaluate y(1) , z(1) , u(1) with h = 0.1 , N = 10:
<< OBJ-> DROP -> X Y Z U
<< 1 Y Z U * * NEG
Y Z + U - X *
X Y * Z U * - 4 ->ARRY
>>
>>
ENTER
0.1
ENTER
10
ENTER
[ 0 1 1 2 ] RK10
yields [ 1
0.258207906453 1.15762398081 0.842178311706
]
-Press RK10 again to get y(2) z(2) u(2) .....
Notes:
-Since there is no error estimate, the calculations must be performed
with a smaller stepsize, for instance h = 0.05
-Of course,the execution time increases like the number of functions
in the system.
Runge-Kutta-Verner 8th order formula enbedded within 9th
order
-RKV8E9 employs an 8th order formula and a 9th order formula.
-The difference between these gives an error estimate of the 8th order
result
-This difference is stored in a variable 'ERROR'
-Always PURGE the variable 'ERROR' before the 1st execution.
-The successive "errors" are simply added to 'ERROR', so the estimation
of the error may be underestimated...
STACK | INPUTS | OUTPUTS |
Level 4 | << f >> | << f >> |
Level 3 | h | h |
Level 2 | N | N |
Level 1 | [ x y1 ... yn ] | [ x y1 ... yn ]* |
where
<< f >> is a program ( or its name )
that computes the derivative of the (n+1)-vector [ x y1
... yn ] Since dx/dx = 1 the first component is
always 1
h = stepsize
N = number of steps
[ x y1 ... yn ] = initial value
and [ x y1 ... yn ]* is the result with
x* = x + N.h
Example:
dy/dx = -yzu
y(0)=1
dz/dx = x(y+z-u)
z(0)=1
du/dx = xy-zu
u(0)=2
with h = 0.1 , N = 10:
*** PURGE 'ERROR' before the first execution.
<< OBJ-> DROP -> X Y Z U
<< 1 Y Z U * * NEG
Y Z + U - X *
X Y * Z U * - 4 ->ARRY
>>
>> ENTER
0.1 ENTER
10 ENTER
[ 0 1 1 2 ] and press RK8E9
-It returns in level 1 [ 1 0.258207906449 1.15762398084 0.842178311722 ]
and 'ERROR' contains [ 0 2.7631E-11 3.27392E-11 7.636E-11 ]
-Press RK8E9 again to continue ( after changing
h and/or N if need be )
Implicit Runge-Kutta formula of order 12
-IRK12 & IRK13 use implicit Runge-Kutta formulae:
-A n-stage implicit Runge-Kutta method is defined by n(n+2) coefficients ai,j ; bi ; ci
k1 = h.f ( x + b1h ; y + a1,1 k1
+ a1,2 k2 + ..... + a1,n kn
)
.....................................................................................
( actually, ai,1 + ai,2
+ .......... + ai,n = bi )
kn = h.f ( x + bnh ; y + an,1 k1
+ an,2 k2 + ..... + an,n kn
)
then: y(x+h) = y(x) + c1.k1+ ................ + cn.kn
-So, the calculator must solve a non-linear system at each step !
-It is solved by a simple successive approximation method which may
... not converge !
-Even if it does converge, the execution time makes IRK12 & IRK13
very slow.
-These 2 programs are given for completeness but I'm not sure they will
be very useful...
STACK | INPUTS | OUTPUTS |
Level 4 | << f >> | << f >> |
Level 3 | h | h |
Level 2 | N | N |
Level 1 | [ x y1 ... yn ] | [ x y1 ... yn ]* |
where
<< f >> is a program ( or its name )
that computes the derivative of the (n+1)-vector [ x y1
... yn ] Since dx/dx = 1 the first component is
always 1
h = stepsize
N = number of steps
[ x y1 ... yn ] = initial value
and [ x y1 ... yn ]* is the result with
x* = x + N.h
Example: y(0) = 1 and dy/dx = 2 x.y Evaluate y(1) ( The exact solution is y = exp ( x2 ) )
-With h = 0.1 & N = 10
<< OBJ-> DROP * 2 *
1 SWAP 2 ->ARRY >> ENTER
.1
ENTER
10
ENTER
[ 0 1 ]
IRK12
gives [ 1 2.71828182846
]
-Press IRK12 again to get y(2) ... and so on ...
Note:
-The HP48 displays successive values so that you can check if the process
converges or not.
Implicit Runge-Kutta formula of order 13
-Same remarks.
STACK | INPUTS | OUTPUTS |
Level 4 | << f >> | << f >> |
Level 3 | h | h |
Level 2 | N | N |
Level 1 | [ x y1 ... yn ] | [ x y1 ... yn ]* |
where
<< f >> is a program ( or its name )
that computes the derivative of the (n+1)-vector [ x y1
... yn ] Since dx/dx = 1 the first component is
always 1
h = stepsize
N = number of steps
[ x y1 ... yn ] = initial value
and [ x y1 ... yn ]* is the result with
x* = x + N.h
Example: y(0) = 1 and dy/dx = 2 x.y Evaluate y(1) ( The exact solution is y = exp ( x2 ) )
-With h = 0.1 & N = 10
<< OBJ-> DROP * 2 *
1 SWAP 2 ->ARRY >> ENTER
.1
ENTER
10
ENTER
[ 0 1 ]
IRK13
gives [ 1 2.71828182846
]
-Press IRK13 again to get y(2) ... and so on ...
Note:
-The HP48 displays successive values so that you can check if the process
converges or not.
-You can choose between 'rk4' 'rk8' 'rk10' ( which call 'RK4' 'RK8' 'RK10' and 'GM' ) to solve the gravitational n-body problem.
-Let M1( x1, y1,z1)
; ....... ; Mn( xn, yn,zn)
be n celestial bodies with initial velocities V1(
x'1, y'1,z'1) ; ....... ; Vn(
x'n, y'n,z'n) at an instant t
and m1 , ...... , mn
the n masses of these bodies.
-We want to know their future positions and velocities at an instant
t + N.h ( h = step size in days ; N = number of steps
)
-So, we have to solve the system of (6n+1) differential equations:
d2xi /dt2 = SUMj#i
Gmj ( xj - xi ) / [ ( xi -
xj )2+ ( yi - yj )2
+ ( zi - zj )2 ]3/2
d2yi /dt2 = SUMj#i
Gmj ( yj - yi ) / [ ( xi -
xj )2 + ( yi - yj )2
+ ( zi - zj )2 ]3/2
i , j = 1 , ..... , n
d2zi /dt2 = SUMj#i
Gmj ( zj - zi ) / [ ( xi -
xj )2 + ( yi - yj )2
+ ( zi - zj )2 ]3/2
where G is the gravitational constant: G = k2 where k = 0.01720209895 is Gaussian gravitational constant.
-The distances are to be expressed in Astronomical Units, the times in days and the masses in Solar mass.
1°) Store the n masses into 'M1' 'M2' .....
2°) Store the stepsize in 'h'
3°) Store the number of steps in 'N'
4°) Place in level 1 the (6n+1)-vector [ t x1, y1,z1 ............... xn, yn,zn , x'1, y'1,z'1 ............... x'n, y'n,z'n ]
and press 'rk4' or 'rk8' or 'rk10' , you'll get the new vector in level 1
5°) Press again 'rk4' or 'rk8' or
'rk10' to get the position & velocities at the instant
t + 2N h
STACK | INPUT | OUTPUT |
Level 1 | [ t x1, y1,z1 ............... xn, yn,zn , x'1, y'1,z'1 ............... x'n, y'n,z'n ] | [ t x1, y1,z1 ............... xn, yn,zn , x'1, y'1,z'1 ............... x'n, y'n,z'n ]* |
where [ t x1, y1,z1
............... xn, yn,zn , x'1,
y'1,z'1 ............... x'n, y'n,z'n
] is the initial vector
and [ t x1, y1,z1
............... xn, yn,zn , x'1,
y'1,z'1 ............... x'n, y'n,z'n
]* is the position-velocity vector at t + N.h
Example:
-Let's imagine a system of three stars
M1 ( 2 ; 0 ;0 ) M2
( 0 ; 4 ; 0 ) M3 ( 0 ; 0 ; 1 )
unit = 1 AU
with initial velocities
V1 ( 0 ; 0.03 ; 0 ) V2 ( 0 ; 0 ; 0.01
) V3 ( -0.02 ; 0 ; 0 )
unit = 1 AU per day
and masses
m1 = 2 ; m2 = 1 ; m3
= 3
unit = 1 Solar mass
-Calculate the positions and velocities 10 days later.
-Masses: 2 'M1' STO 1 'M2' STO 3 'M3' STO
-With N = 1 & h = 10 days 1 'N' STO 10 'h' STO and if you want to use 'rk4'
[ 0 2 0 0 0 4 0 0 0 1 0 0.03 0 0 0 0.01 -0.02 0 0 ] rk4 yields ( rounded to 9 decimals )
[ 10 1.992077551 0.300333856
0.003673779 0.000661665 3.996080593
0.100603408 -0.194938922 0.001083898
0.997349678
-0.001550089 0.030038159 0.000706688
0.000132598 -0.000790383 0.010117548
-0.019010806 0.000238022 -0.000510308
]
-With N = 2 & h = 5 days, the results are given in the last column
hereunder
- | coord | input | h = 10 ; N=1 | h = 5 ; N=2 |
p
|
x1
y1 z1 -------- x2 y2 z2 -------- x3 y3 z3 |
2
0 0 ----- 0 4 0 ----- 0 0 1 |
1.992077551
0.300333856 0.003673779 -------------- 0.000661665 3.996080593 0.100603408 -------------- -0.194938922 0.001083898 0.997349678 |
1.992077584
0.300333570 0.003673683 -------------- 0.000661669 3.996080575 0.100603412 -------------- -0.194938946 0.001084095 0.997349741 |
v
e l . |
x'1
y'1 z'1 -------- x'2 y'2 z'2 -------- x'3 y'3 z'3 |
0
0.03 0 ----- 0 0 0.01 ----- -0.02 0 0 |
-0.001550089
0.030038159 0.000706688 -------------- 0.000132598 -0.000790383 0.010117548 -------------- -0.019010806 0.000238022 -0.000510308 |
-0.001550083
0.030038158 0.000706684 -------------- 0.000132598 -0.000790384 0.010117549 -------------- -0.019010811 0.000238023 -0.000510306 |
Notes:
-Of course, 'rk8' & 'rk10' will produce more accurate results but
the execution time will be increased too.
-The directory contains 10 variables 'M1' 'M2' ..........
'M10'
-Add other 'Mk' if there are more than 10 celestial bodies.
Runge-Kutta-Fehlberg 4-5 formula
-Here, we use the built-in RKF function on the HP48G/GX, HP49G,
HP50G
-The usage is different from that of RK4 , RK8 ....
-Store the initial x-value in 'X' , the initial y-value in 'Y' , and
a program that computes dy/dx in 'F'
-Store a tolerance value in 'TOL'
-Place the new x-value in level 1 and press the 'rkf' key
-The y-result will be in level 1 ( and in 'Y' ) and the new x-value
will be in 'X'
STACK | INPUT | OUTPUT |
Level 1 | x | [ y1 ... yn ] |
where
x = new x-value
and [ y1 ...
yn ] = new y-value
Example1: y(0) = 1 and dy/dx = 2 x.y Evaluate y(1) with a tolerance 10^(-10)
-10 ALOG 'TOL' STO
or press the left shit key and TOL
0 'X' STO
............................
1 'Y' STO
<< X Y * 2 * >> ENTER 'F' STO
1 rkf gives 2.71828182955
-Press 2 rkf to get y(2) ... and so on ...
Example2: ( the required data are already stored in the DIFF file )
dy/dx = -yzu
y(0)=1
dz/dx = x(y+z-u)
z(0)=1
du/dx = xy-zu
u(0)=2
-Evaluate y(1) , z(1) , u(1) with the same tolerance
-10 ALOG 'TOL' STO
0
'X' STO
[ 1 1 2 ] 'Y' STO
<< Y OBJ-> DROP -> Y Z U
<< Y Z U * * NEG
Y Z + U - X *
X Y * Z U * - 3 ->ARRY
>> >>
ENTER
'F' STO
1 rkf yields [ 1 0.258207906452 1.15762398091 0.842178311783 ] in level1 and in 'Y' too.
-Press 2 rkf
to get y(2) z(2) u(2) .....
Gravitational n-body Problem Solved by the built-in function
RKF
-Here, we use the Runge-Kutta-Fehlberg 4-5 method on the HP48G/GX, HP49G, HP50G
-Store the initial t-value in 'T' , the initial Y-value = [ x1,
y1,z1 ............... xn, yn,zn
, x'1, y'1,z'1 ............... x'n,
y'n,z'n ] in 'Y'
-Store a tolerance value in 'TOL' and the n masses into
'M1' 'M2' .......
-Place the new T-value in level 1 and press the 'rkf' key
-The y-result will be in level 1 ( and in 'Y' ) and the new T-value
will be in 'T'
STACK | INPUT | OUTPUT |
Level 1 | T | [ x1, y1,z1 ............... xn, yn,zn , x'1, y'1,z'1 ............... x'n, y'n,z'n ]* |
where [ x1, y1,z1 ............... xn, yn,zn , x'1, y'1,z'1 ............... x'n, y'n,z'n ]* is the position-velocity vector at the instant T
Example: the same as above:
A system of three stars
M1 ( 2 ; 0 ;0 ) M2
( 0 ; 4 ; 0 ) M3 ( 0 ; 0 ; 1 )
unit = 1 AU
with initial velocities
V1 ( 0 ; 0.03 ; 0 ) V2 ( 0 ; 0 ; 0.01
) V3 ( -0.02 ; 0 ; 0 )
unit = 1 AU per day
and masses
m1 = 2 ; m2 = 1 ; m3
= 3
unit = 1 Solar mass
-Calculate the positions and velocities 10 days later.
-Masses: 2 'M1' STO 1
'M2' STO 3 'M3' STO
-Store 0 into 'T'
-With a tolerance of 10^(-7) , store this value into 'TOL'
-Store [ 2 0 0 0 4 0 0 0 1 0 0.03 0 0 0 0.01 -0.02 0 0 ] into 'Y' ( all these variables are already initialized in the 'DIFF' file )
-Then, 10 rkf yields ( rounded to 9 decimals )
[ 1.992077586
0.300333553 0.003673677 0.000661669
3.996080574 0.100603412 -0.194938947
0.001084107 0.997349745
-0.001550083 0.030038158 0.000706684
0.000132598 -0.000790385 0.010117549
-0.019010811 0.000238023 -0.000510306
]
-Press 20 rkf to get the positions & velocities 10 days later....
Notes:
-The directory contains 10 variables 'M1' 'M2' ..........
'M10'
-Add other 'Mk' if there are more than 10 celestial bodies.
References:
[1] Abramowitz and Stegun , "Handbook of Mathematical Functions"
- Dover Publications - ISBN 0-486-61272-4
[2] Press , Vetterling , Teukolsky , Flannery - "Numerical Recipes
in C++" - Cambridge University Press - ISBN 0-521-75033-4
[3] F. Scheid - "Numerical Analysis" - Mc Graw Hill
ISBN 07-055197-9
[4] J.C. Butcher - "The Numerical Analysis of Ordinary
Differential Equations" - John Wiley & Sons - ISBN
0-471-91046-5
[5] T. Feagin - "A tenth-order Runge-Kutta Method"