hp41programs

Matrix M-Code

M-Code Routines for Matrices


Overview
 

 0°)  Subroutine
 1°)  Matrix Product
 2°)  Euclidean Norm
 3°)  Trace of a Square Matrix
 
 

0°)  Subroutine
 

-This routine takes the control number of a matrix   bbb.eeenn   in CPU register C
  where  Rbb is the 1st register,  Ree is the last register and  nn = number of rows
- nn may be replaced by 00 if nn = 01

-It checks if  Rbb & Ree  do exist  ( otherwise, you get the NONEXISTENT message )
  and returns in C register:     nn.eee+1.bbb.bbb   where all these abolute addresses are now expressed in hexadecimal

-There is no check for alpha data and synthetic register Q is used.
-The status registers must be the active registers block
 

2A0  SETDEC                   @E4C6   in my ROM
070   N=C ALL
088   C
0ED  =
064   int(C)
0F0   C<>N ALL
084   C
0ED  =
064   frc(C)
2EE  ?C#0 ALL
023   JNC+04
226   C
226   =
226   1000 C
268   Q=C
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
008   02E3
106   A=C S&X
0B0  C= N ALL
0A6  A<>C S&X
10E  A=C ALL
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
10E  A=C ALL
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
0AE  A<>C ALL
03C  RCR 3
0AE  A<>C ALL
306  ?A<C S&X
381  ?NCGO
00A  02E0
2A0  SETDEC
278  C=Q
084   C
0ED  =
064   frc(C)
2EE  ?C#0 ALL
01B   JNC+03
226   C=
226   100 C
260    SETHEX
38D  ?NCXQ
008   02E3
2E6  ?C#0 S&X
017   JC+02
226   C=C+1 S&X
106   A=C S&X
0B0  C= N ALL
23A  C=C+1 M
17C  RCR 6
0A6  A<>C S&X
13C  RCR 8
106   A=C S&X
1BC  RCR 11
0A6  A<>C S&X
3E0   RTN                        @E50B   in my ROM

( 70 words )
 

-This subroutine is called by all the following functions.
 

1°)  Matrix Product
 

08D  "M"                           @E50C   in my ROM
02A   "*"
00D  "M"
2A0   SETDEC
248   SETF 9
0B8   C=Y
05E   C=| C |                     loop0
070   N=C ALL
088    C
0ED   =
064    int(C)
2BE   C=-C
268    Q=C
0B0   C=N ALL
084    C
0ED   =
064    frc(C)
2EE   ?C#0 ALL
023    JNC+04
226    C
226    =
226    1000.C
070    N=C ALL
088    C
0ED   =
064    int(C)
278    C=Q
025    C=
060    AB+C
2FE   ?C<0
0B5   ?CGO
0A3   DATAERROR
001    C=
060    AB+1
0F0    C<>N ALL
084    C
0ED   =
064    frc(C)
2EE   ?C#0 ALL
01B    JNC+03
226    C=
226    100.C
088    C
0ED   =
064    int(C)
2EE   ?C#0 ALL
01F   JC+03
35C  C=
050   1
228   P=C
10E   A=C ALL
0B0   C=N ALL
0AE  A<>C ALL
261   C=
060   A/C
268   Q=C
084    C
0ED   =
064    frc(C)
2EE   ?C#0 ALL
0B5   ?CGO
0A3   DATAERROR
24C   ?FSET 9
043    JNC+08
244    CLRF 9
278   C=Q
168   M=C
238   C=P
1A8   N=C
078   C=Z
203   JNC-64d                       goto loop0
278    C=Q
10E   A=C ALL
1B8   C=N
36E   ?A#C ALL
0B5   ?CGO
0A3   DATAERROR
238   C=P
10E   A=C ALL
266   C=
266   C/100
228   P=C
178   C=M
135    C=
060    A*C
268    Q=C
0F8    C=X
05E   C=| C |
088    C
0ED   =
064    int(C)
128    L=C
278    C=Q
025    C=
060    AB+C
009    C=
060    AB-1
238    C=P
025    C=
060    AB+C
1A6    A
1A6    =
1A6    A/1000
138    C=L
025    C=
060    AB+C
0E8    X=C
319    ?NCXQ                        calls the subroutine
390     E4C6                           listed in paragraph 0
266    C=C-1 S&X
1E8    O=C
0B8    C=Y
319    ?NCXQ                        calls the subroutine
390     E4C6                           listed in paragraph 0
1A8    N=C
078     C=Z
319    ?NCXQ                        calls the subroutine
390     E4C6                           listed in paragraph 0
168     M=C
228     P=C
1A0    A=B=C=0 ALL            LOOP                  @E584   in my ROM
089     AB
064     STO Q+
178     C=M                             loop1
270     RAMSLCT
038    READATA
10E    A=C ALL
046    C=0 S&X
270    RAMSLCT
1B8   C=N
270    RAMSLCT
038    READATA
2A0   SETDEC
135   C=
060   A*C
0C9   0 ramslct
064    & RCL Q+
031    C=
060    AB+CM
070    N=C ALL
089    AB
064    STO Q+
260    SETHEX
178    C=M
27C   RCR 9
106   A=C S&X
178   C=M
206   C=A+C S&X
168   M=C
106   A=C S&X
17C   RCR 6
306   ?A<C S&X
02B   JNC+05
1B8   C=N
226   C=C+1 S&X
1A8   N=C
2FB   JNC-33d                             goto loop1
1F8    C=O
226    C=C+1 S&X
1E8    O=C
270    RAMSLCT
0B0   C=N ALL
2F0   WRITDATA
046   C=0 S&X
270   RAMSLCT
1B8   C=N
03C   RCR 3
106    A=C S&X
1BC   RCR 11
0A6   A<>C S&X
1A8   N=C
178    C=M
03C   RCR 3
226    C=C+1 S&X
106    A=C S&X
1BC   RCR 11
0A6   A<>C S&X
168    M=C
106    A=C S&X
238    C=P
1C6   A=A-C S&X
27C   RCR 9
306    ?A<C S&X
20F    JC-63d                            goto LOOP
238    C=P
168    M=C
1B8    C=N
03C    RCR 3
106    A=C S&X
17C   RCR 6
146    A=A+C S&X
13C   RCR 8
0A6   A<>C S&X
106    A=C S&X
1BC   RCR 11
0A6   A<>C S&X
1A8   N=C
106    A=C S&X
17C   RCR 6
306    ?A<C S&X
211    ?CGO
397     E584                                goto  LOOP
345    ?NCGO
042    CLA                                 @E5D7   in my ROM

( 204 words )
 
 

      STACK        INPUTS      OUTPUTS
           T            T             T
           Z     bbb.eeerr1     bbb.eeerr1
           Y     bbb.eeerr2     bbb.eeerr2
           X         bbb3   | bbb.eeerr3 |
           L           /       | bbb3 |

 
Example:  Calculate  C = A.B where

                                                        3  1
                 2  7  1  3                         4  2
         A =  1  9  4  2                B =   7  5        assuming   A is stored in registers R01 thru R12         and choosing R26
                 4  6  2  1                         2  6                         B is stored in registers R15 thru R22         as the first register of C

-In other words,

     R01  R04  R07  R10                2  7  1  3                                   R15  R19         3  1
     R02  R05  R08  R11       =       1  9  4  2               and              R16  R20   =    4  2      respectively.
     R03  R06  R09  R12                4  6  2  1                                   R17  R21         7  5
                                                                                                      R18  R22         2  6

-Key in:           1.01203  ENTER^
                     15.02204  ENTER^
                          26        XEQ "M*M"   >>>>   26.03103   =   the control number of the matrix C and the result is:

                47  39       R26  R29
       C =   71  51  =   R27  R30
                52  32       R28  R31

Notes:

-Only the integer part of X-input is taken into account.
-This routine checks that the number of columns of the first matrix is equal to the number of rows of the second matrix.
-Otherwise, you get a DATA ERROR message.
-The validity of the control numbers is also checked
-For example, if you key in 1.01303 instead of 1.01203 you'll get DATA ERROR too.

-You can key in  bbb.eee  instead of  bbb.eee01 and the decimals beyond the 5th are not taken into account.
-Negative control numbers are also OK: the absolute value is always computed.

-However, there is no check for alpha data , neither in the stack nor in the data registers.

-Execution time = 67 seconds for the product of two 10x10 matrices, about 6 times as fast as the focal program "M*"

-The outputs in Y-Z-T are different from those given by "M*"
-So several programs that use the focal program "M*" must be changed a little if you replace "M*" by the M-Code M*M
 

2°)  Euclidean Norm
 

-"MNORM"  calculates  ( SUM i,j  ai,j2 )1/2
 

08D  "M"
012   "R"
00F   "O"
00E   "N"
00D  "M"
0F8   C=X
128   L=C
319   ?NCXQ                        calls the subroutine
390    E4C6                           listed in paragraph 0
070   N=C ALL
1A0  A=B=C=0
089   AB
064   STO Q+
2A0   SETDEC                      loop
0B0   C=N ALL
270    RAMSLCT
038   READATA
10E   A=C ALL
135   C=
060   A*C
0C9   0 ramslct
064    & RCL Q+
031    C=
060    AB+CM
089    AB
064    STO Q+
260    SETHEX
0B0   C=N ALL
226   C=C+1 S&X
070   N=C ALL
106   A=C S&X
17C  RCR 6
306   ?A<C S&X
367   JC-20d                 goto loop
1A0   A=B=C=0
2A0   SETDEC
0D1   RCL
064    Q+
031    C=
060    AB+CM
305    C=
060    sqrt(AB)
0E8    X=C
3E0    RTN

( 44 words )
 
 

      STACK        INPUT      OUTPUTS
           X       bbb.eeerr        || A ||
           L             /      bbb.eeerr

  In fact, rr is not taken into account

Example:

             1  2  4        R03  R06  R09
    A =   3  5  7   =   R04  R07  R10
             7  9  8        R05  R08  R11

   3.01103  XEQ "MNORM"  >>>>  || A || = 17.26267650 = sqrt(298)

Notes:

-Registers  Y-Z-T  are unchanged.
-With a matrix of 100 elements, execution time = 6.6 seconds.
 

3°)  Trace of a Square Matrix
 
 

085   "E"
003   "C"
001   "A"
012   "R"
014   "T"
0F8   C=X
128   L=C
319   ?NCXQ                        calls the subroutine
390    E4C6                           listed in paragraph 0
27C   RCR 9
226   C=C+1 S&X
13C   RCR 8
070   N=C ALL
1A0  A=B=C=0
089   AB
064   STO Q+
2A0   SETDEC                      loop
0B0   C=N ALL
270   RAMSLCT
038   READATA
10E   A=C ALL
046   C=0 S&X
0EE   B<>C ALL
0C9   0 ramslct
064    & RCL Q+
031    C=
060    AB+CM
089    AB
064    STO Q+
260    SETHEX
0B0   C=N ALL
17C   RCR 6
106   A=C S&X
0B0  C=N ALL
206   C=A+C S&X
070   N=C ALL
106   A=C S&X
03C  RCR 3
306  ?A<C S&X
34F  JC-23d                          goto loop
1A0   A=B=C=0
2A0   SETDEC
0D1   RCL
064    Q+
031    C=
060    AB+CM
0E8    X=C
3E0    RTN

( 48 words )
 
 

      STACK        INPUT      OUTPUT
           X       bbb.eeerr        Tr(A)
           L             /       bbb.eeerr

 
Example:

             1  2  4        R03  R06  R09
    A =   3  5  7   =   R04  R07  R10
             7  9  8        R05  R08  R11

   3.01103  XEQ "TRACE"  >>>>  Tr(A) = 14

-Registers  Y-Z-T  are unchanged.