hp41programs

Pseudo-Inverse

Matrix Pseudo-Inverse for the HP-41


Overview
 

 1°)  The Method of Gréville ( 2nd version )
 2°)  Ben-Israel and Cohen Algorithm
 3°)  An Iterative Method of order 3
 4°)  Rank of a Matrix
 

-If A is a nxm matrix ( n rows, m columns ), the pseudoinverse A+ , also called Moore-Penrose inverse, of the matrix A
  A+ is the unique mxn matrix ( m rows, n columns ) such that:  A A+ A = A ,  A+ A A+  = A+ ,  A A+ and  A+ A  symmetric.

-The following routines only deal with real matrices.
 
 

1°)  The Method of Gréville ( 2nd Version )
 

-A program that uses Gréville's method is already listed in "Matrix Operations for the HP-41" where the formulas are given too.
-Unlike the 1st program, this variant does not call "TM*" as a subroutine.
-For the rest, the calculations are almost identical.
 

Data Registers:           R00 thru R08: temp                    ( Registers Rbb to Ree  are to be initialized before executing "GRVL" )

                                  •  Rbb thru  •  Ree  the coefficients of the matrix A, in column order   bb > 07

         >>>>   When the program stops, the pseudo-inverse A+ has replaced A in Rbb to Ree

                                      Registers  Ree+1 , ... are used during the calculations
Flags: /
Subroutines:    "TRN"  "M*"  "MCO"  ( cf  "Matrix Operations for the HP-41" )
                          "MCO" may be replaced by the M-Code routine "LCO"  listed in "Miscellaneous Short Routines for the HP-41"

-Line 194 is a three-byte  GTO 03
 
 

  01  LBL "GRVL"
  02  STO 00
  03  STO 01 
  04  FRC
  05  ISG X
  06  INT
  07  .1
  08  %
  09  ST+ 01
  10  +
  11  STO 02 
  12  LASTX
  13  RCL 00
  14  INT
  15  .1
  16  %
  17  +
  18  +
  19   E3
  20  STO 08 
  21  1/X
  22  -
  23  STO 03
  24  STO 04        
  25  RCL 00
  26  FRC
  27  RCL 08
  28  *
  29  INT
  30  1
  31  +
  32  STO 06
  33  RCL 00
  34  INT
  35  -
  36  ST+ 01
  37  STO 05 
  38  ST+ 06
  39  RCL 02
  40  INT
  41  ST/ 05
  42   E5
  43  /
  44  ST+ 04
  45  RCL 05 
  46  RCL 06
  47  +
  48  STO 07
  49  RCL 03
  50  RCL 01 
  51  INT
  52  XEQ "MCO"
  53  ENTER^
  54  ENTER^
  55  CLX
  56  STO 05
  57  DSE 07
  58  LBL 01
  59  RCL IND Y
  60  X^2
  61  +
  62  ISG Y
  63  GTO 01
  64  SQRT
  65   E-7
  66  X>Y?
  67  GTO 03
  68  R^
  69  LASTX
  70  LBL 02
  71  ST/ IND Y
  72  ISG Y
  73  GTO 02
  74  LBL 03
  75  RCL 02 
  76  ST+ 03
  77  RCL 01 
  78  INT
  79  RCL 03
  80  INT
  81  X#Y?
  82  GTO 03
  83  RCL 01 
  84  RCL 00
  85  INT
  86  XEQ "TRN"
  87  RTN
  88  LBL 03
  89  LASTX
  90  RCL 01
  91  RCL 06        
  92  INT
  93  XEQ "M*"
  94  STO 06
  95  RCL 05
  96  +
  97  RCL 04
  98  X<>Y
  99  RCL 07
100  INT
101  XEQ "M*"
102  STO 07
103  RCL 08
104  *
105  INT
106  RCL 08 
107  /
108  STO M
109  RCL 03 
110  LBL 04
111  RCL IND X
112  RCL IND Z
113  -
114  STO IND Z
115  ISG Y
116  RDN
117  ISG Y
118  GTO 04
119  RCL M
120  0
121  LBL 05
122  RCL IND Y
123  X^2
124  +
125  ISG Y
126  GTO 05       
127  SQRT
128   E-7
129  X<Y?
130  GTO 03
131  RCL 01
132  RCL 06
133  RCL 05
134  +
135  RCL 07
136  INT
137  XEQ "M*"
138  STO 07
139  RCL 08 
140  *
141  INT
142  RCL 08 
143  /
144  STO M
145  RCL 06
146  1
147  GTO 05
148  LBL 03
149  RCL M
150  LASTX
151  LBL 06
152  ST/ IND Y
153  ISG Y
154  GTO 06
155  RCL M
156  RCL 01
157  FRC
158  RCL 08        
159  *
160  INT
161  1
162  +
163  XEQ "MCO"
164  RCL 07
165  RCL 06
166  RCL 07
167  FRC
168  RCL 08 
169  *
170  INT
171  1
172  +
173  XEQ "M*"
174  RCL 08 
175  *
176  INT
177  RCL 08 
178  /
179  RCL 01
180  LBL 07
181  RCL IND Y
182  ST- IND Y
183  CLX
184  SIGN
185  +
186  ISG Y
187  GTO 07
188  RCL 02        
189  FRC
190  ST+ 01
191  ST+ 04
192   E-5
193  ST+ 05
194  GTO 03
195  END

 
    ( 282 bytes / SIZE bb+3n.m+m-1 )
 
 

      STACK         INPUT       OUTPUT
           X      bbb.eeennA    bbb.eeemmA+

  where  bbb.eeenn = control number of the matrix A   bbb > 008

Example:    The same matrix as in "Matrix Operations"

                 1  1  4  2                     R10  R13  R16  R19
      A  =    0  1  2  3         =          R11  R14  R17  R20      ( respectively )      control number =  10.02103
                 3  2  6  7                     R12  R15  R18  R21
 

   •   10.02103         XEQ "GRVL"  >>>>   10.02104                  --- execution time = 71s ---

 and we get:

                  R10   R14   R18              -21/112    -85/112   43/112
                  R11   R15   R19     =         7/112      23/112   -9/112         =   A+   ( with some roundoff errors of course ).
                  R12   R16   R20                49/112      1/112   -15/112
                  R13   R17   R21               -35/112    29/112    13/112

-In this example,  A A+ = Id3

Notes:

-SIZE 049 is enough for this matrix

-Lines 65 and 128,  E-7  is used to identify tiny real numbers.
-Another choice may be better according to the matrix elements.

-The routine stops at line 87.
-Lines 83 to 87 actually overwrite the original matrix A.
-If you want to save A, replace these lines by

    RCL 01           XEQ "MCO"       XEQ "TRN"
    RCL 06           RCL 01               RTN
    INT                 INT
 

2°)  Ben-Israel and Cohen Algorithm
 

-Ben-Israel and Cohen algorithm is an iterative method:

    Ak+1 =  2 Ak -  Ak A Ak      with  A0 = µ AT          where   AT = transposed of A   and   0 < µ <= 2 / Trace(A.AT)

-The following program uses  µ = 1 / Trace(A.AT)
 

Data Registers:           R00 thru R05: temp                    ( Registers Rbb to Ree  are to be initialized before executing "BISC" )

                                  •  Rbb thru  •  Ree  the coefficients of the matrix A, in column order   bb > 05

         >>>>   When the program stops, the pseudo-inverse A+ is stored in Ree+1 to Ree+m.n

Flags: /
Subroutines:    "TRN"  "M*"  ( cf  "Matrix Operations for the HP-41" )

-Lines 31 to 38 may be replaced by   XEQ "TRACE"   ( cf  "Matrix Operations for the HP-41" )
 
 

 01  LBL "BISC"
 02  ENTER^
 03  STO 00 
 04  FRC
 05   E3
 06  STO 05 
 07  *
 08  INT
 09  1
 10  +
 11  XEQ "TRN"
 12  STO 01        
 13  RCL 00
 14  -
 15  INT
 16  RCL 01 
 17  INT
 18  +
 19  STO 02
 20  RCL 00 
 21  FRC
 22  ISG X
 23  INT
 24  X^2
 25  +
 26  STO 03
 27  RCL 00         
 28  RCL 01 
 29  RCL 02
 30  XEQ "M*"
 31   E-5
 32  +
 33  0
 34  LBL 00
 35  RCL IND Y
 36  +
 37  ISG Y
 38  GTO 00
 39  RCL 01
 40  RCL 05 
 41  *
 42  INT
 43  RCL 05         
 44  /
 45  STO 04 
 46  X<>Y
 47  LBL 01
 48  ST/ IND Y
 49  ISG Y
 50  GTO 01
 51  LBL 02
 52  RCL 00
 53  RCL 01
 54  RCL 02
 55  XEQ "M*"
 56  RCL 01 
 57  X<>Y
 58  RCL 03
 59  XEQ "M*"
 60  INT
 61  STO M
 62  RCL 04        
 63  STO N
 64  CLX
 65  LBL 03
 66  RCL IND N
 67  RCL IND M
 68  -
 69  ST+ IND N
 70  ABS
 71  +
 72  ISG M
 73  CLX
 74  ISG N
 75  GTO 03
 76  VIEW X
 77   E-7
 78  X<Y?
 79  GTO 02 
 80  CLA
 81  CLD
 82  RCL 01        
 83  END

 
    ( 127 bytes / SIZE bb+3n.m+n^2 )
 
 

      STACK         INPUT       OUTPUT
           X      bbb.eeennA    bbb.eeemm'A+

  where  bbb.eeenn = control number of the matrix A   bbb > 005

Example:       The same matrix again:

                 1  1  4  2                     R10  R13  R16  R19
      A  =    0  1  2  3         =          R11  R14  R17  R20      ( respectively )      control number =  10.02103
                 3  2  6  7                     R12  R15  R18  R21
 

   •   10.02103         XEQ "BISC"  >>>>   22.03304                  --- execution time = 7m40s ---

 and we get:

                  R22   R26   R30              -21/112    -85/112   43/112
                  R23   R27   R31     =         7/112      23/112   -9/112         =   A+   ( with some roundoff errors ).
                  R24   R28   R32                49/112      1/112   -15/112
                  R25   R29   R33               -35/112    29/112    13/112

Notes:

-"BISC" is obviously very slow but with a good emulator...
-The advantage is that it's also much shorter than "GRVL" !

-The successive "amplitudes" of the increments are successively displayed ( line 71 )
-Though very slow in the first iterations, the convergence becomes quadratic near the end.

-Line 72,  10^(-7) is used to evaluate the difference between 2 successive approximations.
-This real may be changed according to the type of matrix.
-Anyway, after the program stops, simply execute XEQ 02 to perform another iteration if need be.

   Ak+1 =  2 Ak -  Ak A Ak  may also be used to improve the precision of the result returned by "GRVL"
 

3°)  An Iterative Method of Order 3
 

-Other methods of higher order may also be derived:
 

Formula of order q:

    with  A0 = µ AT          where     0 < µ <= 2 / Trace(A.AT)

    Tk = I - Ak A
    Mk = I + Tk + ..... + Tkq-1
   Ak+1 = Mk Ak                             the sequence  ( Ak )  tends to  A+  when k tends to infinity
 

-The routine hereunder uses  q = 3
 
 

Data Registers:           R00 thru R06: temp                     ( Registers Rbb to Ree  are to be initialized before executing "INV3" )

                                  •  Rbb thru  •  Ree  the coefficients of the matrix A, in column order   bb > 06

         >>>>   When the program stops, the pseudo-inverse A+ is stored in Ree+1 to Ree+m.n

Flags: /
Subroutines:    "TRN"  "M*"  ( cf  "Matrix Operations for the HP-41" )

-Lines 33 to 40 may be replaced by   XEQ "TRACE"   ( cf  "Matrix Operations for the HP-41" )
 
 

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

 
    ( 151 bytes / SIZE bb+4n.m+n^2 )
 
 

      STACK         INPUT       OUTPUT
           X      bbb.eeennA    bbb.eeemm'A+

  where  bbb.eeenn = control number of the matrix A   bbb > 006

Example:    Still the same matrix

                 1  1  4  2                     R10  R13  R16  R19
      A  =    0  1  2  3         =          R11  R14  R17  R20      ( respectively )      control number =  10.02103
                 3  2  6  7                     R12  R15  R18  R21
 

   •   10.02103         XEQ "INV3"  >>>>   22.03304                  --- execution time = 7m40s ---

 and we get:

                  R22   R26   R30              -21/112    -85/112   43/112
                  R23   R27   R31     =         7/112      23/112   -9/112         =   A+   ( with some roundoff errors ).
                  R24   R28   R32                49/112      1/112   -15/112
                  R25   R29   R33               -35/112    29/112    13/112

Notes:

-In this example, the execution is the same !
-Convergence is faster, so less iterations are needed, but each iteration is more time consuming.

-If you want to execute another loop, simply press  XEQ 02
 

4°)  Rank of a Matrix
 

-The rank r(A) of an nxm matrix A may be computed by    r(A) = Trace ( A A+ )
-So we can use one of the 3 programs above to calculate  r(A)

-"TRACE" is listed in "Matrix Operations for the HP-41"

-If you want to use the 1st version, on the left, modify "GRVL" to save the matrix A, as suggested in the note, paragraph 1.
-If you prefer the 2nd version, add  STO 05  after line 55 in the "BISC" listing.
-In the 3rd version on the right, "INV3" doesn't need any change.
 
 
 

 01  LBL "RANK"
 02  XEQ "GRVL"
 03  RCL 00
 04  X<>Y
 05  RCL 06
 06  INT
 07  XEQ "M*"
 08  XEQ "TRACE"
 09  FIX 0
 10  RND
 11  FIX 4
 12  END
 01  LBL "RANK"
 02  XEQ "BISC"
 03  RCL 05
 04  XEQ "TRACE"
 05  FIX 0
 06  RND
 07  FIX 4
 08  END
 01  LBL "RANK"
 02  XEQ "INV3"
 03  RCL 02
 04  XEQ "TRACE"
 05  FIX 0
 06  RND
 07  FIX 4
 08  END

 
        ( 37 bytes )                 ( 30 bytes )                ( 30 bytes )
 
 

      STACK         INPUT       OUTPUT
           X      bbb.eeennA           r(A)

  where  bbb.eeenn = control number of the matrix A

Example1:

                 1  1  4  2                     R10  R13  R16  R19
      A  =    0  1  2  3         =          R11  R14  R17  R20           control number =  10.02103
                 3  2  6  7                     R12  R15  R18  R21
 

   •   10.02103         XEQ "RANK"  >>>>   3.0000

Example2:

                 1  1  4  2                     R10  R13  R16  R19
      A  =    0  1  2  3         =          R11  R14  R17  R20           control number =  10.02103
                 1  3  8  8                     R12  R15  R18  R21
 

   •   10.02103         XEQ "RANK"  >>>>   2.0000
 

Notes:

-Due to roundoff-errors, "TRACE" doesn't always return an integer.
-That's why  FIX 0  RND  FIX 4  are added before the  END
-Alternatively, these 3 instructions may be replaced by  .5  +   INT

-The 1st version  - that calls "GRVL" - is of course much faster.

-But if you like the iterative method of Ben-Israel & Cohen, the following program can be used to get the rank only.
 

Formula:

    B0   =  ( A AT )  /   Trace ( A AT )
   Bk+1 = 2 Bk - Bk2

  >>>     r(A) = Limk->infinity Tr ( Bk )
 
 

Data Registers:           R00 thru R04: temp                    ( Registers Rbb to Ree  are to be initialized before executing "RANK" )

                                  •  Rbb thru  •  Ree  the coefficients of the matrix A, in column order   bb > 04

         >>>>   When the program stops, the rank  r(A) is in X ( the non-rounded value is in R04 )

Flags: /
Subroutines:    "TRN"  "M*"  "MCO"
 
 

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

 
      ( 140 bytes )
 
 

      STACK         INPUT       OUTPUT
           X      bbb.eeennA           r(A)

  where  bbb.eeenn = control number of the matrix A

Example:

                 1  1  4  2                     R10  R13  R16  R19
      A  =    0  1  2  3         =          R11  R14  R17  R20           control number =  10.02103
                 1  3  8  8                     R12  R15  R18  R21
 

   •   FIX 7    10.02103         XEQ "RANK"  >>>>   r(A) = 2        ---Execution time = 3m22s---
 

Notes:

-The termination criterion depends on the display setting.
-The program stops when the rounded difference between 2 successive values = 0

-Lines 40 & 68 may be replaced by  XEQ "TRACE"
-In this case, delete lines 80 to 91.

-If there are more rows than columns, store AT instead of A.

Warning:

-In the example above, if you execute "RANK" in FIX 9, it first seems to converge to 2
  but then, Tr ( Bk ) starts to decrease and finally tends to minus infinity !
-So, the formula becomes unstable, especially if the matrix is badly ill-conditionned.
 

References:

[1]  Adi Ben-Israel & Dan Cohen - "On Iterative Computation of Generalized Inverses and Associated Projections" -
          J. Siam Numer. Anal. Vol 3, n°3 , 1966
[2]  R. Penrose - "A Generalized Inverse for Matrices"
[3]  Ben-Israel & Greville - "Generalized Inverses: Theory and Applications" -