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.