Ephemerides & Chebyshev Polynomials for the HP-41
Overview
1°) Positions
a) Recurrence Relation
b) Trigonometric Relation
c) Clenshaw's Algorithm
2°) Positions & Velocities
a) Recurrence Relation
b) Trigonometric Relation
c) Clenshaw's Algorithm
3°) M-Code Routines
a) Positions
b) Positions & Velocities
c) Positions & Velocities ( Clenshaw's
Algorithm )
d) Clenshaw's Algorithm ( simplified
version )
-One program is already listed in "Orthogonal Polynomials for the HP-41"
paragraph 5-b)
-Several variants are proposed hereunder.
-If y(t) is a coordinate of a celestial body at a given instant t ( t belonging to the interval [ t0 ; t0 + DT ] ) , y is given by the formula:
y = a0 + a1.T1(x) + ....... + an.Tn(x) where x = -1 + 2(t-t0)/DT ( -1 <= x <= +1 ) , Tk(x) are Chebyshev polynomials of the 1st kind
and a0 , a1 , ....... , an are given in various publications, see for example references [2] & [3]
-The derivative of such a function may also be obtained by
dy/dx = a1.U0(x) + 2a2.U1(x)
+........ + n.an.Un-1(x)
where Uk(x) are Chebyshev polynomials of the 2nd
kind
1°) Positions
a) Recurrence Relation
-Here, the Chebyshev polynomials of the 1st kind are computed by the
formula
Tk(x) = 2x.Tk-1(x)
- Tk-2(x) ; T0(x) = 1 ; T1(x)
= x
Data Registers: ( Registers Rbb thru Ree are to be initialized before executing "CdT" )
• Rbb = a0 • Rbb+1 = a1
......................... • Ree = an
ee = bb + n
Flags: /
Subroutines: /
01 LBL "CdT"
02 X<>Y 03 STO M 04 SIGN 05 STO O 06 X<>Y 07 STO N |
08 RCL IND M
09 ISG M 10 RCL IND M 11 RCL Z 12 * 13 + 14 STO P |
15 CLX
16 ISG M 17 LBL 01 18 R^ 19 ST+ X 20 RCL N 21 ST* Y |
22 X<> O
23 - 24 STO N 25 RCL IND M 26 * 27 + 28 ISG M |
29 GTO 01
30 RCL P 31 + 32 CLA 33 END |
( 59 bytes )
STACK | INPUTS | OUTPUTS |
T | / | x |
Z | / | x |
Y | bbb.eee | x |
X | x | y(x) |
where bbb.eee is the control number of coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
Example: Calculate the mean ecliptic longitude of Jupiter ( with respect to the standard ecliptic J2000.0 ) on 2004/07/07 16h41m TT
-In the French Ephemeris "La Connaissance des Temps", we find 6 coefficients valid between 2004/01/00 0h TT to 2004/12/33 0h TT ( DT = 368 days )
-Store these coefficients into, say R10 thru R15 ( control number = 10.015 )
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
-The number days since 2004/01/00 0h TT is 189.695138889 whence x = -1 + 189.695138889 / 184 = 0.030951842
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time = 2s---
Notes:
-Unlike the version of "CdT" listed in "Orthogonal Polynomials for the
HP-41" paragraph 5-b)
this routine adds a0 + a1.x after
calculating a2.T2(x) + ....... + an.Tn(x)
-Since the first 2 coefficients usually have larger magnitudes than
the other ones,
we can expect less roundoff-errors in the final result.
-For the rest, the methods are identical.
b) Trigonometric Relation
-Here, we use Tk(x) = Cos ( k Acos x )
Data Registers: ( Registers R00 thru Rnn are to be initialized before executing "CdT2" )
• R00 = a0 • R01 = a1
......................... • Rnn = an
Flags: /
Subroutines: /
01 LBL "CdT2"
02 X<>Y 03 STO M 04 CLX 05 LBL 01 06 RCL Y 07 ACOS 08 RCL M 09 * 10 COS 11 RCL IND M 12 * 13 + 14 DSE M 15 GTO 01 16 RCL 00 17 + 18 END |
( 33 bytes / SIZE nnn+1 )
STACK | INPUTS | OUTPUTS |
T | / | x |
Z | / | x |
Y | n | x |
X | x | y(x) |
where (n+1) is the number of coefficients a0
, a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
Example: The same one. Store the 6 coefficients into R00 thru R05
R00 = a0 = 173.010953
R01 = a1 = 13.996747
R02 = a2 = -0.032139
R03 = a3 = 0.003368
R04 = a4 = 0.000037
R05 = a5 = -0.000008
5
ENTER^
0.030951842 XEQ "CdT2"
>>>> L = 173°475979
---Execution time = 7s---
Notes:
-This version is obviously slower, but the routine is also shorter.
-Synthetic register M is cleared.
c) Clenshaw's Algorithm
-Another method to compute a sum of Chebyshev polynomials is given in
reference [4]
-Let:
• dn+1 = dn = 0
• dj = 2.x dj+1 - dj+2
+ aj for
j = n , n-1 , n-2 , ..... , 1
-Then y = a0 + a1.T1(x)
+ ....... + an.Tn(x) = x d1 - d2
+ a0
Data Registers: ( Registers Rbb thru Ree are to be initialized before executing "CdT" )
• Rbb = a0 • Rbb+1 = a1
......................... • Ree = an
ee = bb + n
Flags: /
Subroutines: /
01 LBL "CdT"
02 STO M 03 X<>Y 04 ENTER^ 05 INT 06 ST- Y 07 E3 08 ST* Z 09 / 10 + 11 STO N 12 CLST 13 LBL 01 14 RCL X 15 RCL M 16 ST+ X 17 * 18 R^ 19 - 20 RCL IND N 21 + 22 DSE N 23 GTO 01 24 RCL M 25 * 26 X<>Y 27 - 28 RCL IND N 29 + 30 CLA 31 END |
( 52 bytes )
STACK | INPUTS | OUTPUTS |
Y | bbb.eee | / |
X | x | y(x) |
where bbb.eee is the control number of coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
Example: The same one. Store the 6 coefficients, for instance into R10 thru R15 ( control number = 10.015 )
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time = 2s---
Notes:
-The method is faster than the elementary one.
-The alpha register is cleared.
-If you place in Y a control number of the form eee.bbb
( like 15.010 in the example above ) , delete lines 04 to 10.
2°) Positions & Velocities
a) Recurrence Relations
-The Chebyshev polynomials of the 1st & 2nd kind are computed by
the formulae:
Tk(x) = 2x.Tk-1(x) - Tk-2(x)
; T0(x) = 1 ; T1(x) = x
( first kind )
Uk(x) = 2x.Uk-1(x) - Uk-2(x)
; U0(x) = 1 ; U1(x) = 2x
( second kind )
Data Registers: ( Registers Rbb thru Ree are to be initialized before executing "CdT" )
• Rbb = a0 • Rbb+1 = a1 ......................... • Ree = an ee = bb + n
Flag: F01 CF 01 = y(x)
SF 01 = dy/dx
Subroutines: /
01 LBL "CdT"
02 CLA 03 STO O 04 X<>Y 05 STO M 06 SIGN 07 FC? 01 08 STO N |
09 CHS
10 FS? 01 11 STO O 12 CLX 13 RCL IND M 14 FS? 01 15 CLX 16 ISG M |
17 LBL 01
18 RCL Y 19 ST+ X 20 RCL N 21 ST* Y 22 X<> O 23 - 24 STO N |
25 RCL IND M
26 * 27 ISG P 28 CLX 29 RCL P 30 FC? 01 31 SIGN 32 * |
33 +
34 ISG M 35 GTO 01 36 CLA 37 END |
( 66 bytes )
STACK | INPUTS | OUTPUTS |
T | / | x |
Z | / | x |
Y | bbb.eee | x |
X | x | F(x) |
where bbb.eee is the control number of the coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
--> F(x) = y(x) if CF 01
--> F(x) = dy/dx if SF 01
Example: The same one. If the 6 coefficients are stored in R10 thru R15 , Control number = 10.015
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
• Position CF 01
CF 01
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time = 3s---
• Velocity SF 01
SF 01
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> dL/dx = 13.982645
---Execution time = 3s---
Note:
-To get the velocity in degree/day, the last result must be divided
by DT/2 , here 368/2 = 184
-It yields: dL/dt = 0.075992635 deg/day
b) Trigonometric Relation
-The Chebyshev polynomials of the 2nd kind are computed by
Uk(x) = Sin ( (k+1) Acos x ) / Sin ( Acos
x )
Data Registers: ( Registers R00 thru Rnn are to be initialized before executing "CdT2" )
• R00 = a0 • R01 = a1 ......................... • Rnn = an
Flag: F01
CF 01 = y(x)
SF 01 = dy/dx
Subroutines: /
01 LBL "CdT2"
02 DEG 03 X<>Y 04 STO M 05 CLX 06 LBL 01 07 RCL Y |
08 ACOS
09 RCL M 10 * 11 FS? 01 12 SIN 13 FC? 01 14 COS |
15 RCL M
16 FC? 01 17 SIGN 18 * 19 RCL IND M 20 * 21 + |
22 DSE M
23 GTO 01 24 X<>Y 25 ACOS 26 SIN 27 FC? 01 28 SIGN |
29 /
30 RCL 00 31 FS? 01 32 CLX 33 + 34 END |
( 55 bytes / SIZE nnn+1 )
STACK | INPUTS | OUTPUTS |
T | / | x |
Z | / | x |
Y | n | x |
X | x | F(x) |
where (n+1) is the number of coefficients a0
, a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
--> F(x) = y(x) if CF 01
--> F(x) = dy/dx if SF 01
Example: The same one. Store the 6 coefficients into R00 thru R05
R00 = a0 = 173.010953
R01 = a1 = 13.996747
R02 = a2 = -0.032139
R03 = a3 = 0.003368
R04 = a4 = 0.000037
R05 = a5 = -0.000008
• Position CF 01
CF 01
5
ENTER^
0.030951842 XEQ "CdT2"
>>>> L = 173°475979
---Execution time = 9s---
• Velocity SF 01
SF 01
5
ENTER^
0.030951842 XEQ "CdT2"
>>>> dL/dx = 13.982645
---Execution time = 9s---
Notes:
-To get the velocity in degree/day, the last result must be divided
by DT/2 , here 368/2 = 184
-It yields: dL/dt = 0.075992635 deg/day
-This variant has a defect: if flag F01 is set, it does not work for
x = +/-1
c) Clenshaw's Algorithm
y(x) is obtained by the method of paragraph 1°-c)
To get the first derivative, let:
• d'n+1 = d'n = 0
• d'j = 2.x d'j+1 - d'j+2
+ j.aj for
j = n , n-1 , n-2 , ..... , 1
-Then d'1 = dy/dx = a1.U0(x)
+ 2a2.U1(x) +........ + n.an.Un-1(x)
Data Registers: ( Registers Rbb thru Ree are to be initialized before executing "CdT" )
• Rbb = a0 • Rbb+1 = a1 ......................... • Ree = an ee = bb + n
Flag: F01 CF 01 = y(x)
SF 01 = dy/dx
Subroutines: /
-Line 28 = TEXT0 or another NOP instruction like STO X
or LBL 00 ....
01 LBL "CdT"
02 STO M 03 X<>Y 04 INT 05 ST- L 06 LASTX 07 E3 08 * 09 STO N |
10 X<>Y
11 - 12 STO O 13 CLST 14 LBL 01 15 RCL X 16 RCL M 17 ST+ X 18 * |
19 R^
20 - 21 RCL IND N 22 RCL O 23 FC? 01 24 SIGN 25 * 26 + 27 DSE N |
28 ""
29 DSE O 30 GTO 01 31 FS? 01 32 GTO 02 33 RCL M 34 * 35 X<>Y 36 - |
37 RCL IND N
38 + 39 LBL 02 40 CLA 41 END |
( 67 bytes )
STACK | INPUTS | OUTPUTS |
T | / | x |
Z | / | x |
Y | bbb.eee | x |
X | x | F(x) |
where bbb.eee is the control number of the coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
--> F(x) = y(x) if CF 01
--> F(x) = dy/dx if SF 01
Example: The same one. If the 6 coefficients are stored in R10 thru R15 , Control number = 10.015
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
• Position CF 01
CF 01
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time = 3s---
• Velocity SF 01
SF 01
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> dL/dx = 13.982645
---Execution time = 3s---
Note:
-To get the velocity in degree/day, the last result must be divided
by DT/2 , here 368/2 = 184
-It yields: dL/dt = 0.075992635 deg/day
3°) M-Code Routines
a) Positions
-This routine employs Clenshaw's algorithm ( paragraph 1-c) )
-13-digit routines are used to get a better precision.
-The existence of the registers is tested, but there is no check for
alpha data.
094 "T"
044 "d"
003 "C"
2A0 SETDEC
0B8 C=Y
070 N=C ALL
084 C
0ED =
064 frc(C)
226 C
226 =
226 1000.C
0F0 C<>N ALL
260 SETHEX
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
1BC RCR 11
0F0 C<>N ALL
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
106 A=C S&X
0B0 C=N ALL
11A A=C M
378 C=c
03C RCR 3
0E6 B<>C S&X
378 C=c
0E6 B<>C S&X
20E C=A+C ALL
23A C=C+1 M
070 N=C ALL
CPU register N now contains 1+bbb.eee ( absolute address in
hexadecimal )
106 A=C S&X
130 LDI S&X
200 200h
( correct value for an HP-41CV/CX or C with a QUAD memory module )
306 ?A<C S&X
381 ?NCGO
00A 02E0
NONEXISTENT is displayed if the specified register doesn't exist and the
routine stops
0F8 C=X
128 L=C
345 ?NCXQ
040 CLA
2A0 SETDEC
LOOP
138 C=L
10E A=C ALL
01D C=
060 A+C
1B8 C=N
158 M=C ALL
178 C=M
149 C=
060 AB*CM
238 C=P
2BE C=-C
158 M=C ALL
1F8 C=O
031 C=
060 AB+CM
178 C=M
1E8 O=C
1B8 C=N
228 P=C
0B0 C=N ALL
270 RAMSLCT
038 READATA
025 C=
060 AB+C
046 C=0 S&X
270 RAMSLCT
0AE A<>C ALL
1A8 N=C
0CE C=B ALL
168 M=C
260 SETHEX
0B0 C=N ALL
266 C=C-1 S&X
070 N=C ALL
106 A=C S&X
03C RCR 3
306 ?A<C S&X
2D3 JNC-38d
GOTO LOOP
2A0 SETDEC
1B8 C=N
10E A=C ALL
138 C=L
13D C=
060 AB*C
238 C=P
2BE C=-C
158 M=C ALL
1F8 C=O
031 C=
060 AB+CM
0B0 C=N ALL
270 RAMSLCT
038 READATA
025 C=
060 AB+C
10E A=C ALL
046 C=0 S&X
270 RAMSLCT
0AE A<>C ALL
0E8 X=C
345 ?NCGO
042 CLA
( 104 words )
STACK | INPUTS | OUTPUTS |
T | T | T |
Z | Z | Z |
Y | bbb.eee | bbb.eee |
X | x | y(x) |
L | / | x |
where bbb.eee is the control number of the coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
Example: Always the same one. If the 6 coefficients are stored in R10 thru R15 , Control number = 10.015
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time < 1s---
Notes:
-The alpha register is cleared but synthetic register Q is not
used.
-If eee = 000 , you'll get a DATA ERROR message, even in R00
does exist.
-This routine is the fastest program that is written in this page.
-With 14 coefficients, execution time = 1.4 second
-With 100 coefficients, ------------- = 9.6 seconds.
b) Positions & Velocities
-This M-Code routine "CdT" employs the recurrence relations of paragraphs
1-a) & 2-a)
-13-digit routines are used to get a better precision.
-The existence of the registers is tested, but there is no check for
alpha data.
094 "T"
044 "d"
003 "C"
2A0 SETDEC
0B8 C=Y
070 N=C ALL
084 C
0ED =
064 frc(C)
226 C
226 =
226 1000.C
0F0 C<>N ALL
260 SETHEX
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
1BC RCR 11
0F0 C<>N ALL
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
106 A=C S&X
0B0 C=N ALL
11A A=C M
378 C=c
03C RCR 3
0E6 B<>C S&X
378 C=c
0E6 B<>C S&X
20E C=A+C ALL
070 N=C ALL
CPU register N now contains bbb.eee ( absolute address in
hexadecimal )
106 A=C S&X
03C RCR 3
306 ?A<C S&X
013 JNC+02
0A6 A<>C S&X
130 LDI S&X
200 200h
( correct value for an HP-41CV/CX or C with a QUAD memory module )
306 ?A<C S&X
381 ?NCGO
00A 02E0
NONEXISTENT is displayed if the specified register doesn't exist and the
routine stops
2A0 SETDEC
0F8 C=X
128 L=C
104 CLRF 8
0B8 C=Y
2FE ?C<0
013 JNC+02
108 SETF 8
04E C=0 ALL
0E8 X=C
1A8 N=C
10C ?FSET 8
053 JNC+10d
168 M=C
35C C=
050 1
1E8 O=C
04E C=0 ALL
2BE C=-C
228 P=C
1A0 A=B=C=0
08B JNC+17d
35C C=
050 1
168 M=C
138 C=L
02E B=0 ALL
0FA B<>C M
228 P=C
0EE B<>C ALL
1E8 O=C
0B0 C=N ALL
03C RCR 3
270 RAMSLCT
038 READATA
02E C
0FA ->
0AE AB
081 0 ramslct
064 AB STO Q+
260 SETHEX
LOOP
0B0 C=N ALL
23A C=C+1 M
070 N=C ALL
106 A=C S&X
03C RCR 3
306 ?A<C S&X
1BF JC+55d
2A0 SETDEC
138 C=L
10E A=C ALL
01D C=
060 A+C
1B8 C=N
158 M=C ALL
178 C=M
149 C=
060 AB*CM
238 C=P
2BE C=-C
158 M=C ALL
1F8 C=O
031 C=
060 AB+CM
178 C=M
1E8 O=C
1B8 C=N
228 P=C
0AE A<>C ALL
1A8 N=C
0EE B<>C ALL
168 M=C
0F8 C=X
10C ?FSET 8
017 JC+02
1A0 A=B=C=0
02E C
0FA ->
0AE AB
001 C=
060 AB+1
0E8 X=C
0B0 C=N ALL
03C RCR 3
270 RAMSLCT
038 READATA
13D C=
060 AB*C
046 C=0 S&X
270 RAMSLCT
1B8 C=N
158 M=C ALL
178 C=M
149 C=
060 AB*CM
0D1 RCL
064 Q+
031 C=
060 AB+CM
089 AB
064 STO Q+
21B JNC-61d
GOTO LOOP
2A0 SETDEC
1A0 A=B=C=0
0D1 RCL
064 Q+
031 C=
060 AB+CM
0E8 X=C
345 ?NCGO
042 CLA
( 151 words )
STACK | INPUTS | OUTPUTS |
T | T | T |
Z | Z | Z |
Y | +/- bbb.eee | +/- bbb.eee |
X | x | F(x) |
L | / | x |
where bbb.eee is the control number of the coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
--> F(x) = y(x) if the control number is
+ bbb.eee
--> F(x) = dy/dx if the control number is -
bbb.eee
Example: Always the same one. If the 6 coefficients are stored in R10 thru R15 , Control number = 10.015
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
• Position:
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time = 1s---
• Velocity:
10.015 CHS ENTER^
0.030951842 XEQ "CdT"
>>>> dL/dx = 13.982645
---Execution time = 1s---
Notes:
-To get the velocity in degree/day, the last result must be divided
by DT/2 , here 368/2 = 184
-It yields: dL/dt = 0.075992635 deg/day
-The alpha register is cleared and synthetic register Q is used.
-If eee = 000 , you'll get a DATA ERROR message, even if R00
does exist.
c) Positions & Velocities
( Clenshaw's Algorithm )
-This routine employs Clenshaw's algorithm ( paragraphs 1-c) & 2-c)
)
-13-digit routines are used to get a better precision.
-The existence of the registers is tested, but there is no check for
alpha data.
094 "T"
044 "d"
003 "C"
2A0 SETDEC
0B8 C=Y
070 N=C ALL
084 C
0ED =
064 frc(C)
226 C
226 =
226 1000.C
268 Q=C
0F0 C<>N ALL
260 SETHEX
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
1BC RCR 11
0F0 C<>N ALL
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
106 A=C S&X
0B0 C=N ALL
11A A=C M
378 C=c
03C RCR 3
0E6 B<>C S&X
378 C=c
0E6 B<>C S&X
20E C=A+C ALL
23A C=C+1 M
070 N=C ALL
CPU register N now contains 1+bbb.eee ( absolute address in
hexadecimal )
106 A=C S&X
130 LDI S&X
200 200h
( correct value for an HP-41CV/CX or C with a QUAD memory module )
306 ?A<C S&X
381 ?NCGO
00A 02E0
NONEXISTENT is displayed if the specified register doesn't exist and the
routine stops
0F8 C=X
128 L=C
345 ?NCXQ
040 CLA
2A0 SETDEC
278 C=Q
088 C
0ED =
064 Int(C)
268 Q=C
0B8 C=Y
088 C
0ED =
064 Int(C)
2BE C=-C
10E A=C ALL
278 C=Q
01D C=
060 A+C
05E C= | C |
268 Q=C
104 CLRF 8
0B8 C=Y
2FE ?C<0
013 JNC+02
108 SETF 8
2A0 SETDEC
LOOP
138 C=L
10E A=C ALL
01D C=
060 A+C
1B8 C=N
158 M=C ALL
178 C=M
149 C=
060 AB*CM
238 C=P
2BE C=-C
158 M=C ALL
1F8 C=O
031 C=
060 AB+CM
178 C=M
1E8 O=C
1B8 C=N
228 P=C
0AE A<>C ALL
1A8 N=C
0CE C=B ALL
168 M=C
278 C=Q
10C ?FSET 8
027 JC+04
04E C
35C =
050 1
10E A=C ALL
0B0 C=N ALL
270 RAMSLCT
038 READATA
135 C=
060 A*C
046 C=0 S&X
270 RAMSLCT
1B8 C=N
158 M=C ALL
178 C=M
031 C=
060 AB+CM
0AE A<>C ALL
1A8 N=C
0CE C=B ALL
168 M=C
278 C=Q
02E C
0FA ->
0AE AB
009 C=
060 AB-1
268 Q=C
260 SETHEX
0B0 C=N ALL
266 C=C-1 S&X
070 N=C ALL
106 A=C S&X
03C RCR 3
306 ?A<C S&X
21B JNC-61d
GOTO LOOP
2A0 SETDEC
1B8 C=N
10E A=C ALL
178 C=M
0EE B<>C ALL
04E C=0 ALL
10C ?FSET 8
06F JC+13d
138 C=L
13D C=
060 AB*C
238 C=P
2BE C=-C
158 M=C ALL
1F8 C=O
031 C=
060 AB+CM
0B0 C=N ALL
270 RAMSLCT
038 READATA
025 C=
060 AB+C
10E A=C ALL
046 C=0 S&X
270 RAMSLCT
0AE A<>C ALL
0E8 X=C
345 ?NCGO
042 CLA
( 155 words )
STACK | INPUTS | OUTPUTS |
T | T | T |
Z | Z | Z |
Y | +/- bbb.eee | +/- bbb.eee |
X | x | F(x) |
L | / | x |
where bbb.eee is the control number of the coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
--> F(x) = y(x) if the control number is
+ bbb.eee
--> F(x) = dy/dx if the control number is -
bbb.eee
Example: Always the same one. If the 6 coefficients are stored in R10 thru R15 , Control number = 10.015
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
• Position:
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time = 1s---
• Velocity:
10.015 CHS ENTER^
0.030951842 XEQ "CdT"
>>>> dL/dx = 13.982645
---Execution time = 1s---
Notes:
-To get the velocity in degree/day, the last result must be divided
by DT/2 , here 368/2 = 184
-It yields: dL/dt = 0.075992635 deg/day
-The alpha register is cleared and synthetic register Q is used.
-If eee = 000 , you'll get a DATA ERROR message, even in R00
does exist.
-With 14 coefficients, execution time = 2.2 seconds
-With 100 coefficients, ------------- = 16 seconds.
-All these M-Code routines use 2 registers for the dj's:
1 for the 13-digit mantissa and 1 for the sign & exponent.
-So, they could be simplified with perhaps a small roundoff-error in
the last decimal...
d) Clenshaw's Algorithm
( simplified version )
-This M-code routine uses only one register for each intermediate result:
-The program runs faster with perhaps a minor loss of precision.
-The existence of the registers is tested, but there is no check for
alpha data.
094 "T"
044 "d"
003 "C"
2A0 SETDEC
0B8 C=Y
070 N=C ALL
084 C
0ED =
064 frc(C)
226 C
226 =
226 1000.C
268 Q=C
0F0 C<>N ALL
260 SETHEX
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
1BC RCR 11
0F0 C<>N ALL
38D ?NCXQ
converts the decimal number in C
008 02E3
into hexadecimal in C S&X field
106 A=C S&X
0B0 C=N ALL
11A A=C M
378 C=c
15A A=A+C M
03C RCR 3
146 A=A+C S&X
0AE A<>C ALL
23A C=C+1 M
070 N=C ALL
CPU register N now contains 1+bbb.eee ( absolute address in
hexadecimal )
106 A=C S&X
130 LDI S&X
200 200h
( correct value for an HP-41CV/CX or C with a QUAD memory module )
306 ?A<C S&X
381 ?NCGO
00A 02E0
NONEXISTENT is displayed if the specified register doesn't exist and the
routine stops
0F8 C=X
128 L=C
345 ?NCXQ
040 CLA
2A0 SETDEC
278 C=Q
088 C
0ED =
064 Int(C)
268 Q=C
0B8 C=Y
088 C
0ED =
064 Int(C)
2BE C=-C
10E A=C ALL
278 C=Q
01D C=
060 A+C
05E C= | C |
268 Q=C
104 CLRF 8
0B8 C=Y
2FE ?C<0
013 JNC+02
108 SETF 8
2A0 SETDEC
LOOP
138 C=L
10E A=C ALL
01D C=
060 A+C
178 C=M
13D C=
060 AB*C
1B8 C=N
2BE C=-C
025 C=
061 AB+C
1E8 O=C
178 C=M
1A8 N=C
0B0 C=N ALL
270 RAMSLCT
038 READATA
10E A=C ALL
046 C=0 S&X
270 RAMSLCT
10C ?FSET 8
02B JNC+05
278 C=Q
135 C=
060 A*C
10E A=C ALL
1F8 C=O
01D C=
060 A+C
168 M=C
10C ?FSET 8
043 JNC+08
278 C=Q
02E C
0FA ->
0AE AB
009 C=
060 AB-1
268 Q=C
260 SETHEX
0B0 C=N ALL
266 C=C-1 S&X
070 N=C ALL
106 A=C S&X
03C RCR 3
306 ?A<C S&X
28B JNC-47d
GOTO LOOP
2A0 SETDEC
178 C=M
10C ?FSET 8
097 JC+18d
10E A=C ALL
138 C=L
135 C=
060 A*C
1B8 C=N
2BE C=-C
025 C=
061 AB+C
0B0 C=N ALL
270 RAMSLCT
038 READATA
025 C=
060 AB+C
10E A=C ALL
046 C=0 S&X
270 RAMSLCT
0AE A<>C ALL
0E8 X=C
345 ?NCGO
042 CLA
( 135 words )
STACK | INPUTS | OUTPUTS |
T | T | T |
Z | Z | Z |
Y | +/- bbb.eee | +/- bbb.eee |
X | x | F(x) |
L | / | x |
where bbb.eee is the control number of the coefficients
a0 , a1 , ....... , an
and x = -1 + 2(t-t0)/DT
( -1 <= x <= +1 )
--> F(x) = y(x) if the control number is
+ bbb.eee
--> F(x) = dy/dx if the control number is -
bbb.eee
Example: Again the same one. If the 6 coefficients are stored in R10 thru R15 , Control number = 10.015
R10 = a0 = 173.010953
R11 = a1 = 13.996747
R12 = a2 = -0.032139
R13 = a3 = 0.003368
R14 = a4 = 0.000037
R15 = a5 = -0.000008
• Position:
10.015
ENTER^
0.030951842 XEQ "CdT"
>>>> L = 173°475979
---Execution time < 1s---
• Velocity:
10.015 CHS ENTER^
0.030951842 XEQ "CdT"
>>>> dL/dx = 13.982645
---Execution time < 1s---
Notes:
-To get the velocity in degree/day, the last result must be divided
by DT/2 , here 368/2 = 184
-It yields: dL/dt = 0.075992635 deg/day
-The alpha register is cleared and synthetic register Q is used.
-If eee = 000 , you'll get a DATA ERROR message, even in R00
does exist.
-With 14 coefficients, execution time = 1.3 second
-With 100 coefficients, ------------- = 10 seconds ( 14s for
dy/dx ).
References:
[1] Newhall - "Numerical Representation of Planetary Ephemerides"
[2] ftp://ssd.jpl.nasa.gov/pub/eph/planets/ascii
[3] http://www.imcce.fr/inpop
[4] Press , Vetterling , Teukolsky , Flannery - "Numerical
Recipes in C++" - Cambridge University Press - ISBN 0-521-75033-4