hp41programs

ContFrac

Continued Fractions for the HP-41


Overview
 

 1°) Real Arguments

   a) Wallis method
   b) Modified Lenz's algorithm

 2°) Complex Arguments

   a) Wallis method
   b) Modified Lenz's algorithm
 

-The 4 following programs compute a function f(x) defined by a continued fraction:

                            a1       a2       a3                               an
      f(x) =  b0 +  -----   -----   -----   .....................   -----  .......................     where  an &  bn are functions of  x and n
                          b1 +    b2 +    b3 +                            bn +
 

a) The Wallis method calculates  An  &  Bn  via the formulae   An = bn An-1 + an An-2  ,   Bn = bn Bn-1 + an Bn-2   with  A-1 = 1 ,  A0 = b0 ,  B-1 = 0 ,  B0 = 1
    f(x) is the limit  An/Bn as n tends to infinity and these programs stop when 2 consecutive fractions are equal.

b) In the modified Lenz's algorithm,
    we set   f0 = b0  if  b0 # 0  or  f0 = tiny  if  b0 = 0    ( tiny = E-30 in the following programs )
               C0 = f0 and D0 = 0

   then, for  n = 1 , 2 , .......      Cn = bn + an/Cn-1              (  Cn is replaced by tiny if Cn = 0 )
                                              Dn = 1/ [ bn + an Dn-1 ]      (  Dn = 1/tiny  if the denominator = 0 )

   and  fn = Cn Dn fn-1   until  | Cn Dn - 1 |  <=  a "small" number  (  E-9 in the following programs )    f(x) = the last  fn
 

1°) Real Arguments
 

     a) Wallis Method
 

Data Registers:           •  R00 = Subroutine name                          ( Register R00 is to be initialized before executing "CFR" )

                                         R01 = x       R03 = An    R05 = An-1        R07 = the successive An/Bn  and f(x)  at the end
                                         R02 = n       R04 = Bn    R06 = Bn-1

Flags: /                                                     Y-register = bn
Subroutine:  this program must produce   X-register = an    assuming  x is in R01 and n is in R02   ( n > 0 )

-To avoid an  OUT OF RANGE   add  the following instuctions after line 14
  RCL 03   ABS   RCL 04   ABS   X<Y?   X<>Y   X#0?   LOG   INT   10^X   ST/ 03   ST/ 04   ST/ 05   ST/ 06
-To avoid a possible infinite loop, you can replace line 39  by   ST- Y   X=0?   SIGN   /   ABS   E-9   X<Y?
 
 

01  LBL "CFR"  
02  STO 01
03  X<>Y
04  STO 03
05  STO 07
06  CLX
07  STO 02
08  STO 06
09  SIGN
10  STO 04
11  STO 05
12  LBL 01
13  ISG 02
14  CLX
15  XEQ IND 00
16  X=0?
17  GTO 02
18  ST* 06
19  RCL 05
20  *
21  RCL Y
22  RCL 03         
23  STO 05
24  *
25  +
26  STO 03
27  RCL 06
28  RCL 04
29  STO 06
30  R^
31  *
32  +
33  STO 04         
34  X=0?
35  GTO 01
36  /
37  ENTER^
38  X<> 07
39  X#Y? 
40  GTO 01
41  LBL 02
42  RCL 07         
43  END

 
   ( 59 bytes / SIZE 008 )
 
 

      STACK        INPUTS      OUTPUTS
           Y             b0            /
           X             x          f(x)

 
Example1:    tanh x may be computed by a continued fraction:

                   x      x2     x2     x2
   tanh x =  ----  ----  ----  ----  .....................
                  1+    3+   5+    7+

-Load the short routine ( let's call it "T" , any global LBL , maximum 6 characters )

  LBL "T"        GTO 01      -               X^2
  RCL 02        RCL 01      RCL 02     RTN
  1                   RTN           +
  X#Y?           LBL 01       RCL 01

     T  ASTO 00   and, for instance,  to get  tanh 1

     0  ENTER^   ( here b0 = 0 )
     1  XEQ "CFR"                     >>>>   tanh 1 =  0.761594156  ( in 9 seconds )
 

Example2:    If  f is defined by:    b0 = 1  ;   an = 2.x + n  ,  bn =  x2 + n2  ( n > 0 )  ;    evaluate  f(2) & f(Pi)

  LBL "T"        X^2           RCL 02
  RCL 01         +               +
  X^2              RCL 01     RTN
  RCL 02        ST+ X

     T  ASTO 00

     1  ENTER^
     2  XEQ "CFR"   >>>>    f(2) =  1.876576535    ( 8 seconds )

     1  ENTER^
    PI    R/S         >>>>   f(Pi) = 1.636265662   ( 9 seconds )
 

     b) Modified Lenz's Algorithm
 
 

Data Registers:           •  R00 = Subroutine name                          ( Register R00 is to be initialized before executing "LCFR" )

                                         R01 = x       R03 = fn            R05 = Dn        R07 = tiny = E-30
                                         R02 = n       R04 = Cn , bn    R06 = an

Flags: /                                                     Y-register = bn
Subroutine:  this program must produce   X-register = an    assuming  x is in R01 and n is in R02   ( n > 0 )

-Lines 38 thru 41 may be replaced by  X#Y?  but with a risk of infinite loop.
 
 

01  LBL "LCFR" 
02  STO 01
03   E-30
04  STO 07
05  0
06  STO 02
07  STO 05
08  R^
09  X=0?
10  RCL 07
11  STO 03
12  STO 04
13  LBL 01
14  ISG 02
15  CLX
16  XEQ IND 00
17  STO 06
18  RCL 04
19  /
20  X<>Y
21  STO 04
22  +
23  X=0?
24  RCL 07         
25  X<> 04
26  RCL 05
27  RCL 06
28  *
29  +
30  X=0?
31  RCL 07
32  1/X
33  STO 05         
34  RCL 04
35  *
36  ST* 03
37  1
38  - 
39  ABS
40   E-9
41  X<Y?
42  GTO 01
43  RCL 03         
44  END

 
    ( 63 bytes / SIZE 008 )
 
 

      STACK        INPUTS      OUTPUTS
           Y             b0            /
           X             x          f(x)

 
Example:       b0 = 1  ;   an = 2.x + n  ,  bn =  x2 + n2  ( n > 0 )  ;    evaluate  f(2)

  LBL "T"        X^2           RCL 02
  RCL 01         +               +
  X^2              RCL 01     RTN
  RCL 02        ST+ X

     T  ASTO 00

     1  ENTER^
     2  XEQ "LCFR"   >>>>    f(2) =  1.876576535    ( 10 seconds )
 

-"CFR" and "LCFR" are almost equivalent.
 

2°) Complex Arguments
 

     a) Wallis Method
 

-Here we have to compute  f(z) = Z = X + i.Y  with  z = x + i.y
 

Data Registers:           •  R00 = Subroutine name                                       ( Register R00 is to be initialized before executing "CFRZ" )

                                         R01 = x       R04 R05 = An    R08 R09 = An-1       R12-R13: temp           R14 = X
                                         R02 = y       R06 R07 = Bn    R10 R11 = Bn-1                                           R15 = Y
                                         R03 = n
Flags: /
Subroutine:   a program that returns

     T-register = Im(bn)
     Z-register = Re(bn)
     Y-register = Im(an)              assuming  x is in R01 ,  y is in R02  and n is in R03   ( n > 0 )
     X-register = Re(an)

-To avoid an  OUT OF RANGE   add  the following instuctions after line 24
  RCL 04   RCL 06   X<Y?   X<>Y   X#0?   LOG   INT   10^X   ST/ 04   ST/ 06   ST/ 08   ST/ 10
-To avoid a possible infinite loop,  replace line 95 by   E-8     X<Y?      ( or another "small" number )
 
 

  01  LBL "CFRZ"
  02  STO 01
  03  RDN
  04  STO 02
  05  X<> Z
  06  STO 15
  07  X<>Y
  08  STO 14
  09  R-P
  10  STO 04
  11  X<>Y
  12  STO 05
  13  CLX
  14  STO 03
  15  STO 07
  16  STO 09
  17  STO 10
  18  STO 11
  19  SIGN
  20  STO 06
  21  STO 08
  22  LBL 01
  23  ISG 03
  24  CLX 
  25  XEQ IND 00
  26  R-P
  27  X=0?
  28  GTO 02
  29  ST* 08
  30  ST* 10
  31  RDN
  32  ST+ 09
  33  ST+ 11
  34  RDN
  35  R-P
  36  STO 12
  37  X<>Y
  38  STO 13
  39  RCL 05
  40  +
  41  X<>Y
  42  RCL 04
  43  *
  44  P-R
  45  RCL 09
  46  RCL 08        
  47  P-R
  48  X<>Y
  49  ST+ T
  50  RDN
  51  +
  52  R-P
  53  X<> 04
  54  STO 08
  55  X<>Y
  56  X<> 05
  57  STO 09
  58  RCL 07
  59  RCL 13
  60  +
  61  RCL 06
  62  RCL 12
  63  *
  64  P-R
  65  RCL 11
  66  RCL 10        
  67  P-R
  68  X<>Y
  69  ST+ T
  70  RDN
  71  +
  72  R-P
  73  X<> 06
  74  STO 10
  75  X<>Y
  76  X<> 07
  77  STO 11
  78  RCL 05
  79  RCL 07
  80  -
  81  RCL 04
  82  RCL 06
  83  X=0?
  84  GTO 01
  85  /
  86  P-R
  87  ENTER^
  88  X<> 14
  89  -
  90  X<>Y
  91  ENTER^
  92  X<> 15
  93  -
  94  R-P
  95  X#0?
  96  GTO 01
  97  LBL 02
  98  RCL 15        
  99  RCL 14
100  END

 
   ( 127 bytes / SIZE 016 )
 
 

      STACK        INPUTS      OUTPUTS
           T         Im(b0)            /
           Z         Re(b0)            0
           Y             y            Y
           X             x            X

  with  f(z) = f(x+i.y) = X + i.Y

Example1:     Let's compute  tanh ( 1+2.i )

  LBL "T"       X#Y?          RCL 01       RCL 03       R-P           X^2
  CLST          GTO 01       RTN           +                 X<>Y        P-R
  RCL 03       CLX            LBL 01       RCL 02       ST+ X       RTN
  1                  RCL 02       -                 RCL 01       X<>Y

       T  ASTO 00

       0   ENTER^    ENTER^      (  b0 = 0 = 0 + 0.i )
       2   ENTER^
       1   XEQ "CFRZ"   >>>>    1.166736258   X<>Y  -0.243458200   whence   tanh ( 1+2.i ) =  1.166736258 - 0.243458200 i    ( in 96 seconds )
 

Example2:        If  f(z)  is defined by:    b0 = 0.2 + 0.3 i  ;   an = 2.z + n  ,  bn =  z2 + n2  ( n > 0 )  ;    evaluate  f(1+2.i)

  LBL "T"
  RCL 02
  RCL 01
  XEQ "Z^2"      ( cf "Complex Functions for the HP-41" )
  RCL 03
  X^2
  +
  RCL 01
  ST+ X
  RCL 03
  +
  RCL 02
  ST+ X
  X<>Y
  RTN

  T  ASTO 00

  0.3  ENTER^
  0.2  ENTER^
   2    ENTER^
   1   XEQ "CFRZ"  >>>>   1.084596569   X<>Y   -0.749791581    whence   f(1+2.i) =  1.084596569 - 0.749791581 i    ( in 74 seconds )
 

     b) Modified Lenz's Algorithm
 

                 f(z) = Z = X + i.Y  with  z = x + i.y
 

Data Registers:           •  R00 = Subroutine name                                       ( Register R00 is to be initialized before executing "LCFRZ" )

                                         R01 = x       R04 R05 = fn     R08 R09 = Dn       R12-R13 = bn
                                         R02 = y       R06 R07 = Cn    R10 R11 = an       R14 = tiny = E-30
                                         R03 = n
Flags: /
Subroutine:  a program that returns

     T-register = Im(bn)
     Z-register = Re(bn)
     Y-register = Im(an)              assuming  x is in R01 ,  y is in R02  and n is in R03   ( n > 0 )
     X-register = Re(an)
 
 

01  LBL "LCFRZ"
02  STO 01
03  RDN
04  STO 02
05  CLX
06   E-30
07  STO 14
08  RDN
09  R-P
10  X=0?
11  R^
12  STO 04
13  STO 06
14  X<>Y
15  STO 05
16  STO 07
17  CLX
18  STO 03
19  STO 08
20  STO 09
21  LBL 01
22  ISG 03
23  CLX
24  XEQ IND 00 
25  R-P
26  STO 10
27  RDN
28  STO 11
29  RDN
30  STO 12
31  RDN
32  STO 13
33  X<> Z
34  RCL 07
35  -
36  X<>Y
37  RCL 06
38  /
39  P-R
40  X<> Z
41  +
42  X<>Y
43  RCL 12          
44  +
45  R-P
46  X=0?
47  RCL 14
48  STO 06
49  X<>Y
50  STO 07
51  RCL 09
52  RCL 11
53  +
54  RCL 08
55  RCL 10
56  *
57  P-R
58  RCL 13
59  ST+ Z
60  CLX
61  RCL 12          
62  +
63  R-P
64  X=0?
65  RCL 14
66  1/X
67  STO 08
68  RCL 06
69  *
70  ST* 04
71  X<>Y
72  CHS
73  STO 09
74  RCL 07
75  +
76  ST+ 05
77  X<>Y
78  P-R
79  1
80  -
81  R-P
82   E-9
83  X<Y?
84  GTO 01
85  RCL 05          
86  RCL 04
87  P-R
88  END

 
   ( 111 bytes / SIZE 015 )
 
 

      STACK        INPUTS      OUTPUTS
           T         Im(b0)            /
           Z         Re(b0)            /
           Y             y            Y
           X             x            X

  with  f(z) = f(x+i.y) = X + i.Y

Example:           f(z)  is defined by:    b0 = 0.2 + 0.3 i  ;   an = 2.z + n  ,  bn =  z2 + n2  ( n > 0 )  ;    evaluate  f(1+2.i)

  LBL "T"
  RCL 02
  RCL 01
  XEQ "Z^2"      ( cf "Complex Functions for the HP-41" )
  RCL 03
  X^2
  +
  RCL 01
  ST+ X
  RCL 03
  +
  RCL 02
  ST+ X
  X<>Y
  RTN

  T  ASTO 00

  0.3  ENTER^
  0.2  ENTER^
   2    ENTER^
   1   XEQ "LCFRZ"  >>>>   1.084596568   X<>Y   -0.749791576    whence   f(1+2.i) =  1.084596568 - 0.749791576 i    ( in 60 seconds )

-"LCFRZ"  is shorter than "CFRZ"
-Moreover, it seems faster ( there are less  R-P & P-R  instructions ).
-The modified Lenz's algorithm also avoids the risk of "OUT OF RANGE"
 

References:

[1]  Abramowitz & 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