# hp41programs

Elliptic Elliptic Integrals for the HP-41

Overview

1°) Legendre Elliptic Integrals of the first and second kind
2°) Carlson Elliptic Integrals

a) Carlson Elliptic Integrals of the first kind

a-1) Program#1
a-2) Program#2  ( faster )

b) Carlson Elliptic Integrals of the second kind ( degenerate form & symmetric form )
c) Carlson Elliptic Integrals of the third kind

c-1) Program#1
c-2) Program#2  ( faster )
c-3) Program#3  ( even faster )

d) Complex arguments

d-1) Elliptic Integrals of the first kind

d-1a)  Program#1
d-1b)  Program#2  ( faster )

d-2) Elliptic Integrals of the third kind

d-2a)  Program#1
d-2b)  Program#2  ( faster )
d-2c)  Program#3  ( even faster )

e) Micro-Code Functions

e-1) Integrals of the first kind - real & complex
e-2) Integrals of the third kind - real & complex

3°) Legendre Elliptic Integrals    ( via Carlson Integrals )

a) Legendre Elliptic Integrals of the first kind
b) Legendre Elliptic Integrals of the second kind
c) Legendre Elliptic Integrals of the third kind
d) Legendre Elliptic Integrals ( all three )

NB:  Integrals are symbolized by  "§" :      §a f(x) dx  ...

1°) Legendre Elliptic Integrals of the first and second kind

-Legendre elliptic integrals are:

- the complete elliptic integrals of the 1st kind:          K ( m ) =  §0pi/2 ( 1 - m sin2 t )-1/2 dt
- the complete elliptic integrals of the 2nd kind:         E ( m ) =  §0pi/2  ( 1 - m sin2 t )1/2 dt
- the incomplete elliptic integrals of the 1st kind:   F ( v | m ) =  §0v ( 1 - m sin2 t )-1/2 dt       ( 0 < = v < = 90° )
- the incomplete elliptic integrals of the 2nd kind:  E ( v | m ) =  §0v  ( 1 - m sin2 t )1/2 dt

-The elliptic integrals of the third kind are much more complicated and will be calculated differently  ( cf  below )

-Here we assume:  0 < = m < = 1
-The arithmetic-geometric mean ( AGM ) scheme is used here ( cf "Jacobian Elliptic Functions" ), after which:

K(m) = pi/2an
E(m) = K(m) - K(m).(c02+21c12+ ... +2ncn2)/2

-To obtain   F ( v | m) , the HP-41 must determine n angles  v1 , ... , vn
In Abramowitz' "Handbook of Mathematical Functions" , we find:

tan ( vn+1 - vn ) = ( bn/an ) tan vn  and  v0 = v

-However, with this recurrence relation, we can't determine the angles v  in the proper quadrant
and so, we obtain wrong results. That's why I 've changed this formula into:

tan ( vn+1 - 2vn ) = (( bn/an ) tan vn - tan vn) / ( 1 + ( bn/an ) tan2 vn )

-But there is still a problem: if one angle is equal to 90°, tan2 v  will produce "OUT OF RANGE"
-Finally, the HP-41 uses the relation:

tan ( vn+1 - 2vn ) = (( bn/an )  - 1 ) / ( 1 / tan vn + ( bn/an ) tan vn )         ( without forgetting lines 45-48-50 )

Then,    F ( v | m ) = vn / ( 2nan )
and       E ( v | m ) = Z ( v | m ) + ( E / K ) F ( v | m )

where    Z( v | m ) = c1 sin v1 + ... + cn sin vn   is the Jacobian Zeta function.

Notes:

1-R00 = c02+21c12+ ... +2ncn2        R01 = 1 , 2 , 4 , 8 , .....      R02 = ak
R03 = bk and  F ( v | m )               R04 = vk                            R05 = Z( v | m )          R06 = an-1
2-K( 1 ) is infinite  ( 9.999999999 E99 in the T-register )                  E( 1 ) = 1
F ( v | 1 ) = ln ( tan ( pi/4 + v/2 ) )                                             E ( v | 1 ) = sin v
3-K( m ) and E( m ) are automatically calculated in the T and Z registers
4-The angle v must be expressed in degrees..

 01  LBL "ELI"   02  DEG   03  STO 04   04  X<>Y   05  1   06  X#Y?   07  GTO 00   08  90   09  TAN   10  X<>Y   11  R^   12  LASTX   13  X#Y?   14  GTO 02          15  TAN   16  X<>Y   17  SIGN   18  RTN   19  LBL 02   20  RDN   21  SIN   22  ST+ Y   23  X<>Y   24  LASTX   25  COS 26  /   27  LN   28  1   29  X<> Z   30  RTN   31  LBL 00   32  STO 01   33  STO 02   34  X<>Y   35  STO 00   36  -   37  SQRT   38  STO 03   39  CLX   40  STO 05          41  LBL 01   42  1   43  STO 06   44  RCL 04   45  ENTER^   46  ST+ Y   47  TAN   48  RCL 03   49  RCL 02   50  / 51  ST- 06   52  X<>Y   53  ST* Y   54  X#0?   55  1/X   56  +   57  X=0?   58  STO 06   59  X#0?   60  ST/ 06   61  X<> 06   62  ATAN   63  -   64  STO 04          65  RCL 02   66  STO 06   67  RCL 03   68  -   69  2   70  ST* 01   71  /   72  ENTER^   73  X^2   74  RCL 01   75  * 76  ST+ 00   77  RCL 02   78  RCL 03   79  *   80  SQRT   81  X<> 03   82  RCL 02   83  +   84  2   85  /   86  STO 02   87  RCL 04          88  SIN   89  R^   90  *   91  ST+ 05   92  RCL 02   93  RCL 06   94  X#Y?   95  GTO 01   96  RCL 04   97  RCL 02   98  /   99  RCL 01 100  / 101  D-R 102  STO 03 103  PI 104  RCL 02 105  ST+ X 106  / 107  ENTER^ 108  ST* 00 109  RCL 00        110  2 111  / 112  - 113  STO Z 114  X<>Y 115  / 116  RCL 03 117  * 118  RCL 05 119  + 120  RCL 03 121  X<>Y 122  END

( 148 bytes / SIZE 007 )

 STACK INPUTS OUTPUTS T / K ( m ) Z / E ( m ) Y m F ( v | m) X v ( degrees ) E ( v | m) L / Z ( v | m)

Z ( v | m)   is in the L-register only if m < 1

Examples:

1-If   v = 84° and m = 0.7

0.7 ENTER^
84 XEQ "ELI"  yields       E ( 84° | 0.7 ) = 1.184070048        ( in 16 seconds )
RDN       F ( 84° | 0.7 ) = 1.884976271
RDN               E ( 0.7 ) = 1.241670567
RDN               K ( 0.7 ) = 2.075363134
and        LASTX        Z ( 84° | 0.7 ) = 0.056306180

2-If   v = 84°  and m = 1

1 ENTER^
84 XEQ "ELI"  yields     E ( 84° | 1 ) = 0.994521895           ( in 2 seconds )
RDN      F ( 84° | 1 ) = 2.948700239
RDN              E ( 1 ) = 1
RDN              K ( 1 ) = 9.999999999E99    ( in fact infinity )

Complete Elliptic Integrals of the first and second kind:

-If you are only interested by the complete elliptic integrals,
here is a shorter and faster program to compute K ( m ) and E ( m ):

 01  LBL "CEI" 02  STO 00 03  SIGN 04  ENTER^ 05  STO 01        06  LASTX 07  - 08  SQRT 09  ENTER^ 10  LBL 01        11  CLX 12  RCL Z 13  RCL Y 14  - 15  2 16  ST* 01 17  / 18  X^2 19  RCL 01        20  * 21  ST+ 00 22  RDN 23  STO Z 24  STO T 25  X<>Y 26  ST* Z 27  + 28  2 29  / 30  X<>Y 31  SQRT 32  R^ 33  X#Y? 34  GTO 01        35  ST+ X 36  PI 37  X<>Y 38  / 39  ENTER^ 40  ST* 00 41  RCL 00        42  2 43  / 44  - 45  END

( 63 bytes / SIZE 002 )

 STACK INPUTS OUTPUTS T / K (m) Z / K (m) Y / K (m) X m* E (m)

* 0 < = m < 1

Example:

E ( 0.7 ) = 1.241670567   and
K ( 0.7 ) = 2.075363134   are obtained in 5 seconds.

2°) Carlson Elliptic Integrals

a) Carlson Elliptic Integrals of the first kind

a-1) Program#1

-Carlson has given a new definition of a standard elliptic integral of the first kind:

RF(x;y;z) =  (1/2) §0infinity  ( ( t + x ).( t + y ).( t + z ) ) -1/2 dt             with  x , y , z  non-negative and at most one is zero

-This program uses the following property:

RF(x;y;z) = RF((x+L)/4;(y+L)/4;(z+L)/4)  where  L = x1/2y1/2 + x1/2z1/2 + y1/2z1/2

-This transformation is performed until  x , y , z are close enough to apply  RF(x;y;z) = µ -1/2   with  µ = (x+y+z)/3     ( we have  RF(x;x;x) = x -1/2 )
-Actually, the iterations may be stopped earlier. Then, the function could be evaluated by a Taylor series.
-But this approach requires more bytes ( cf next paragraph ).

Data Registers:   R00 unused , R01 thru R03: temp
Flags: /
Subroutines: /

 01  LBL "RF" 02  XY 04  RDN 05  X>Y? 06  X<>Y 07  STO 01        08  X<> T 09  X>Y? 10  X<>Y 11  STO 02 12  X<>Y 13  STO 03 14  LBL 01 15  RCL 01 16  SQRT 17  RCL 02        18  SQRT 19  STO Z 20  RCL 03 21  SQRT 22  ST* T 23  + 24  * 25  + 26  ST+ 01         27  ST+ 02 28  ST+ 03 29  4 30  ST/ 01 31  ST/ 02 32  ST/ 03 33  RCL 03 34  RCL 01        35  ST- Y 36  RCL 02 37  RCL 03 38  + 39  + 40  / 41   E-5 42  X

( 68 bytes / SIZE 004 )

 STACK INPUTS OUTPUTS Z z / Y y / X x RF(x;y;z)

Example:

4  ENTER^
3  ENTER^
2  XEQ "RF"  >>>>  RF(2;3;4) = 0.584082842  ( in 10 seconds )

Degenerate Form

-Carson also defines   RC(x;y) = RF(x;y;y)  if y > 0
and  RC(x;y) = (x/(x-y))1/2 RC(x-y;-y)      if y < 0

Data Registers:   R00  thru R03: temp
Flags: /
Subroutine: "RF"

 01  LBL "RC"  02  1  03  STO 00  04  X<> Z  05  X>0?  06  GTO 00  07  X<>Y  08  STO 00  09  X<>Y  10  -  11  ST/ 00  12  LASTX  13  CHS  14  LBL 00  15  STO Z   16  X<>Y  17  XEQ "RF"  18  RCL 00  19  SQRT  20  *  21  END

( 35 bytes / SIZE 004 )

 STACK INPUTS OUTPUTS Y y / X x RC(x;y)

Examples:

3  ENTER^
1  XEQ "RC"  >>>>  RC(1;3) = 0.675510859   ( 11 seconds )

-3  ENTER^
1     R/S       >>>>   RC(1;-3) = 0.274653072   ( 10  seconds )

a-2) Program#2

-Now, "RF2" calculates  RF(x;y;z)  by the same method as "RF" but we stop the iterations when  Max { | X | , | Y | , | Z | } is smaller than 1/40
where  X = 1 - x/µ  ,  Y = 1 - y/µ  ,   Z = 1 - z/µ

-Then,   RF(x;y;z) =  ( 1 - E/10 + F/14 + E2/24 - 3 E.F/44 ) µ -1/2    with  E = XY - Z2   and  F = X.Y.Z

Data Registers:   R00 thru R05: temp
Flags: /
Subroutines: /

 01  LBL "RF2" 02  STO 01 03  RDN 04  STO 02 05  X<>Y 06  STO 03 07  40 08  1/X 09  STO 04 10  LBL 01 11  RCL 01        12  SQRT 13  RCL 02 14  SQRT 15  STO Z 16  RCL 03 17  SQRT 18  ST* T 19  + 20  * 21  + 22  ST+ 01 23  ST+ 02 24  ST+ 03 25  4 26  ST/ 01 27  ST/ 02 28  ST/ 03 29  RCL 01        30  RCL 02 31  RCL 03 32  + 33  + 34  3 35  / 36  STO 00 37  RCL 03 38  - 39  RCL 00 40  / 41  STO 05 42  ABS 43  RCL 04 44  X

( 118 bytes / SIZE 006 )

 STACK INPUTS OUTPUTS Z z / Y y / X x RF(x;y;z)

Example:

4  ENTER^
2  ENTER^
1  XEQ "RF2"  >>>>  RF(1,2,4) = 0.685085817  ( in 6 seconds )

b) Carlson Elliptic Integrals of the second kind

-They are only a degenerate form of the integrals of the third kind   RD(x;y;z) = RJ(x;y;z;z)    ( cf c) for RJ )

 01  LBL "RD"  02  0  03  +  04  XEQ "RJ"  05  END

( 15 bytes / SIZE 013 )

 STACK INPUTS OUTPUTS Z z / Y y / X x RD(x;y;z)

Example:

4  ENTER^
3  ENTER^
2  XEQ "RD"  >>>>  RD(2;3;4) = 0.165105273    ( 30 seconds )

-However, Carlson has also defined a  symmetric Elliptic Integral of the second kind:

RG(x;y;z) =  (1/4)  §0infinity  ( ( t + x ).( t + y ).( t + z ) ) -1/2 .( x/(t+x) + y/(t+y) + z/(t+z) )  t.dt

And we have:  2.RG(x;y;z) = z.RF(x;y;z) - (x-z)(y-z)/3 RD(x;y;z) + ( x.y/z )1/2

Data Registers:   R00  thru R04: temp
Flags: /
Subroutines:  The M-code functions RF & RJ  or "RF" & "RJ" ...  In this case, use other registers to avoid a register usage conflict.

 01  LBL "RG" 02  STO 01 03  RDN 04  STO 02 05  X<>Y 06  STO 03        07  R^ 08  RF 09  RCL 01 10  SQRT 11  RCL 02        12  SQRT 13  * 14  RCL 03 15  ST* Z 16  SQRT 17  / 18  + 19  STO 00        20  RCL 03 21  RCL 03 22  RCL 02 23  RCL 01 24  RJ 25  RCL 03 26  RCL 01        27  - 28  * 29  RCL 02 30  RCL 03 31  - 32  * 33  3 34  / 35  RCL 00        36  + 37  2 38  / 39  END

( 49 bytes / SIZE 004 )

 STACK INPUTS OUTPUTS Z z / Y y / X x RG(x;y;z)

Example:

4  ENTER^
3  ENTER^
2  XEQ "RG"  >>>>  RG(2;3;4) = 1.725503028  ( in 15 seconds )

-If  one of the arguments is zero, do not place it in  Z-register ( there would be a DATA ERROR line 17 )
Or add   X#0?   X<>Y  after line 03.

c) Carlson Elliptic Integrals of the third kind

c-1) Program#1

-The elliptic integral of the third kind is defined by

RJ(x;y;z;p) =  (3/2)  §0infinity  ( t + p ) -1  ( ( t + x ).( t + y ).( t + z ) ) -1/2  dt        with  x , y , z  non-negative and at most one is zero    p > 0

-We have  RJ(x,x,x,x) = x -3/2
-The following program applies  RJ(x;y;z;p) = 3 Sumn=0,1,2,....,k  RF(an,bn,bn)/4n + 1/(4k+1µ 3/2)

where   x0 = x , y0 = y , z0 = z , p0 = p        ;      xn+1 = ( xn+ Ln )/4 , yn+1 = ( yn+ Ln )/4 , zn+1 = ( zn + Ln )/4 , pn+1 = ( pn +Ln )/4

with    Ln = xn1/2yn1/2 + xn1/2zn1/2 + yn1/2zn1/2
an = ( pn( xn1/2 + yn1/2 + zn1/2 ) + ( xnynzn )1/2 )2    ;   bn = pn ( pn + Ln )2

and    µ = (xk+1+yk+1+zk+1+2pk+1)/5

-The iterations stop when  xn , yn , zn , pn  are close enough to produce a good accuracy.
-This program also computes the Cauchy principal value of the integral if  p < 0

Data Registers:   R00  thru R12: temp
Flags: /
Subroutines: "RF" & "RC"

 01  LBL "RJ'"   02  XY   04  RDN   05  X>Y?   06  X<>Y   07  STO 04          08  X<> T   09  XY   11  STO 06   12  X<>Y   13  STO 05   14  ST- Y   15  R^   16  -   17  *   18  RCL 05   19  R^   20  STO 07   21  1   22  STO 08   23  STO 09   24  STO 10   25  CLX   26  STO 11   27  STO 12 28  RDN   29  X>0?   30  GTO 01   31  -   32  STO 09   33  /   34  STO 10          35  RCL 05   36  +   37  ENTER^   38  X<> 07   39  *   40  RCL 04   41  RCL 06   42  *   43  RCL 05   44  ST/ Z   45  /   46  XEQ "RC"   47  STO 11   48  RCL 06   49  RCL 05   50  RCL 04   51  XEQ "RF"   52  ST- 11   53  LBL 01   54  RCL 04 55  SQRT   56  ENTER^   57  STO 01   58  RCL 05   59  SQRT   60  ST* Z   61  STO 02   62  RCL 06          63  SQRT   64  ST* T   65  ST* 02   66  +   67  ST* 01   68  +   69  RCL 07   70  *   71  +   72  X^2   73  RCL 07   74  RCL 01   75  RCL 02   76  +   77  ST+ 04   78  ST+ 05   79  ST+ 06   80  RCL 07   81  + 82  STO 07   83  X^2   84  *   85  ENTER^   86  XEQ "RF"   87  RCL 08          88  *   89  ST+ 12   90  4   91  ST/ 04   92  ST/ 05   93  ST/ 06   94  ST/ 07   95  ST/ 08   96  RCL 07   97  RCL 06   98  -   99  ABS 100  RCL 04 101  ST- Y 102  RCL 05 103  + 104  RCL 06 105  ST+ Z 106  + 107  RCL 07 108  ST+ X 109  + 110  / 111   E-5 112  X

( 175 bytes / SIZE 013 )

 STACK INPUTS OUTPUTS T p#0 / Z z / Y y / X x RJ(x;y;z;p)

Examples:

4  ENTER^
3  ENTER^
2  ENTER^
1  XEQ "RJ"  >>>>  RJ(1;2;3;4) = 0.239848100   ( in 42 seconds )

-4  ENTER^
3  ENTER^
2  ENTER^
1     R/S        >>>>  RJ(1;2;3;-4) =  -0.237867695  ( in 58 seconds )

Note:

-The Cauchy principal value of  RJ(x;y;z;p)  has a zero for some p < 0  and a loss of significant digits is to be expected near the zero:

-For instance,  RJ(1;2;3;p) = 0  for p = -0.775227.......

and this program gives  RJ(1;2;3;-0.775227) = 8.4498 10-8

Line131 adds  0.1220082998  and  -0.1220080653   Therefore,  the result has probably no more than 2 or 3 significant figures.

c-2) Program#2

-This new program computes  RJ(x;y;z;p)  for p>0  only.
-Instead of calling "RF" as a subroutine, it calculates RF(a,b,b)  directly by the formulae:

RF(a,b,b) = ( a - b ) -1/2  Arctanh ( 1-b/a )1/2     if   a > b
RF(a,b,b) =   a -1/2                                             if   a = b
RF(a,b,b) = ( b - a ) -1/2  Arctan ( b/a - 1 )1/2      if   a < b

-So, it is much faster.

Data Registers:   R00 thru R08: temp
Flags: /
Subroutines: /

-Line 117 is a three-byte GTO 01

 01  LBL "RJ2"   02  STO 01   03  RDN   04  STO 02   05  RDN   06  STO 03   07  X<>Y   08  STO 04   09  CLX   10  STO 00          11  STO 08   12  SIGN   13  STO 07   14  RAD   15  LBL 01   16  RCL 01   17  SQRT   18  ENTER^   19  STO 05   20  RCL 02   21  SQRT   22  ST* Z   23  STO 06   24  RCL 03 25  SQRT   26  ST* T   27  ST* 06   28  +   29  ST* 05   30  +   31  RCL 04          32  *   33  +   34  X^2   35  RCL 04   36  RCL 05   37  RCL 06   38  +   39  ST+ 01   40  ST+ 02   41  ST+ 03   42  RCL 04   43  +   44  STO 04   45  X^2   46  *   47  X=Y?   48  GTO 02 49  -   50  X<0?   51  GTO 03   52  STO 05          53  X<>Y   54  /   55  SQRT   56  ENTER^   57  ST+ Y   58  SIGN   59  LASTX   60  -   61  /   62  LN1+X   63  2   64  /   65  GTO 04   66  LBL 02   67  SQRT   68  1/X   69  GTO 05   70  LBL 03   71  CHS   72  STO 05 73  X<>Y   74  /   75  SQRT   76  ATAN   77  LBL 04   78  RCL 05          79  SQRT   80  /   81  LBL 05   82  RCL 07   83  *   84  ST+ 00   85  4   86  ST/ 01   87  ST/ 02   88  ST/ 03   89  ST/ 04   90  ST/ 07   91  RCL 08   92  RCL 07   93  RCL 01   94  RCL 02   95  +   96  RCL 03 97  +   98  RCL 04          99  ST+ X 100  + 101  5 102  / 103  ENTER^ 104  SQRT 105  * 106  / 107  RCL 00 108  3 109  * 110  + 111  STO 08 112  ST- Y 113  / 114  ABS 115  2 E-9 116  X

( 153 bytes / SIZE 009 )

 STACK INPUTS OUTPUTS T p>0 / Z z / Y y / X x RJ(x;y;z;p)

Example:

4  ENTER^
3  ENTER^
2  ENTER^
1  XEQ "RJ2"  >>>>  RJ(1;2;3;4) = 0.239848100   ( in 22 seconds - instead of 42 with "RJ" )

-The iterations stop when 2 consecutive results are nearly equal.

c-3) Program#3

-Let    X = 1 - x/µ  ,  Y = 1 - y/µ  ,  Z = 1 - z/µ  ,  P = 1 - p/µ

-"RJ3" stops the iterations when   Max { | X | , | Y | , | Z | , | P | } is smaller than 1/67

-Then,  RJ(x;y;z;p) = 3 Sumn=0,1,2,....,k  RF(an,bn,bn)/4n + (1+eps)/(4k+1µ 3/2)

where  eps = -3.E/14 + F/6 + 9.E2/88 - 3.G/22 - 9.E.F/52 + 3.H/26

with        E = X.(Y+Z) + Y.Z - 3.P2          G = ( 2.X.Y.Z + E.P + 3.P3 ).P
and         F = X.Y.Z + 2.E.P + 4.P3           H = X.Y.Z.P2

Data Registers:   R00 thru R11: temp
Flags: /
Subroutines: /

-Lines 112-122-132-142 are three-byte GTO 01

 01  LBL "RJ3"   02  STO 01   03  RDN   04  STO 02   05  RDN   06  STO 03   07  X<>Y   08  STO 04   09  CLX   10  STO 00   11  SIGN   12  STO 07   13  67   14  1/X   15  STO 08           16  RAD   17  LBL 01   18  RCL 01   19  SQRT   20  ENTER^   21  STO 05   22  RCL 02   23  SQRT   24  ST* Z   25  STO 06   26  RCL 03   27  SQRT   28  ST* T   29  ST* 06   30  +   31  ST* 05   32  +   33  RCL 04   34  *   35  +   36  X^2   37  RCL 04 38  RCL 05   39  RCL 06   40  +   41  ST+ 01   42  ST+ 02   43  ST+ 03   44  RCL 04   45  +   46  STO 04   47  X^2   48  *   49  X=Y?   50  GTO 02   51  -   52  X<0?   53  GTO 03   54  STO 05           55  X<>Y   56  /   57  SQRT   58  ENTER^   59  ST+ Y   60  SIGN   61  LASTX   62  -   63  /   64  LN1+X   65  2   66  /   67  GTO 04   68  LBL 02   69  SQRT   70  1/X   71  GTO 05   72  LBL 03   73  CHS   74  STO 05 75  X<>Y   76  /   77  SQRT   78  ATAN   79  LBL 04   80  RCL 05   81  SQRT   82  /   83  LBL 05   84  RCL 07   85  *   86  ST+ 00   87  4   88  ST/ 01   89  ST/ 02   90  ST/ 03   91  ST/ 04   92  ST/ 07   93  RCL 01           94  RCL 02   95  +   96  RCL 03   97  +   98  RCL 04   99  ST+ X 100  + 101  5 102  / 103  STO 05 104  RCL 01 105  - 106  RCL 05 107  / 108  STO 06 109  ABS 110  RCL 08 111  X 06 148  ST* 06 149  RCL 09 150  LASTX 151  * 152  ST+ 06 153  * 154  STO 09 155  RCL 11 156  X^2 157  STO 10 158  3 159  * 160  ST- 06 161  RCL 10 162  ST+ X 163  RCL 06 164  + 165  RCL 11         166  * 167  ST+ X 168  RCL 09 169  + 170  STO 08 171  LASTX 172  + 173  RCL 06 174  RCL 10 175  ST* 09 176  + 177  RCL 11 178  * 179  - 180  ST* 11 181  RCL 06 182  88 183  / 184  RCL 08 185  52 186  / 187  - 188  3 189  * 190  14 191  1/X 192  - 193  RCL 06 194  * 195  RCL 09 196  26 197  / 198  + 199  RCL 11         200  22 201  / 202  - 203  3 204  * 205  RCL 08 206  6 207  / 208  + 209  RCL 07 210  ST* Y 211  + 212  RCL 05 213  ENTER^ 214  SQRT 215  * 216  / 217  RCL 00 218  3 219  * 220  + 221  END

( 271 bytes / SIZE 012 )

 STACK INPUTS OUTPUTS T p>0 / Z z / Y y / X x RJ(x;y;z;p)

Example:

4  ENTER^
3  ENTER^
2  ENTER^
1  XEQ "RJ3"  >>>>  RJ(1,2,3,4) = 0.239848100  ( in 14 seconds )

RJ(1,2,4,7) = 0.147854445  is obtained in 17 seconds.

-The execution time increases when x , y , z , p  have huge ratios.

d) Complex Arguments

d-1) Elliptic Integrals of the first kind

d-1a) Program#1

-This program computes  RF ( x , y+i.z , y-i.z )
-This is not most the general case, but it's useful when the radicand has one real root and a pair of complex conjugate roots.

Data Registers:   R00 unused  R01 thru R03: temp
Flags: /
Subroutines: /

 01  LBL "RFZ" 02  STO 01        03  RDN 04  STO 02 05  X<>Y 06  ABS 07  STO 03 08  LBL 01 09  RCL 03 10  RCL 02        11  R-P 12  STO Y 13  LASTX 14  + 15  ST+ X 16  SQRT 17  RCL 01 18  SQRT 19  * 20  + 21  ST+ 01 22  ST+ 02 23  4 24  ST/ 01 25  ST/ 02 26  ST/ 03 27  RCL 03 28  RCL 02 29  RCL 01 30  - 31  ABS 32  + 33  RCL 01        34  RCL 02 35  ST+ X 36  + 37  / 38   E-5 39  X

( 64 bytes / SIZE 004 )

 STACK INPUTS OUTPUTS Z z / Y y / X x RF(x,y+iz,y-iz)

Example:

4  ENTER^
3  ENTER^
2  XEQ "RFZ"  >>>>  RF ( 2 , 3+4i , 3-4i ) = 0.543421944    ( in 14 seconds )

d-1b) Program#2

-This routine uses the same series expansion as "RF2"

Data Registers:   R00 thru R05: temp
Flags: /
Subroutines: /

 01  LBL "RFZ2" 02  STO 01  03  RDN 04  STO 02        05  X<>Y 06  STO 03 07  40 08  1/X 09  STO 04 10  LBL 01 11  RCL 03 12  RCL 02 13  R-P 14  STO Y 15  LASTX 16  + 17  ST+ X 18  SQRT 19  RCL 01        20  SQRT 21  * 22  + 23  ST+ 01 24  ST+ 02 25  4 26  ST/ 01 27  ST/ 02 28  ST/ 03 29  RCL 01 30  RCL 02 31  ST+ X 32  + 33  3 34  / 35  STO 00 36  RCL 01        37  - 38  RCL 00 39  / 40  STO 05 41  ABS 42  RCL 04 43  XY 61  - 62  STO 04 63  24 64  / 65  .1 66  - 67  RCL 05 68  3 69  * 70  44 71  / 72  - 73  RCL 04        74  * 75  RCL 05 76  14 77  / 78  + 79  1 80  + 81  RCL 00 82  SQRT 83  / 84  END

( 110 bytes / SIZE 006 )

 STACK INPUTS OUTPUTS Z z / Y y / X x RF(x,y+iz,y-iz)

Example:

4  ENTER^
2  ENTER^
1  XEQ "RFZ2"  >>>>  RF ( 1 , 2+4i , 2-4i ) = 0.631488738    ( in 11 seconds )

d-2) Elliptic Integrals of the third kind

-The 3 following programs compute  RJ ( x , y+i.z , y-i.z , p )  with  p > 0

d-2a) Program#1

Data Registers:   R00 unused  R01 thru R09: temp  ( R09 may be replaced by R00 )
Flags: /
Subroutine:  "RF"

 01  LBL "RJZ" 02  STO 04  03  RDN 04  STO 05 05  RDN 06  ABS 07  STO 06        08  X<>Y 09  STO 07 10  CLX 11  STO 08 12  SIGN 13  STO 09 14  LBL 01 15  RCL 06 16  RCL 05 17  R-P 18  ENTER^ 19  STO Z 20  LASTX 21  + 22  ST+ X 23  SQRT 24  STO 01  25  RCL 04        26  SQRT 27  ST* T 28  ST+ 01 29  * 30  + 31  ST+ 04 32  ST+ 05 33  X<> 07 34  ST+ 07 35  ENTER^ 36  X<> 01 37  * 38  + 39  X^2 40  RCL 01 41  RCL 07        42  X^2 43  * 44  ENTER^ 45  XEQ "RF" 46  RCL 09 47  * 48  ST+ 08 49  4 50  ST/ 04 51  ST/ 05 52  ST/ 06 53  ST/ 07 54  ST/ 09 55  RCL 05 56  RCL 07 57  - 58  ABS 59  RCL 06        60  + 61  RCL 04  62  RCL 05 63  - 64  ABS 65  + 66  RCL 04 67  RCL 05 68  RCL 07 69  + 70  ST+ X 71  + 72  / 73   E-5 74  X

( 118 bytes / SIZE 010 )

 STACK INPUTS OUTPUTS T p>0 / Z z / Y y / X x RJ(x,y+iz,y-iz,p)

Example:

4  ENTER^
3  ENTER^
2  ENTER^
1  XEQ "RJZ"  >>>>  RJ ( 1 , 2+3i , 2-3i , 4 ) = 0.205644141   ( in 46 seconds )

d-2b) Program#2

-Like "RJ2" this routine calculates RF(a,b,b)  directly, without calling "RF"

Data Registers:   R00 thru R07: temp
Flag:   F10
Subroutines:  /

-Lines 115 & 117 are three-byte GTO 01

 01  LBL "RJZ2"   02  STO 01    03  RDN   04  STO 02   05  RDN   06  STO 03   07  X<>Y   08  STO 04   09  CLX   10  STO 00   11  STO 06          12  SIGN   13  STO 07   14  RAD   15  SF 10   16  LBL 01   17  RCL 03   18  RCL 02   19  R-P   20  ENTER^   21  STO Z   22  LASTX   23  +   24  ST+ X 25  SQRT   26  STO 05    27  RCL 01   28  SQRT   29  ST* T   30  ST+ 05   31  *   32  +   33  ST+ 01   34  ST+ 02   35  X<> 04   36  ST+ 04   37  ENTER^   38  X<> 05   39  *   40  +   41  X^2   42  RCL 05          43  RCL 04   44  ENTER^   45  *   46  *   47  X=Y?   48  GTO 02 49  -   50  X<0?   51  GTO 03   52  STO 05          53  X<>Y   54  /   55  SQRT   56  ENTER^   57  ST+ Y   58  SIGN   59  LASTX   60  -   61  /   62  LN1+X   63  2   64  /   65  GTO 04   66  LBL 02   67  SQRT   68  1/X   69  GTO 05   70  LBL 03   71  CHS   72  STO 05 73  X<>Y   74  /   75  SQRT   76  ATAN   77  LBL 04   78  RCL 05          79  SQRT   80  /   81  LBL 05   82  RCL 07   83  *   84  ST+ 00   85  4   86  ST/ 01   87  ST/ 02   88  ST/ 03   89  ST/ 04   90  ST/ 07   91  RCL 06   92  RCL 07   93  RCL 02   94  RCL 04   95  +   96  ST+ X 97  RCL 01   98  +   99  5 100  / 101  ENTER^ 102  SQRT 103  * 104  / 105  RCL 00        106  3 107  * 108  + 109  STO 06 110  ST- Y 111  / 112  ABS 113  2 E-9 114  X

( 160 bytes / SIZE 008 )

 STACK INPUTS OUTPUTS T p>0 / Z z / Y y / X x RJ(x,y+iz,y-iz,p)

Example:

4  ENTER^
3  ENTER^
2  ENTER^
1  XEQ "RJZ2"  >>>>  RJ ( 1 , 2+3i , 2-3i , 4 ) = 0.205644141   ( in 26 seconds - instead of 46 seconds with "RJZ" )

-It may happen that 2 consecutive approximations are nearly equal too early,
so we use a flag to prevent a premature stop!

d-3b) Program#3

-"RJZ3" uses the same series expansion and the same termination criterion as "RJ3"

Data Registers:   R00 thru R11: temp
Flags: /
Subroutines: /

-Lines 109-121-131 are three-byte GTO 01

 01  LBL "RJZ3"   02  STO 01    03  RDN   04  STO 02   05  RDN   06  STO 03   07  X<>Y   08  STO 04   09  CLX   10  STO 00          11  SIGN   12  STO 07   13  67   14  1/X   15  STO 08   16  RAD   17  LBL 01   18  RCL 03   19  RCL 02   20  R-P   21  ENTER^   22  STO Z   23  LASTX   24  +   25  ST+ X   26  SQRT   27  STO 05   28  RCL 01   29  SQRT   30  ST* T   31  ST+ 05   32  *   33  +   34  ST+ 01   35  ST+ 02   36  X<> 04 37  ST+ 04   38  ENTER^   39  X<> 05    40  *   41  +   42  X^2   43  RCL 05   44  RCL 04          45  ENTER^   46  *   47  *   48  X=Y?   49  GTO 02   50  -   51  X<0?   52  GTO 03   53  STO 05   54  X<>Y   55  /   56  SQRT   57  ENTER^   58  ST+ Y   59  SIGN   60  LASTX   61  -   62  /   63  LN1+X   64  2   65  /   66  GTO 04   67  LBL 02   68  SQRT   69  1/X   70  GTO 05   71  LBL 03   72  CHS 73  STO 05    74  X<>Y   75  /   76  SQRT   77  ATAN   78  LBL 04   79  RCL 05          80  SQRT   81  /   82  LBL 05   83  RCL 07   84  *   85  ST+ 00   86  4   87  ST/ 01   88  ST/ 02   89  ST/ 03   90  ST/ 04   91  ST/ 07   92  RCL 01   93  RCL 02   94  RCL 04   95  +   96  ST+ X   97  +   98  5   99  / 100  STO 05 101  RCL 01 102  - 103  RCL 05 104  / 105  STO 06 106  ABS 107  RCL 08 108  X 06 140  ST* 06 141  RCL 09 142  X^2 143  ST+ 06 144  * 145  STO 09 146  RCL 11  147  X^2 148  STO 10        149  3 150  * 151  ST- 06 152  RCL 10 153  ST+ X 154  RCL 06 155  + 156  RCL 11 157  * 158  ST+ X 159  RCL 09 160  + 161  STO 08 162  LASTX 163  + 164  RCL 06 165  RCL 10 166  ST* 09 167  + 168  RCL 11 169  * 170  - 171  ST* 11 172  RCL 06 173  88 174  / 175  RCL 08 176  52 177  / 178  - 179  3 180  * 181  14 182  1/X 183  - 184  RCL 06        185  * 186  RCL 09 187  26 188  / 189  + 190  RCL 11 191  22 192  / 193  - 194  3 195  * 196  RCL 08 197  6 198  / 199  + 200  RCL 07 201  ST* Y 202  + 203  RCL 05 204  ENTER^ 205  SQRT 206  * 207  / 208  RCL 00 209  3 210  * 211  + 212  END

( 264 bytes / SIZE 012 )

 STACK INPUTS OUTPUTS T p>0 / Z z / Y y / X x RJ(x,y+iz,y-iz,p)

Example:

7  ENTER^
4  ENTER^
2  ENTER^
1  XEQ "RJZ3"  >>>>  RJ ( 1 , 2+4i , 2-4i , 7 ) = 0.126039065   ( in 18 seconds )

e) Micro-Code Functions

e-1) Integrals of the first kind - real & complex

086    "F"
012    "R"
104    CLRF8                  The first executable word of RF
244    CLRF9
00E    A=0  ALL
2EE    ?C#0?  ALL
04F    JC+09
166    A=A+1  S&X
03B    JNC+07
09A   "Z"
006    "F"
012    "R"
108    SETF8                  The first executable word of RFZ
248    SETF9
00E    A=0  ALL            We first check that no more than 1 argument  ( among  x , y , z  for RF or  x , x+iy , x-iy  for RFZ )  equals zero
2EE    ?C#0?  ALL
017    JC+02
166    A=A+1  S&X
2EE    ?C#0?  ALL
017    JC+02
166    A=A+1  S&X
130    LDI S&X
002    002
306    ?A<C  S&X
0B5   ?NCGO               otherwise we get DATA ERROR
0A2    282D
0F8    READ3(X)          these 8 words check for alpha data in registers X , Y , Z and execute SETDEC
361    ?NCXQ              If you don't want to check for alpha data, replace them ( 0F8  361  050  0B8  10E  078  355  050  )
050    14D8                   by  2A0    SETDEC
10E    A=C  ALL
355    ?NCXQ
050    14D5
04E    C=0  ALL
028    WRIT0(T)
0F8    READ3(X)      loop       This loop begins at the address F1A7  in my ROM , you'll have to change the ?NCGOs written in red ( near the end )
2F9    ?NCXQ            C=                                                                                       if you store this word at another address in your own ROM
060    18BE                 sqrt(C)
128    WRIT4(L)
10C   ?FSET8
097    JC+18d
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
070    N=C  ALL
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
268    WRIT9(Q)
10E    A=C  ALL
0B0    C=N  ALL
135    ?NCXQ           C=
060    184D               A*C
0F0    C<>N  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
0CB    JNC+25d
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
070    N=C  ALL
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
0B0    C=N  ALL
01D    ?NCXQ          C=
060     1807               A+C
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
070    N=C  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
0B0    C=N  ALL
01D    ?NCXQ          C=
060     1807               A+C
070    N=C  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
04E    C=0  ALL        C
35C    PT=12             =
110    LD@PT-4        4
128    WRIT4(L)
261    ?NCXQ           C=
060    1898                A/C
0A8    WRIT2(Y)
0B0    C=N  ALL
10E    A=C  ALL
10C    ?FSET8
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
261    ?NCXQ           C=
060    1898                A/C
068    WRIT1(Z)
0B0    C=N  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
261    ?NCXQ           C=
060    1898                A/C
0E8    WRIT3(X)
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
10C    ?FSET8
013    JNC+02
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
046    C=0 S&X        C
270    RAMSLCT      =
2BE    C=-C-1 MS    C=-C
0AE    A<>C
028    WRIT0(T)
070    N=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
0B0    C=N  ALL
261    ?NCXQ           C=
060    1898                A/C
05E    C=0 MS          C= | C |
10E    A=C  ALL
04E    C=0                 |
2BE    C=-C-1 MS    |
35C    PT=12            |
090    LD@PT-2       |      C = -2 E-9
21C    PT=2              |
250    LD@PT-9      |
250    LD@PT-9      |
050    LD@PT-1      |
01D    ?NCXQ          C=
060     1807               A+C
2FE    ?C#0 MS
29D    ?NCGO         if not carry goto
3C6    F1A7             loop
24C    ?FSET9
023    JNC+04
244    CLRF9
29D    ?NCGO         if not carry goto
3C6    F1A7             loop
04E    C=0               C
35C    PT=12           =
0D0    LD@PT-3     3
10E    A=C  ALL
270    RAMSLCT      C=
261    ?NCXQ           C=
060    1898                A/C
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
0E8    WRIT3(X)
3E0    RTN

 RF STACK INPUTS OUTPUTS Z z / Y y / X x RF(x,y,z)

Example:

4  ENTER^
2  ENTER^
1  XEQ "RF" yields  RF(1,2,4) = 0.685085816  ( in 4.5 seconds )

 RFZ  STACK INPUTS OUTPUTS Z z / Y y / X x RF(x,y+iz,y-iz)

Example:

4  ENTER^
2  ENTER^
1  XEQ "RFZ"  gives  RF ( 1 , 2+4i , 2-4i ) = 0.631488738    ( in 5.5 seconds )

-The execution time may be longer if the arguments have huge ratios.
-For instance:  RF(0,10 -70,1080) =  1.740801762 10 -38   is obtained in 9 seconds

-There will be a DATA ERROR if  x , y , z < 0 ( with RF )  or  x < 0  ( with RFZ )
-Space can be saved if you don't check for zero-arguments...
-In this case, there will be an infinite loop if you execute RF with x = y = 0 and z # 0  or if you execute RFZ with y = z = 0
press  ENTER^  ON to stop the loop with a "newest" HP-41
-On older HP-41s, insert

3CC   ?KEY
360    ?C RTN    at the beginning of the loop: any infinite loop will be stopped by pressing any key for 1 second.

-RF & RFZ  do not use any data register and the alpha registers are undisturbed
-However, RF uses the "scratch" register Q

-The routine stops when 2 consecutive approximations are nearly equal ( CPU-flag9 is also used by RFZ to avoid a premature stop ).
-You can certainly write a faster function if you use the method of "RF2" & "RFZ2":
the number of iterations will be reduced, but the series expansion needs several extra words.

e-2) Integrals of the third kind - real & complex

08A    "J"
012    "R"
104    CLRF8                  The first executable word of RJ
244    CLRF9
00E    A=0  ALL
2EE    ?C#0?  ALL
04F    JC+09
166    A=A+1  S&X
03B    JNC+07
09A   "Z"
00A    "J"
012    "R"
108    SETF8                  The first executable word of RJZ
248    SETF9
00E    A=0  ALL            We check that no more than 1 argument  ( among  x , y , z  for RJ or  x , x+iy , x-iy  for RJZ )  equals zero
2EE    ?C#0?  ALL
017    JC+02
166    A=A+1  S&X
2EE    ?C#0?  ALL
017    JC+02
166    A=A+1  S&X
130    LDI S&X
002    002
306    ?A<C  S&X
0B5   ?NCGO               otherwise we get DATA ERROR
0A2    282D
0F8    READ3(X)          these 12 words check for alpha data in registers X , Y , Z , T  execute SETDEC and return T in C
10E    A=C  ALL          If you don't want to check for alpha data, replace them ( 0F8  10E  0B8  355  050  046  270  038  10E  078  355  050  )
355    ?NCXQ                    046    C=0 S&X
050    14D5                        270    RAMSLCT
270    RAMSLCT
10E    A=C  ALL
355    ?NCXQ
050    14D5
228    WRIT8(P)
04E    C=0
028    WRIT0(T)
268    WRIT9(Q)
35C    PT=12             C=
050    LD@PT-1        1
1E8    WRIT7(O)
0F8    READ3(X)      loop       This loop begins at the address FAD4  in my ROM , you'll have to change the ?NCGOs written in red ( near the end )
2F9    ?NCXQ           C=                                                                                               if you store this word at another address in your own ROM
060    18BE                sqrt(C)
168    WRIT5(M)
10C    ?FSET8
10F    JC+33d
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
1A8    WRIT6(N)
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
128    WRIT4(L)
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
070    N=C  ALL
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
0F0    C<>N  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
0AE    A<>C  ALL
1A8    WRIT6(N)
135    ?NCXQ           C=
060    184D               A*C
128    WRIT4(L)
10E    A=C  ALL
0B0    C=N  ALL
133    JNC+38d
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
070    N=C  ALL
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
0B0    C=N  ALL
01D    ?NCXQ          C=
060     1807               A+C
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
128    WRIT4(L)
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
070    N=C  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
1A8    WRIT6(N)
10E    A=C  ALL
0B0    C=N  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
070    N=C  ALL
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
168    WRIT5(M)
0B0    C=N  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
04E    C=0  ALL        C
35C    PT=12             =
110    LD@PT-4        4
128    WRIT4(L)
261    ?NCXQ           C=
060    1898                A/C
0E8    WRIT3(X)
0B0    C=N  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
261    ?NCXQ           C=
060    1898                A/C
0A8    WRIT2(Y)
0B0    C=N  ALL
10E    A=C  ALL
10C    ?FSET8
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
261    ?NCXQ           C=
060    1898                A/C
068    WRIT1(Z)
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
168    WRIT5(M)
0B0    C=N  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
070    N=C  ALL
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
1A8    WRIT6(N)
0B0    C=N  ALL
10E    A=C  ALL
261    ?NCXQ           C=
060    1898                A/C
228    WRIT8(P)
2BE    C=-C-1 MS    C=-C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
1A8    WRIT6(N)       then the HP41 calculates RF(a,b,b) according to the sign of  a-b
2EE    ?C#0  ALL
1F3    JNC+62d
2FE    ?C#0  MS
09B    JNC+19d
05E    C=0 MS          C= | C |
10E    A=C  ALL
1A8    WRIT6(N)
261    ?NCXQ           C=
060    1898                A/C
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
070    N=C  ALL
130    LDI S&X         The 8 following words calculate ATAN in radians without disturbing the current angular mode
090    090
358    ST=C XP
144    CLRF6
284    CLRF7
0B0    C=N  ALL
205    ?NCXQ           C=
040    1081                Atan(C)
103    JNC+32d
10E    A=C  ALL
261    ?NCXQ           C=
060    1898                A/C
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
168    WRIT5(M)
2BE    C=-C-1 MS    C=-C
00E    A=0  ALL        A
35C    PT=12             =
162    A=A+1@PT    1
01D    ?NCXQ          C=
060     1807               A+C
070    N=C  ALL
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
0B0    C=N  ALL
261    ?NCXQ           C=
060    1898                A/C
084    CLRF5            C
1CD   ?NCXQ          =
06C    1B73              LN1+C
10E    A=C  ALL
04E    C=0  ALL        C
35C    PT=12             =
090    LD@PT-2        2
261    ?NCXQ           C=
060    1898                A/C               now, we have  atanh ((a-b)/a)^(1/2)
070    N=C  ALL
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
10E    A=C  ALL
0B0    C=N  ALL
0AE   A<>C  ALL
261    ?NCXQ           C=
060    1898                A/C
033    JNC+06
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
22D   ?NCXQ           C=
060    188B                1/C
10E    A=C  ALL
04E    C=0  ALL        C
35C    PT=12             =
0D0    LD@PT-3       3
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
268    WRIT9(Q)
10E    A=C  ALL
261    ?NCXQ           C=
060    1898                A/C
1E8    WRIT7(O)
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
10C    ?FSET8
013    JNC+02
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
04E    C=0  ALL        C
35C    PT=12             =
150    LD@PT-5        5
261    ?NCXQ           C=
060    1898                A/C
128    WRIT4(L)
2F9    ?NCXQ           C=
060    18BE                sqrt(C)
10E    A=C  ALL
135    ?NCXQ           C=
060    184D               A*C
10E    A=C  ALL
0AE   A<>C  ALL
261    ?NCXQ           C=
060    1898                A/C
10E    A=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
046    C=0 S&X        C
270    RAMSLCT      =
2BE    C=-C-1 MS    C=-C
0AE    A<>C
028    WRIT0(T)
070    N=C  ALL
01D    ?NCXQ          C=
060     1807               A+C
10E    A=C  ALL
0B0    C=N  ALL
261    ?NCXQ           C=
060    1898                A/C
05E    C=0 MS          C= | C |
10E    A=C  ALL
04E    C=0                 |
2BE    C=-C-1 MS    |
35C    PT=12            |
090    LD@PT-2       |      C = -2 E-9
21C    PT=2              |
250    LD@PT-9      |
250    LD@PT-9      |
050    LD@PT-1      |
01D    ?NCXQ          C=
060     1807               A+C
2FE    ?C#0 MS
351    ?NCGO          if not carry goto
24C    ?FSET9
023    JNC+04
244    CLRF9
351    ?NCGO          if not carry goto
3B5    ?NCXQ         if not carry
050    14ED              R^
345    ?NCXQ         if not carry
040    10D1             CLA ( clears the alpha registers M N O P )
331    ?NCGO        checks for
002    00CC            underflow/overflow

 RJ  STACK INPUTS OUTPUTS T p>0 / Z z / Y y / X x RJ(x;y;z;p)

Example:

7  ENTER^
4  ENTER^
2  ENTER^
1  XEQ "RJ"  yields   RJ(1,2,4,7) = 0.147854445   ( in 9.6 seconds )

 RJZ  STACK INPUTS OUTPUTS T p>0 / Z z / Y y / X x RJ(x,y+iz,y-iz,p)

Example:

7  ENTER^
4  ENTER^
2  ENTER^
1  XEQ "RJZ" produces  RJ ( 1 , 2+4i , 2-4i , 7 ) = 0.126039065   ( in 11.8 seconds )

-If the arguments have huge ratios, the execution time may be huge too!
-For instance:  RJ(0,10 -50,10 -10,1050) =  1.423139884 10 -43   is obtained in almost 3 minutes!
-Note that the other programs would lead to OUT OF RANGE though the final result is neither underflowed nor overflowed.

-If the result is really underflowed, it is replaced by zero.
-If the result is really overflowed, you'll get OUT OF RANGE, but the content of X-register will remain the same
-For example, RJ(0,10 -80,10 -80,10 -80) produces an OUT OF RANGE  with X-register = 2.356194491 E-80  apparently but if you press 1/X you'll get 0.

-However, if you've set flag F24,     RJ(0,10 -80,10 -80,10 -80)   gives   9.999999999 E99
-In fact, the correct result is 2.35619449 E+120  so the mantissa was good but the exponent was not ( and couldn't be ) exact.

-There will be a DATA ERROR if  x or y or z < 0 or p <= 0 ( with RJ )  or  x < 0  or p <= 0 ( with RJZ )
-Space can be saved if you don't check for zero-arguments...
-In this case, there will be an infinite loop if you execute RJ with x = y = 0 and z # 0  or if you execute RJZ with y = z = 0
press  ENTER^  ON to stop the loop with a "newest" HP-41
-On older HP-41s, insert

3CC   ?KEY
360    ?C RTN    at the beginning of the loop: the infinite loop will be stopped by pressing any key for 2 seconds.

-RJ & RJZ  do not use any data register but the alpha registers M N O P are cleared and Q is also used.

-The routine stops when 2 consecutive approximations are nearly equal ( CPU-flag9 is also used by RJZ to avoid a premature stop ).

-You can certainly write a faster function if you employ the method of "RJ3" & "RJZ3":
the number of iterations will be reduced, but the series expansion needs many extra words.

-Another improvement is to modify RJ so that it returns the Cauchy principal value of the integral if p < 0
-All depends on the place you want to allocate on your HP-41 for Carlson Elliptic Integrals ...

3°) Legendre Elliptic Integrals  ( another method via Carlson Integrals )

a) Legendre Elliptic Integrals of the first kind

-We use the formula:    F ( phi | m ) = §0phi ( 1 - m sin2 t )-1/2 dt = sin (phi) . RF ( cos2(phi) ; 1 - m.sin2(phi) ; 1 )

Data Registers:   R00: temp
Flags: /
Subroutine:  The M-code function RF or the focal program "RF" or "RF2".  In this case, use another register to avoid a register usage conflict.

 01  LBL "LEI1" 02  1 03  P-R 04  X^2 05  X<>Y 06  STO 00        07  X^2 08  SIGN  09  LASTX 10  R^ 11  * 12  - 13  X=Y? 14  X#0? 15  GTO 00 16  DEG 17  90 18  TAN 19  RTN 20  LBL 00 21  1 22  RF 23  RCL 00        24  * 25  END

( 37 bytes / SIZE 001 )

 STACK INPUTS OUTPUTS Y m / X phi F(phi | m)

Example:     in DEG mode:

0.7  ENTER^
84   XEQ "LEI1"  >>>>  F( 84° | 0.7 ) =  1.884976270    ( in 6.5 seconds )

-If you prefer  F( phi , k ) = F ( phi | k2 )   add  X^2 after line 10 and place k in Y-register ( instead of m )
but m may be negative wheras k2 may not.

-You must have  -90° < phi <= 90°  If  90° < phi <= 180°  you'll get  F ( 180°- phi | m )
-This program works in all angular modes.

b) Legendre Elliptic Integrals of the second kind

Formula:    E ( phi | m ) = §0phi ( 1 - m sin2 t )1/2 dt
= sin (phi) . RF ( cos2(phi) ; 1 - m.sin2(phi) ; 1 ) - (m/3) sin3(phi) . RD ( cos2(phi) ; 1 - m.sin2(phi) ; 1 )

Data Registers:   R00  thru R04: temp
Flags: /
Subroutines:  The M-code routines RF & RJ  or "RF" & "RJ" ...  In this case, use other registers to avoid a register usage conflict.

 01  LBL "LEI2" 02  1 03  P-R 04  X^2 05  STO 00        06  X<>Y 07  STO 01 08  X^2 09  SIGN 10  LASTX 11  R^ 12  STO 02        13  * 14  - 15  X=Y? 16  X#0? 17  GTO 00 18  SIGN 19  RTN 20  LBL 00 21  STO 03        22  1 23  RF 24  STO 04 25  1 26  STO Y 27  RCL 00 28  RCL 03 29  RJ 30  RCL 04        31  X<>Y 32  RCL 01 33  X^2 34  * 35  RCL 02 36  * 37  3 38  / 39  - 40  RCL 01        41  * 42  END

( 55 bytes / SIZE 005 )

 STACK INPUTS OUTPUTS Y m / X phi E (phi | m)

Example:     in DEG mode,

0.7  ENTER^
84   XEQ "LEI2"  >>>>  E ( 84° | 0.7 ) =  1.184070047    ( in 18 seconds )

-If you prefer  E( phi , k ) = E ( phi | k2 )   add  X^2 after line 11 and place k in Y-register ( instead of m )
but m may be negative wheras k2 may not.

-You must have  -90° < phi <= 90°
-This program works in all angular modes.

c) Legendre Elliptic Integrals of the third kind

Formula:     ¶ ( n ; phi | m ) = §0phi ( 1 + n sin2 t ) -1 ( 1 - m sin2 t ) -1/2 dt
= sin (phi) . RF ( cos2(phi) ; 1 - m.sin2(phi) ; 1 ) - (n/3) sin3(phi) . RJ ( cos2(phi) ; 1 - m.sin2(phi) ; 1 ; 1 + n.sin2(phi) )

-This sign convention for n is opposite that of Abramowitz and Steigun

Data Registers:   R00  thru R04: temp
Flags: /
Subroutines:  The M-code routines RF & RJ  or "RF" & "RJ" ...  In this case, use other registers to avoid a register usage conflict.

 01  LBL "LEI3" 02  1 03  P-R 04  X^2 05  STO 00        06  X<>Y 07  STO 01 08  X^2 09  STO 02 10  R^ 11  STO 03        12  X<> T 13  * 14  1 15  X<>Y 16  - 17  X=Y? 18  X#0? 19  GTO 00 20  DEG 21  90 22  TAN 23  RTN 24  LBL 00 25  STO 04        26  1 27  RF 28  X<> 02 29  RCL 03 30  * 31  1 32  ST+ Y 33  RCL 04 34  RCL 00        35  RJ 36  RCL 02  37  X<>Y 38  RCL 01 39  X^2 40  * 41  RCL 03        42  * 43  3 44  / 45  - 46  RCL 01 47  * 48  END

( 64 bytes / SIZE 005 )

 STACK INPUTS OUTPUTS Z n / Y m / X phi ¶( n ; phi | m )

Example:     in DEG mode,

0.9  ENTER^
0.7  ENTER^
84   XEQ "LEI3"  >>>>  ¶ ( 0.9 ; 84° | 0.7 ) =  1.336853615    ( in 19 seconds )

-If you prefer  ¶ ( phi , n , k ) = ¶ ( n ; phi | k2 )   add  X^2 after line 12 and place k in Y-register ( instead of m )
but m may be negative wheras k2 may not.

-You must have  -90° < phi <= 90°
-This program works in all angular modes.
->   1 + n.sin2(phi) is supposed to be positive ( otherwise, use "RJ" instead of RJ )

d) Legendre Elliptic Integrals ( all three )

-Considering their great similarity, the last 3 routines may form a single program, thus saving many bytes:

Data Registers:   R00  thru R04: temp

Flags:   F01    Set flag F01 to compute Legendre elliptic integrals of the first kind
F02     Set flag F02 to compute Legendre elliptic integrals of the second kind         Set only one of these 2 flags
Clear   F01 & F02 to compute Legendre elliptic integrals of the third kind

Subroutines: The M-code routines RF & RJ   or "RF" & "RJ" ...  In this case, use other registers to avoid a register usage conflict.

-Add  X^2  after line 11  if you prefer  k  instead of  m

 01  LBL "LEI" 02  1 03  P-R 04  X^2 05  STO 01 06  X<>Y 07  STO 02        08  X^2 09  R^ 10  STO 00  11  X<> T 12  FS? 02 13  STO 00  14  * 15  1 16  X<>Y 17  - 18  X=Y? 19  X#0? 20  GTO 00        21  SIGN 22  FS? 02 23  RTN 24  DEG 25  90 26  TAN 27  RTN 28  LBL 00 29  STO 03  30  1 31  RF 32  FS? 01 33  GTO 00 34  STO 04        35  RCL 02 36  X^2 37  RCL 00  38  * 39  1 40  ST+ Y 41  FS? 02 42  STO Y 43  RCL 03 44  RCL 01        45  RJ 46  RCL 02 47  X^2 48  * 49  RCL 00  50  * 51  3 52  / 53  RCL 04        54  X<>Y 55  - 56  LBL 00 57  RCL 02 58  * 59  END

( 79 bytes / SIZE 005 )

 STACK INPUTS OUTPUTS Z n* / Y m / X phi Leg-Ell-Int

*  n is used for the integrals of the 3rd kind only

Leg-Ell-Int  =  E ( phi | m )        if flag  F01 is set
Leg-Ell-Int  =  F ( phi | m )        if flag  F02 is set
Leg-Ell-Int  =  ¶ ( n ; phi | m )    if flags F01 & F02 are cleared.

References:

[1]  Abramowitz and Stegun , "Handbook of Mathematical Functions" -  Dover Publications -  ISBN  0-486-61272-4
[2]  B.C. Carlson, "Numerical Computation of Real or Complex Elliptic Integrals"
[3]  Press , Vetterling , Teukolsky , Flannery - "Numerical Recipes in C++" - Cambridge University Press - ISBN  0-521-75033-4