Matrix multiplication: Difference between revisions

m
 
(354 intermediate revisions by more than 100 users not shown)
Line 1:
{{task|Matrices}}
{{task|Matrices}}Multiply two matrices together. They can be of any dimensions, so long as the number of columns of the first matrix is equal to the number of rows of the second matrix.
 
;Task:
Multiply two matrices together.
 
They can be of any dimensions, so long as the number of columns of the first matrix is equal to the number of rows of the second matrix.
<br><br>
 
=={{header|11l}}==
{{trans|Nim}}
 
<syntaxhighlight lang="11l">F matrix_mul(m1, m2)
assert(m1[0].len == m2.len)
V r = [[0.0] * m2[0].len] * m1.len
L(j) 0 .< m1.len
L(i) 0 .< m2[0].len
V s = 0.0
L(k) 0 .< m2.len
s += m1[j][k] * m2[k][i]
r[j][i] = s
R r
 
F to_str(m)
V result = ‘([’
L(r) m
I result.len > 2
result ‘’= "]\n ["
L(val) r
result ‘’= ‘#5.2’.format(val)
R result‘])’
 
V a = [[1.0, 1.0, 1.0, 1.0],
[2.0, 4.0, 8.0, 16.0],
[3.0, 9.0, 27.0, 81.0],
[4.0, 16.0, 64.0, 256.0]]
 
V b = [[ 4.0, -3.0 , 4/3.0, -1/4.0],
[-13/3.0, 19/4.0, -7/3.0, 11/24.0],
[ 3/2.0, -2.0 , 7/6.0, -1/4.0],
[ -1/6.0, 1/4.0, -1/6.0, 1/24.0]]
 
print(to_str(a))
print(to_str(b))
print(to_str(matrix_mul(a, b)))
print(to_str(matrix_mul(b, a)))</syntaxhighlight>
 
{{out}}
<pre>
([ 1.00 1.00 1.00 1.00]
[ 2.00 4.00 8.00 16.00]
[ 3.00 9.00 27.00 81.00]
[ 4.00 16.00 64.00 256.00])
([ 4.00 -3.00 1.33 -0.25]
[ -4.33 4.75 -2.33 0.46]
[ 1.50 -2.00 1.17 -0.25]
[ -0.17 0.25 -0.17 0.04])
([ 1.00 0.00 -0.00 -0.00]
[ 0.00 1.00 -0.00 -0.00]
[ 0.00 0.00 1.00 0.00]
[ 0.00 0.00 0.00 1.00])
([ 1.00 0.00 0.00 0.00]
[ 0.00 1.00 -0.00 0.00]
[ 0.00 0.00 1.00 0.00]
[ 0.00 0.00 -0.00 1.00])
</pre>
 
=={{header|360 Assembly}}==
<syntaxhighlight lang="360asm">* Matrix multiplication 06/08/2015
MATRIXRC CSECT Matrix multiplication
USING MATRIXRC,R13
SAVEARA B STM-SAVEARA(R15)
DC 17F'0'
STM STM R14,R12,12(R13)
ST R13,4(R15)
ST R15,8(R13)
LR R13,R15
LA R7,1 i=1
LOOPI1 CH R7,M do i=1 to m (R7)
BH ELOOPI1
LA R8,1 j=1
LOOPJ1 CH R8,P do j=1 to p (R8)
BH ELOOPJ1
LR R1,R7 i
BCTR R1,0
MH R1,P
LR R6,R8 j
BCTR R6,0
AR R1,R6
SLA R1,2
LA R6,0
ST R6,C(R1) c(i,j)=0
LA R9,1 k=1
LOOPK1 CH R9,N do k=1 to n (R9)
BH ELOOPK1
LR R1,R7 i
BCTR R1,0
MH R1,P
LR R6,R8 j
BCTR R6,0
AR R1,R6
SLA R1,2
L R2,C(R1) R2=c(i,j)
LR R10,R1 R10=offset(i,j)
LR R1,R7 i
BCTR R1,0
MH R1,N
LR R6,R9 k
BCTR R6,0
AR R1,R6
SLA R1,2
L R3,A(R1) R3=a(i,k)
LR R1,R9 k
BCTR R1,0
MH R1,P
LR R6,R8 j
BCTR R6,0
AR R1,R6
SLA R1,2
L R4,B(R1) R4=b(k,j)
LR R15,R3 a(i,k)
MR R14,R4 a(i,k)*b(k,j)
LR R3,R15
AR R2,R3 R2=R2+a(i,k)*b(k,j)
ST R2,C(R10) c(i,j)=c(i,j)+a(i,k)*b(k,j)
LA R9,1(R9) k=k+1
B LOOPK1
ELOOPK1 LA R8,1(R8) j=j+1
B LOOPJ1
ELOOPJ1 LA R7,1(R7) i=i+1
B LOOPI1
ELOOPI1 MVC Z,=CL80' ' clear buffer
LA R7,1
LOOPI2 CH R7,M do i=1 to m
BH ELOOPI2
LA R8,1
LOOPJ2 CH R8,P do j=1 to p
BH ELOOPJ2
LR R1,R7 i
BCTR R1,0
MH R1,P
LR R6,R8 j
BCTR R6,0
AR R1,R6
SLA R1,2
L R6,C(R1) c(i,j)
LA R3,Z
AH R3,IZ
XDECO R6,W
MVC 0(5,R3),W+7 output c(i,j)
LH R3,IZ
LA R3,5(R3)
STH R3,IZ
LA R8,1(R8) j=j+1
B LOOPJ2
ELOOPJ2 XPRNT Z,80 print buffer
MVC IZ,=H'0'
LA R7,1(R7) i=i+1
B LOOPI2
ELOOPI2 L R13,4(0,R13)
LM R14,R12,12(R13)
XR R15,R15
BR R14
A DC F'1',F'2',F'3',F'4',F'5',F'6',F'7',F'8' a(4,2)
B DC F'1',F'2',F'3',F'4',F'5',F'6' b(2,3)
C DS 12F c(4,3)
N DC H'2' dim(a,2)=dim(b,1)
M DC H'4' dim(a,1)
P DC H'3' dim(b,2)
Z DS CL80
IZ DC H'0'
W DS CL16
YREGS
END MATRIXRC</syntaxhighlight>
{{out}}
<pre> 9 12 15
19 26 33
29 40 51
39 54 69</pre>
 
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
<syntaxhighlight lang="action!">INCLUDE "D2:PRINTF.ACT" ;from the Action! Tool Kit
 
DEFINE PTR="CARD"
 
TYPE Matrix=[
BYTE width,height
PTR data] ;INT ARRAY
 
PROC PrintMatrix(Matrix POINTER m)
BYTE i,j
INT ARRAY d
CHAR ARRAY s(10)
 
d=m.data
FOR j=0 TO m.height-1
DO
FOR i=0 TO m.width-1
DO
StrI(d(j*m.width+i),s)
PrintF("%2S ",s)
OD
PutE()
OD
RETURN
 
PROC Create(MATRIX POINTER m BYTE w,h INT ARRAY a)
m.width=w
m.height=h
m.data=a
RETURN
 
PROC MatrixMul(Matrix POINTER m1,m2,res)
BYTE i,j,k
INT ARRAY d1,d2,dres,sum
 
IF m1.width#m2.height THEN
Print("Invalid size of matrices for multiplication!")
Break()
FI
d1=m1.data
d2=m2.data
dres=res.data
 
res.width=m2.width
res.height=m1.height
 
FOR j=0 TO res.height-1
DO
FOR i=0 TO res.width-1
DO
sum=0
FOR k=0 TO m1.width-1
DO
sum==+d1(k+j*m1.width)*d2(i+k*m2.width)
OD
dres(j*res.width+i)=sum
OD
OD
RETURN
 
PROC Main()
MATRIX m1,m2,res
INT ARRAY
d1=[2 1 4 0 1 1],
d2=[6 3 65535 0 1 1 0 4 65534 5 0 2],
dres(8)
 
Put(125) PutE() ;clear the screen
 
Create(m1,3,2,d1)
Create(m2,4,3,d2)
Create(res,0,0,dres)
MatrixMul(m1,m2,res)
 
PrintMatrix(m1)
PutE() PrintE("multiplied by") PutE()
PrintMatrix(m2)
PutE() PrintE("equals") PutE()
PrintMatrix(res)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Matrix_multiplication.png Screenshot from Atari 8-bit computer]
<pre>
2 1 4
0 1 1
 
multiplied by
 
6 3 -1 0
1 1 0 4
-2 5 0 2
 
equals
 
5 27 -2 12
-1 6 0 6
</pre>
 
=={{header|Ada}}==
Ada has matrix multiplication predefined for any floating-point or complex type. The implementation is provided by the standard library packages Ada.Numerics.Generic_Real_Arrays and Ada.Numerics.Generic_Complex_Arrays correspondingly. The following example illustrates use of real matrix multiplication for the type Float:
The implementation is provided by the standard library packages Ada.Numerics.Generic_Real_Arrays and Ada.Numerics.Generic_Complex_Arrays correspondingly. The following example illustrates use of real matrix multiplication for the type Float:
<ada>
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
 
Line 34 ⟶ 311:
begin
Put (A * B);
end Matrix_Product;</syntaxhighlight>
{{out}}
</ada>
Sample output:
<pre>
1.00 0.00 0.00 0.00
Line 44 ⟶ 320:
</pre>
The following code illustrates how matrix multiplication could be implemented from scratch:
<syntaxhighlight lang="ada">package Matrix_Ops is
<ada>
type Matrix is array (Natural range <>, Natural range <>) of Float;
package Matrix_Ops is
function "*" (Left, Right : Matrix) return Matrix;
type Matrix is array (Natural range <>, Natural range <>) of Float;
end Matrix_Ops;
function "*" (Left, Right : Matrix) return Matrix;
end Matrix_Ops;
 
package body Matrix_Ops is
---------
-- "*" --
---------
function "*" (Left, Right : Matrix) return Matrix is
Temp : Matrix(Left'Range(1), Right'Range(2)) := (others =>(others => 0.0));
begin
if Left'Length(2) /= Right'Length(1) then
raise Constraint_Error;
end if;
for I in Left'range(1) loop
for J in Right'range(2) loop
for K in Left'range(2) loop
Temp(I,J) := Temp(I,J) + Left(I, K)*Right(K, J);
end loop;
end loop;
end loop;
return Temp;
end "*";
end Matrix_Ops;</syntaxhighlight>
</ada>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
 
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of FORMATted transput}}
An example of user defined Vector and Matrix Multiplication Operators:
<syntaxhighlight lang="algol68">MODE FIELD = LONG REAL; # field type is LONG REAL #
INT default upb:=3;
MODE VECTOR = [default upb]FIELD;
MODE MATRIX = [default upb,default upb]FIELD;
# crude exception handling #
PROC VOID raise index error := VOID: GOTO exception index error;
# define the vector/matrix operators #
OP * = (VECTOR a,b)FIELD: ( # basically the dot product #
FIELD result:=0;
IF LWB a/=LWB b OR UPB a/=UPB b THEN raise index error FI;
FOR i FROM LWB a TO UPB a DO result+:= a[i]*b[i] OD;
result
);
OP * = (VECTOR a, MATRIX b)VECTOR: ( # overload vector times matrix #
[2 LWB b:2 UPB b]FIELD result;
IF LWB a/=LWB b OR UPB a/=UPB b THEN raise index error FI;
FOR j FROM 2 LWB b TO 2 UPB b DO result[j]:=a*b[,j] OD;
result
);
# this is the task portion #
<pre style="background-color:#ffe">
OP * = (MATRIX a, b)MATRIX: ( # overload matrix times matrix #
# this is the task portion #
[LWB a:UPB a, 2 LWB b:2 UPB b]FIELD result;
OP * = (MATRIX a, b)MATRIX: ( # overload matrix times matrix #
IF 2 [LWB a:UPB a, 2 /=LWB b: OR 2 UPB a/=UPB b]FIELD resultTHEN raise index error FI;
FOR IFk 2FROM LWB a/=LWBresult bTO ORUPB 2result UPBDO result[k,]:=a/=UPB [k,]*b THEN raise index error FIOD;
result
FOR k FROM LWB result TO UPB result DO result[k,]:=a[k,]*b OD;
);
result
 
);
</pre>
# Some sample matrices to test #
test:(
MATRIX a=((1, 1, 1, 1), # matrix A #
MATRIX a=((1, 1, 1, (21), # 4,matrix A 8, 16),#
(32, 94, 27 8, 8116),
(43, 16 9, 6427, 256 81));,
(4, 16, 64, 256));
MATRIX b=(( 4 , -3 , 4/3, -1/4 ), # matrix B #
(-13/3, 19/4, -7/3, 11/24),
( 3/2, -2 , 7/6, -1/4 ),
( -1/6, 1/4, -1/6, 1/24));
MATRIX prod = a * b; # actual multiplication example of A x B #
FORMAT real fmt = $g(-6,2)$; # width of 6, with no '+' sign, 2 decimals #
PROC real matrix printf= (FORMAT real fmt, MATRIX m)VOID:(
FORMAT vector fmt = $"("n(2 UPB m-1)(f(real fmt)",")f(real fmt)")"$;
FORMAT matrix fmt = $x"("n(UPB m-1)(f(vector fmt)","lxx)f(vector fmt)");"$;
# finally print the result #
printf((matrix fmt,m))
);
# finally print the result #
print(("Product of a and b: ",new line));
real matrix printf(real fmt, prod)
EXIT
exception index error:
putf(stand error, $x"Exception: index error."l$)
)</syntaxhighlight>
Output:
{{out}}
<pre>
Product of a and b:
(( 1.00, -0.00, -0.00, -0.00),
Line 140 ⟶ 420:
( -0.00, -0.00, 1.00, -0.00),
( -0.00, -0.00, -0.00, 1.00));
</pre>
 
===Parallel processing===
Alternatively, for multicore CPUs, the following recursive algorithm can be used:
Alternatively - for multicore CPUs - use the following parallel code... The next step might be to augment with [http://www.csse.monash.edu.au/~lloyd/tildeProgLang/Algol68/strassen.a68 Strassen's O(n^log2(7)) recursive matrix multiplication algorithm]:
<u>int</u> default upb := 3;
'''int''' default upb := 3;
<u>mode</u> <u>field</u> = <u>long</u> <u>real</u>;
'''mode''' '''field''' = '''long''' '''real''';
<u>mode</u> <u>vector</u> = [default upb]<u>field</u>;
<u>'''mode</u>''' <u>matrix</u>'''vector''' = [default upb, default upb]<u>'''field</u>''';
'''mode''' '''matrix''' = [default upb, default upb]'''field''';
&cent; crude exception handling &cent;
<u>'''proc</u>''' <u>'''void</u>''' raise index error := <u>'''void</u>''': <u>'''goto</u>''' exception index error;
<u>'''sema</u>''' idle cpus = <u>'''level</u>''' ( 8 - 1 ); &cent; 8 = number of CPU cores minus parent CPU &cent;
&cent; define an operator to slice array into quarters &cent;
<u>'''op</u>''' <u>'''top</u>''' = (<u>'''matrix</u>''' m)<u>'''int</u>''': ( &lfloor;m + &lceil;m ) %2,
<u>'''bot</u>''' = (<u>'''matrix</u>''' m)<u>'''int</u>''': <u>'''top</u>''' m + 1,
<u>'''left</u>''' = (<u>'''matrix</u>''' m)<u>'''int</u>''': ( 2 &lfloor;m + 2 &lceil;m ) %2,
<u>'''right</u>''' = (<u>'''matrix</u>''' m)<u>'''int</u>''': <u>'''left</u>''' m + 1,
<u>'''left</u>''' = (<u>'''vector</u>''' v)<u>'''int</u>''': ( &lfloor;v + &lceil;v ) %2,
<u>'''right</u>''' = (<u>'''vector</u>''' v)<u>'''int</u>''': <u>'''left</u>''' v + 1;
<u>'''prio</u>''' <u>'''top</u>''' = 8, <u>'''bot</u>''' = 8, <u>'''left</u>''' = 8, <u>'''right</u>''' = 8; &cent; Operator priority - same as LWB & UPB &cent;
<u>'''op</u>''' &times; = (<u>'''vector</u>''' a, b)<u>'''field</u>''': ( &cent; dot product &cent;
<u>'''if</u>''' (&lfloor;a, &lceil;a) &ne; (&lfloor;b, &lceil;b) <u>'''then</u>''' raise index error <u>'''fi</u>''';
<u>'''if</u>''' &lfloor;a = &lceil;a <u>'''then</u>'''
a[&lceil;a] &times; b[&lceil;b]
<u>'''else</u>'''
<u>'''field</u>''' begin, end;
[]<u>'''proc</u>''' <u>'''void</u>''' schedule=(
<u>'''void</u>''': begin:=a[:<u>'''left</u>''' a] &times; b[:<u>'''left</u>''' b],
<u>'''void</u>''': end :=a[<u>'''right</u>''' a:] &times; b[<u>'''right</u>''' b:]
);
<u>'''if</u>''' <u>'''level</u>''' idle cpus = 0 <u>'''then</u>''' &cent; use current CPU &cent;
<u>'''for</u>''' thread <u>'''to</u>''' &lceil;schedule <u>'''do</u>''' schedule[thread] <u>'''od</u>'''
<u>'''else</u>'''
<u>'''par</u>''' ( &cent; run vector in parallel &cent;
schedule[1], &cent; assume parent CPU &cent;
( &darr;idle cpus; schedule[2]; &uarr;idle cpus)
)
<u>'''fi</u>''';
begin+end
<u>'''fi</u>'''
);
<u>'''op</u>''' &times; = (<u>'''matrix</u>''' a, b)<u>'''matrix</u>''': &cent; matrix multiply &cent;
<u>'''if</u>''' (&lfloor;a, 2 &lfloor;b) = (&lceil;a, 2 &lceil;b) <u>'''then</u>'''
a[&lfloor;a, ] &times; b[, 2 &lceil;b] &cent; dot product &cent;
<u>'''else</u>'''
[&lceil;a, 2 &lceil;b] <u>'''field</u>''' out;
<u>'''if</u>''' (2 &lfloor;a, 2 &lceil;a) &ne; (&lfloor;b, &lceil;b) <u>'''then</u>''' raise index error <u>'''fi</u>''';
[]<u>'''struct</u>'''(<u>'''bool</u>''' required, <u>'''proc</u>''' <u>'''void</u>''' thread) schedule = (
( <u>'''true</u>''', &cent; calculate top left corner &cent;
<u>'''void</u>''': out[:<u>'''top</u>''' a, :<u>'''left</u>''' b] := a[:<u>'''top</u>''' a, ] &times; b[, :<u>'''left</u>''' b]),
( &lfloor;a &ne; &lceil;a, &cent; calculate bottom left corner &cent;
<u>'''void</u>''': out[<u>'''bot</u>''' a:, :<u>'''left</u>''' b] := a[<u>'''bot</u>''' a:, ] &times; b[, :<u>'''left</u>''' b]),
( 2 &lfloor;b &ne; 2 &lceil;b, &cent; calculate top right corner &cent;
<u>'''void</u>''': out[:<u>'''top</u>''' a, <u>'''right</u>''' b:] := a[:<u>'''top</u>''' a, ] &times; b[, <u>'''right</u>''' b:]),
( (&lfloor;a, 2 &lfloor;b) &ne; (&lceil;a, 2 &lceil;b) , &cent; calculate bottom right corner &cent;
<u>'''void</u>''': out[<u>'''bot</u>''' a:, <u>'''right</u>''' b:] := a[<u>'''bot</u>''' a:, ] &times; b[, <u>'''right</u>''' b:])
);
<u>'''if</u>''' <u>'''level</u>''' idle cpus = 0 <u>'''then</u>''' &cent; use current CPU &cent;
<u>'''for</u>''' thread <u>'''to</u>''' &lceil;schedule <u>'''do</u>''' (required &rarr;schedule[thread] | thread &rarr;schedule[thread] ) <u>'''od</u>'''
<u>'''else</u>'''
<u>'''par</u>''' ( &cent; run vector in parallel &cent;
thread &rarr;schedule[1], &cent; thread is always required, and assume parent CPU &cent;
( required &rarr;schedule[4] | &darr;idle cpus; thread &rarr;schedule[4]; &uarr;idle cpus),
Line 209 ⟶ 491:
( required &rarr;schedule[2] | &darr;idle cpus; thread &rarr;schedule[2]; &uarr;idle cpus)
)
<u>'''fi</u>''';
out
<u>'''fi</u>''';
<u>'''format</u>''' real fmt = $g(-6,2)$; &cent; width of 6, with no '+' sign, 2 decimals &cent;
<u>'''proc</u>''' real matrix printf= (<u>'''format</u>''' real fmt, <u>'''matrix</u>''' m)<u>'''void</u>''':(
<u>'''format</u>''' vector fmt = $"("n(2 &lceil;m-1)(f(real fmt)",")f(real fmt)")"$;
<u>'''format</u>''' matrix fmt = $x"("n(&lceil;m-1)(f(vector fmt)","lxx)f(vector fmt)");"$;
&cent; finally print the result &cent;
printf((matrix fmt,m))
Line 222 ⟶ 504:
&cent; Some sample matrices to test &cent;
<u>'''matrix</u>''' a=((1, 1, 1, 1), &cent; matrix A &cent;
(2, 4, 8, 16),
(3, 9, 27, 81),
(4, 16, 64, 256));
<u>'''matrix</u>''' b=(( 4 , -3 , 4/3, -1/4 ), &cent; matrix B &cent;
(-13/3, 19/4, -7/3, 11/24),
( 3/2, -2 , 7/6, -1/4 ),
( -1/6, 1/4, -1/6, 1/24));
<u>'''matrix</u>''' c = a &times; b; &cent; actual multiplication example of A x B &cent;
print((" A x B =",new line));
real matrix printf(real fmt, c).
exception index error:
putf(stand error, $x"Exception: index error."l$)
 
=={{header|Amazing Hopper}}==
<syntaxhighlight lang="amazing hopper">
#include <hopper.h>
main:
first matrix=0, second matrix=0,a=-1
{5,2},rand array(a),mulby(10),ceil, cpy(first matrix), puts,{"\n"},puts
{2,3},rand array(a),mulby(10),ceil, cpy(second matrix), puts,{"\n"},puts
{first matrix,second matrix},mat mul, println
exit(0)
</syntaxhighlight>
Alternatively, the follow code in macro-natural-Hopper:
<syntaxhighlight lang="amazing hopper">
#include <natural.h>
#include <hopper.h>
main:
get a matrix of '5,2' integer random numbers, remember it in 'first matrix' and put it with a newline
get a matrix of '2,3' integer random numbers, remember it in 'second matrix' and put it with a newline
now take 'first matrix', and take 'second matrix', and multiply it; then, print with a new line.
exit(0)
</syntaxhighlight>
{{out}}
<pre>
2 2
1 5
3 4
6 6
4 8
 
7 1 6
6 2 4
 
26 6 20
37 11 26
45 11 34
78 18 60
76 20 56
</pre>
 
=={{header|APL}}==
Matrix multiply in APL is just <tt>+.×</tt>. For example:
 
<syntaxhighlight lang="apl"> x ← +.×
A ← ↑A*¨⊂A←⍳4 ⍝ Same A as in other examples (1 1 1 1⍪ 2 4 8 16⍪ 3 9 27 81,[0.5] 4 16 64 256)
B ← ⌹A ⍝ Matrix inverse of A
'F6.2' ⎕FMT A x B
1.00 0.00 0.00 0.00
0.00 1.00 0.00 0.00
0.00 0.00 1.00 0.00
0.00 0.00 0.00 1.00</syntaxhighlight>
 
By contrast, A×B is for element-by-element multiplication of arrays of the same shape, and if they are simple elements, this is ordinary multiplication.
 
 
 
 
 
 
 
 
 
 
 
=={{header|AppleScript}}==
{{trans|JavaScript}}
<syntaxhighlight lang="applescript">--------------------- MATRIX MULTIPLY --------------------
 
-- matrixMultiply :: Num a => [[a]] -> [[a]] -> [[a]]
to matrixMultiply(a, b)
script rows
property xs : transpose(b)
on |λ|(row)
script columns
on |λ|(col)
my dotProduct(row, col)
end |λ|
end script
map(columns, xs)
end |λ|
end script
map(rows, a)
end matrixMultiply
 
 
--------------------------- TEST -------------------------
on run
matrixMultiply({¬
{-1, 1, 4}, ¬
{6, -4, 2}, ¬
{-3, 5, 0}, ¬
{3, 7, -2} ¬
}, {¬
{-1, 1, 4, 8}, ¬
{6, 9, 10, 2}, ¬
{11, -4, 5, -3}})
--> {{51, -8, 26, -18}, {-8, -38, -6, 34},
-- {33, 42, 38, -14}, {17, 74, 72, 44}}
end run
 
 
-------------------- GENERIC FUNCTIONS -------------------
 
-- dotProduct :: [n] -> [n] -> Maybe n
on dotProduct(xs, ys)
script mult
on |λ|(a, b)
a * b
end |λ|
end script
if length of xs is not length of ys then
missing value
else
sum(zipWith(mult, xs, ys))
end if
end dotProduct
 
 
-- foldr :: (a -> b -> a) -> a -> [b] -> a
on foldr(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldr
 
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
 
 
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
 
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
 
-- product :: Num a => [a] -> a
on product(xs)
script mult
on |λ|(a, b)
a * b
end |λ|
end script
foldr(mult, 1, xs)
end product
 
 
-- sum :: Num a => [a] -> a
on sum(xs)
script add
on |λ|(a, b)
a + b
end |λ|
end script
foldr(add, 0, xs)
end sum
 
 
-- transpose :: [[a]] -> [[a]]
on transpose(xss)
script column
on |λ|(_, iCol)
script row
on |λ|(xs)
item iCol of xs
end |λ|
end script
map(row, xss)
end |λ|
end script
map(column, item 1 of xss)
end transpose
 
 
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(length of xs, length of ys)
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys)
end repeat
return lst
end tell
end zipWith</syntaxhighlight>
{{Out}}
<syntaxhighlight lang="applescript">{{51, -8, 26, -18}, {-8, -38, -6, 34}, {33, 42, 38, -14}, {17, 74, 72, 44}}</syntaxhighlight>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">printMatrix: function [m][
loop m 'row -> print map row 'val [pad to :string .format:".2f" val 6]
print "--------------------------------"
]
 
multiply: function [a,b][
X: size a
Y: size first b
result: array.of: @[X Y] 0
 
loop 0..X-1 'i [
loop 0..Y-1 'j [
loop 0..(size first a)-1 'k ->
result\[i]\[j]: result\[i]\[j] + a\[i]\[k] * b\[k]\[j]
]
]
return result
]
A: [[1.0 1.0 1.0 1.0]
[2.0 4.0 8.0 16.0]
[3.0 9.0 27.0 81.0]
[4.0 16.0 64.0 256.0]]
 
B: @[@[ 4.0 0-3.0 4/3.0 0-1/4.0]
@[0-13/3.0 19/4.0 0-7/3.0 11/24.0]
@[ 3/2.0 0-2.0 7/6.0 0-1/4.0]
@[ 0-1/6.0 1/4.0 0-1/6.0 1/24.0]]
 
printMatrix A
printMatrix B
printMatrix multiply A B
printMatrix multiply B A</syntaxhighlight>
 
{{out}}
 
<pre> 1.00 1.00 1.00 1.00
2.00 4.00 8.00 16.00
3.00 9.00 27.00 81.00
4.00 16.00 64.00 256.00
--------------------------------
4.00 -3.00 1.33 -0.25
-4.33 4.75 -2.33 0.46
1.50 -2.00 1.17 -0.25
-0.17 0.25 -0.17 0.04
--------------------------------
1.00 0.00 -0.00 -0.00
0.00 1.00 -0.00 -0.00
0.00 0.00 1.00 0.00
0.00 0.00 0.00 1.00
--------------------------------
1.00 0.00 0.00 0.00
0.00 1.00 -0.00 0.00
0.00 0.00 1.00 0.00
0.00 0.00 -0.00 1.00
--------------------------------</pre>
 
=={{header|AutoHotkey}}==
ahk [http://www.autohotkey.com/forum/topic44657-150.html discussion]
<syntaxhighlight lang="autohotkey">Matrix("b"," ; rows separated by ","
, 1 2 ; entries separated by space or tab
, 2 3
, 3 0")
MsgBox % "B`n`n" MatrixPrint(b)
Matrix("c","
, 1 2 3
, 3 2 1")
MsgBox % "C`n`n" MatrixPrint(c)
 
MatrixMul("a",b,c)
MsgBox % "B * C`n`n" MatrixPrint(a)
 
MsgBox % MatrixMul("x",b,b)
 
 
Matrix(_a,_v) { ; Matrix structure: m_0_0 = #rows, m_0_1 = #columns, m_i_j = element[i,j], i,j > 0
Local _i, _j = 0
Loop Parse, _v, `,
If (A_LoopField != "") {
_i := 0, _j ++
Loop Parse, A_LoopField, %A_Space%%A_Tab%
If (A_LoopField != "")
_i++, %_a%_%_i%_%_j% := A_LoopField
}
%_a% := _a, %_a%_0_0 := _j, %_a%_0_1 := _i
}
MatrixPrint(_a) {
Local _i = 0, _t
Loop % %_a%_0_0 {
_i++
Loop % %_a%_0_1
_t .= %_a%_%A_Index%_%_i% "`t"
_t .= "`n"
}
Return _t
}
MatrixMul(_a,_b,_c) {
Local _i = 0, _j, _k, _s
If (%_b%_0_0 != %_c%_0_1)
Return "ERROR: inner dimensions " %_b%_0_0 " != " %_c%_0_1
%_a% := _a, %_a%_0_0 := %_b%_0_0, %_a%_0_1 := %_c%_0_1
Loop % %_c%_0_1 {
_i++, _j := 0
Loop % %_b%_0_0 {
_j++, _k := _s := 0
Loop % %_b%_0_1
_k++, _s += %_b%_%_k%_%_j% * %_c%_%_i%_%_k%
%_a%_%_i%_%_j% := _s
}
}
}</syntaxhighlight>
===Using Objects===
<syntaxhighlight lang="autohotkey">Multiply_Matrix(A,B){
if (A[1].Count() <> B.Count())
return ["Dimension Error"]
R := [], RRows := A.Count(), RCols:= b[1].Count()
Loop, % RRows {
RRow:=A_Index
loop, % RCols {
RCol:=A_Index, v := 0
loop % A[1].Count()
col := A_Index, v += A[RRow, col] * B[col, RCol]
R[RRow,RCol] := v
}
}
return R
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">A := [[1,2]
, [3,4]
, [5,6]
, [7,8]]
 
B := [[1,2,3]
, [4,5,6]]
 
if Res := Multiply_Matrix(A,B)
MsgBox % Print(Res)
else
MsgBox Error
return
Print(M){
for i, row in M
for j, col in row
Res .= (A_Index=1?"":"`t") col (Mod(A_Index,M[1].MaxIndex())?"":"`n")
return Trim(Res,"`n")
}</syntaxhighlight>
{{out}}
<pre>9 12 15
19 26 33
29 40 51
39 54 69</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk"># Usage: GAWK -f MATRIX_MULTIPLICATION.AWK filename
# Separate matrices a and b by a blank line
BEGIN {
ranka1 = 0; ranka2 = 0
rankb1 = 0; rankb2 = 0
matrix = 1 # Indicate first (1) or second (2) matrix
i = 0
}
NF == 0 {
if (++matrix > 2) {
printf("Warning: Ignoring data below line %d.\n", NR)
}
i = 0
next
}
{
# Store first matrix in a, second matrix in b
if (matrix == 1) {
ranka1 = ++i
ranka2 = max(ranka2, NF)
for (j = 1; j <= NF; j++)
a[i,j] = $j
}
if (matrix == 2) {
rankb1 = ++i
rankb2 = max(rankb2, NF)
for (j = 1; j <= NF; j++)
b[i,j] = $j
}
}
END {
# Check ranks of a and b
if ((ranka1 < 1) || (ranka2 < 1) || (rankb1 < 1) || (rankb2 < 1) ||
(ranka2 != rankb1)) {
printf("Error: Incompatible ranks (%dx%d)*(%dx%d).\n", ranka1, ranka2, rankb1, rankb2)
exit
}
# Multiplication c = a * b
for (i = 1; i <= ranka1; i++) {
for (j = 1; j <= rankb2; j++) {
c[i,j] = 0
for (k = 1; k <= ranka2; k++)
c[i,j] += a[i,k] * b[k,j]
}
}
# Print matrix c
for (i = 1; i <= ranka1; i++) {
for (j = 1; j <= rankb2; j++)
printf("%g%s", c[i,j], j < rankb2 ? " " : "\n")
}
}
function max(m, n) {
return m > n ? m : n
}</syntaxhighlight>
<p><b>Input:</b></p>
<pre>
6.5 2 3
4.5 1 5
 
10 16 23 50
12 -8 16 -4
70 60 -1 -2
</pre>
{{out}}
<pre>
299. 268. 178.5 311.
407. 364. 114.5 211.
</pre>
 
=={{header|BASIC}}==
{{works with|QuickBasic|4.5}}
{{trans|Java}}
<syntaxhighlight lang="qbasic">Assume the matrices to be multiplied are a and b
 
Assume the matrices to be multiplied are a and b
IF (LEN(a,2) = LEN(b)) 'if valid dims
n = LEN(a,2)
Line 281 ⟶ 1,000:
ELSE
PRINT "invalid dimensions"
END IF</syntaxhighlight>
 
==={{header|CApplesoft BASIC}}===
A nine-liner that fits on one screen. The code and variable names are similar to [[#BASIC|BASIC]] with DATA from [[Full_BASIC|Full BASIC]].
{{works with|gcc|<nowiki>4.1.2 20070925 (Red Hat 4.1.2-27) Options: gcc -std=gnu99</nowiki>}}
<syntaxhighlight lang="gwbasic"> 1 FOR K = 0 TO 1:M = O:N = P: READ O,P: IF K THEN DIM B(O,P): IF N < > O THEN PRINT "INVALID DIMENSIONS": STOP
<c>
2 IF NOT K THEN DIM A(O,P)
#include <stdio.h>
3 FOR I = 1 TO O: FOR J = 1 TO P: IF K THEN READ B(I,J)
#define dim 4 /* fixed length square matrices */
4 IF NOT K THEN READ A(I,J)
const int SLICE=0; /* coder hints */
5 NEXT J,I,K: DIM AB(M,P): FOR I = 1 TO M: FOR J = 1 TO P: FOR K = 1 TO N:AB(I,J) = AB(I,J) + (A(I,K) * B(K,J)): NEXT K,J,I: FOR I = 1 TO M: FOR J = 1 TO P: PRINT MID$ (S$,1 + (J = 1),1)AB(I,J);:S$ = " " + CHR$ (13): NEXT J,I
typedef double field_t; /* field_t type is long float */
10000 DATA4,2
typedef field_t vec_t[dim];
10010 DATA1,2,3,4,5,6,7,8
typedef field_t *ref_vec_t; /* address of first element */
20000 DATA2,3
typedef vec_t matrix_t[dim];
20010 DATA1,2,3,4,5,6</syntaxhighlight>
typedef field_t *ref_matrix_t; /* address of first element */
typedef char* format;
 
===Full BASIC===
/* define the vector/matrix_t operators */
{{works with|Full BASIC}}
{{trans|BBC_BASIC}}
<syntaxhighlight lang="basic">DIM matrix1(4,2),matrix2(2,3)
 
MAT READ matrix1
field_t v_times_v (vec_t a, vec_t b, int step_b){
DATA 1,2
/* basically the dot product if step_b==1*/
DATA 3,4
field_t result=0;
DATA 5,6
for( int i=0; i<sizeof a; i++ )
DATA 7,8
result+= a[i]*b[i*step_b];
return result;
}
 
MAT READ matrix2
ref_vec_t v_eq_v_times_m(vec_t result, vec_t a, matrix_t b){
DATA 1,2,3
for( int j=0; j<sizeof b; j++ )
DATA 4,5,6
result[j]=v_times_v(a,&b[SLICE][j],sizeof b[SLICE] / sizeof (field_t));
return &result[SLICE];
}
 
MAT product=matrix1*matrix2
ref_matrix_t m_eq_m_times_m (matrix_t result, matrix_t a, matrix_t b){
MAT PRINT product</syntaxhighlight>
for( int k=0; k<sizeof result; k++ )
{{out}}
v_eq_v_times_m(&result[k][SLICE],&a[k][SLICE],b);
<pre> 9 12 15
return &result[SLICE][SLICE];
19 26 33
}
29 40 51
39 54 69 </pre>
 
=={{header|BBC BASIC}}==
/* Some sample matrices to test */
BBC BASIC has built-in matrix multiplication
matrix_t a={{1, 1, 1, 1}, /* matrix_t A */
(assumes default lower bound of 0):
{2, 4, 8, 16},
{3, 9, 27, 81},
{4, 16, 64, 256}};
 
<syntaxhighlight lang="bbcbasic"> DIM matrix1(3,1), matrix2(1,2), product(3,2)
matrix_t b={{ 4.0 , -3.0 , 4.0/3, -1.0/4 }, /* matrix_t B */
{-13.0/3, 19.0/4, -7.0/3, 11.0/24},
matrix1() = { 3.0/21, -2.0 , 7.0/6, -1.0/4 },\
\ { -1.0/6, 1.0/4 3, -1.0/64, 1.0/24}};\
\ 5, 6, \
\ 7, 8
matrix2() = 1, 2, 3, \
\ 4, 5, 6
product() = matrix1() . matrix2()
 
FOR row% = 0 TO DIM(product(),1)
int main(){
FOR col% = 0 TO DIM(product(),2)
matrix_t prod;
PRINT product(row%,col%),;
m_eq_m_times_m(prod,a,b); /* actual multiplication example of A x B */
NEXT
PRINT
NEXT
</syntaxhighlight>
{{out}}
<pre> 9 12 15
19 26 33
29 40 51
39 54 69</pre>
 
=={{header|BQN}}==
#define field_fmt "%6.2f" /* width of 6, with no '+' sign, 2 decimals */
<code>Mul</code> is a matrix multiplication idiom from [https://mlochbaum.github.io/bqncrate/ BQNcrate.]
#define vec_fmt "{"field_fmt","field_fmt","field_fmt","field_fmt"}"
#define matrix_fmt " {"vec_fmt",\n "vec_fmt",\n "vec_fmt",\n "vec_fmt"};"
format result_fmt = " Product of a and b: \n"matrix_fmt"\n";
 
<syntaxhighlight lang="bqn">Mul ← +˝∘×⎉1‿∞
/* finally print the result */
 
vprintf(result_fmt,(void*)&prod);
(>⟨
⟨1, 2, 3⟩
⟨4, 5, 6⟩
⟨7, 8, 9⟩
⟩) Mul >⟨
⟨1, 2, 3, 4⟩
⟨5, 6, 7, 8⟩
⟨9, 10, 11, 12⟩
⟩</syntaxhighlight><syntaxhighlight lang="bqn">┌─
╵ 20 23 26 29
56 68 80 92
92 113 134 155
┘</syntaxhighlight>
[https://mlochbaum.github.io/BQN/try.html#code=TXVsIOKGkCAry53iiJjDl+KOiTHigL/iiJ4KCig+4p+oCiAg4p+oMSwgMiwgM+KfqQogIOKfqDQsIDUsIDbin6kKICDin6g3LCA4LCA54p+pCuKfqSkgTXVsID7in6gKICDin6gxLCAgMiwgIDMsIDTin6kKICDin6g1LCAgNiwgIDcsIDjin6kKICDin6g5LCAxMCwgMTEsIDEy4p+pCuKfqQo= Try It!]
 
=={{header|Burlesque}}==
 
<syntaxhighlight lang="burlesque">
blsq ) {{1 2}{3 4}{5 6}{7 8}}{{1 2 3}{4 5 6}}mmsp
9 12 15
19 26 33
29 40 51
39 54 69
</syntaxhighlight>
 
=={{header|C}}==
<syntaxhighlight lang="c">#include <stdio.h>
 
#define MAT_ELEM(rows,cols,r,c) (r*cols+c)
 
//Improve performance by assuming output matrices do not overlap with
//input matrices. If this is C++, use the __restrict extension instead
#ifdef __cplusplus
typedef double * const __restrict MAT_OUT_t;
#else
typedef double * const restrict MAT_OUT_t;
#endif
typedef const double * const MAT_IN_t;
 
static inline void mat_mult(
const int m,
const int n,
const int p,
MAT_IN_t a,
MAT_IN_t b,
MAT_OUT_t c)
{
for (int row=0; row<m; row++) {
for (int col=0; col<p; col++) {
c[MAT_ELEM(m,p,row,col)] = 0;
for (int i=0; i<n; i++) {
c[MAT_ELEM(m,p,row,col)] += a[MAT_ELEM(m,n,row,i)]*b[MAT_ELEM(n,p,i,col)];
}
}
}
}
</c>
Output:
Product of a and b:
{{ 1.00, 0.00, -0.00, -0.00},
{ 0.00, 1.00, -0.00, -0.00},
{ 0.00, 0.00, 1.00, -0.00},
{ 0.00, 0.00, 0.00, 1.00}};
 
static inline void mat_show(
=={{header|Common Lisp}}==
const int m,
(defun matrix-multiply (a b)
const int p,
(flet ((col (mat i) (mapcar #'(lambda (row) (elt row i)) mat))
MAT_IN_t a)
(row (mat i) (elt mat i)))
{
(loop for row from 0 below (length a)
for (int row=0; row<m;row++) {
collect (loop for col from 0 below (length (row b 0))
collectfor (applyint #'+ (mapcar #'* (row a row) (col b=0; col<p;col++))))))) {
printf("\t%7.3f", a[MAT_ELEM(m,p,row,col)]);
}
;; example use:
putchar('\n');
(matrix-multiply '((1 2) (3 4)) '((-3 -8 3) (-2 1 4)))
}
}
 
int main(void)
{
double a[4*4] = {1, 1, 1, 1,
2, 4, 8, 16,
3, 9, 27, 81,
4, 16, 64, 256};
 
double b[4*3] = { 4.0, -3.0, 4.0/3,
(defun matrix-multiply (matrix1 matrix2)
-13.0/3, 19.0/4, -7.0/3,
(mapcar
3.0/2, -2.0, 7.0/6,
(lambda (row)
-1.0/6, 1.0/4, -1.0/6};
(apply #'mapcar
(lambda (&rest column)
(apply #'+ (mapcar #'* row column))) matrix2)) matrix1))
 
double c[4*3] = {0};
=={{header|D}}==
mat_mult(4,4,3,a,b,c);
mat_show(4,3,c);
return 0;
}
 
</syntaxhighlight>
 
=={{header|C sharp|C#}}==
 
This code should work with any version of the .NET Framework and C# language
 
==={{header|Class}}===
 
<syntaxhighlight lang="csharp">public class Matrix
{
int n;
int m;
double[,] a;
 
public Matrix(int n, int m)
{
if (n <= 0 || m <= 0)
throw new ArgumentException("Matrix dimensions must be positive");
this.n = n;
this.m = m;
a = new double[n, m];
}
 
//indices start from one
public double this[int i, int j]
{
get { return a[i - 1, j - 1]; }
set { a[i - 1, j - 1] = value; }
}
 
public int N { get { return n; } }
public int M { get { return m; } }
 
public static Matrix operator*(Matrix _a, Matrix b)
{
int n = _a.N;
int m = b.M;
int l = _a.M;
if (l != b.N)
throw new ArgumentException("Illegal matrix dimensions for multiplication. _a.M must be equal b.N");
Matrix result = new Matrix(_a.N, b.M);
for(int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
double sum = 0.0;
for (int k = 0; k < l; k++)
sum += _a.a[i, k]*b.a[k, j];
result.a[i, j] = sum;
}
return result;
}
}</syntaxhighlight>
 
==={{header|Extension Method}}===
Implementation of matrix multiplication and matrix display for 2D arrays using an extension method
 
<syntaxhighlight lang="csharp">
public static class LinearAlgebra
{
public static double[,] Product(this double[,] a, double[,] b)
{
int na = a.GetLength(0), ma = a.GetLength(1);
int nb = b.GetLength(0), mb = b.GetLength(1);
 
if (ma != nb)
{
throw new ArgumentException("Incompatible Matrix Sizes.", nameof(b));
}
double[,] c = new double[na, mb];
for (int i = 0; i < na; i++)
{
for (int j = 0; j < mb; j++)
{
double sum = 0;
for (int k = 0; k < ma; k++)
{
sum += a[i, k] * b[k, j];
}
c[i, j] = sum;
}
}
return c;
}
public static string Show(this double[,] a, string formatting = "g4", int columnWidth = 12)
{
int na = a.GetLength(0), ma = a.GetLength(1);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < na; i++)
{
sb.Append("|");
for (int j = 0; j < ma; j++)
{
sb.Append(" ");
if (columnWidth > 0)
{
sb.Append(a[i, j].ToString(formatting).PadLeft(columnWidth));
}
else if (columnWidth < 0)
{
sb.Append(a[i, j].ToString(formatting).PadRight(columnWidth));
}
else
{
throw new ArgumentOutOfRangeException(nameof(columnWidth), "Must be non-negative");
}
}
sb.AppendLine(" |");
}
return sb.ToString();
}
}
class Program
{
static void Main(string[] args)
{
double[,] A = new double[,] { { 1, 2, 3 }, { 4, 5, 6 } };
double[,] B = new double[,] { { 8, 7, 6 }, { 5, 4, 3 }, { 2, 1, 0 } };
 
double[,] C = A.Product(B);
Console.WriteLine("A=");
Console.WriteLine(A.Show("f4", 8));
Console.WriteLine("B=");
Console.WriteLine(B.Show("f4", 8));
Console.WriteLine("C=A*B");
Console.WriteLine(C.Show("f4", 8));
 
}
}
</syntaxhighlight>
 
{{out}}
<pre>
A=
import std.stdio: writefln;
| 1.0000 2.0000 3.0000 |
import std.string: format, join;
| 4.0000 5.0000 6.0000 |
 
B=
T[][] matrixMul(T)(T[][] m1, T[][] m2) {
| 8.0000 7.0000 6.0000 |
bool isRectangular(T[][] matrix) {
| 5.0000 4.0000 foreach (row;3.0000 matrix)|
| 2.0000 1.0000 0.0000 |
if (row.length != matrix[0].length)
 
return false;
C=A*B
return true;
| 24.0000 18.0000 12.0000 |
| 69.0000 54.0000 39.0000 |
</pre>
 
=={{header|C++}}==
 
{{works with|Visual C++ 2010}}
 
{{libheader|Blitz++}}
<syntaxhighlight lang="cpp">#include <iostream>
#include <blitz/tinymat.h>
 
int main()
{
using namespace blitz;
 
TinyMatrix<double,3,3> A, B, C;
 
A = 1, 2, 3,
4, 5, 6,
7, 8, 9;
 
B = 1, 0, 0,
0, 1, 0,
0, 0, 1;
 
C = product(A, B);
 
std::cout << C << std::endl;
}</syntaxhighlight>
{{out}}
(3,3):
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
 
===Generic solution===
main.cpp
<syntaxhighlight lang="cpp">
#include <iostream>
#include "matrix.h"
 
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif
 
int main() {
int am[2][3] = {
{1,2,3},
{4,5,6},
};
int bm[3][2] = {
{1,2},
{3,4},
{5,6}
};
 
Matrix<int> a(ARRAY_SIZE(am), ARRAY_SIZE(am[0]), am[0], ARRAY_SIZE(am)*ARRAY_SIZE(am[0]));
Matrix<int> b(ARRAY_SIZE(bm), ARRAY_SIZE(bm[0]), bm[0], ARRAY_SIZE(bm)*ARRAY_SIZE(bm[0]));
Matrix<int> c;
 
try {
c = a * b;
for (unsigned int i = 0; i < c.rowNum(); i++) {
for (unsigned int j = 0; j < c.colNum(); j++) {
std::cout << c[i][j] << " ";
}
std::cout << std::endl;
}
} catch (MatrixException& e) {
std::cerr << e.message() << std::endl;
return e.errorCode();
}
 
} /* main() */
T[][] result;
</syntaxhighlight>
if (isRectangular(m1) && isRectangular(m2) && m1[0].length == m2.length) {
 
result = new T[][](m1.length, m2[0].length);
matrix.h
<syntaxhighlight lang="cpp">
#ifndef _MATRIX_H
#define _MATRIX_H
 
#include <sstream>
#include <string>
#include <vector>
 
#define MATRIX_ERROR_CODE_COUNT 5
#define MATRIX_ERR_UNDEFINED "1 Undefined exception!"
#define MATRIX_ERR_WRONG_ROW_INDEX "2 The row index is out of range."
#define MATRIX_ERR_MUL_ROW_AND_COL_NOT_EQUAL "3 The row number of second matrix must be equal with the column number of first matrix!"
#define MATRIX_ERR_MUL_ROW_AND_COL_BE_GREATER_THAN_ZERO "4 The number of rows and columns must be greater than zero!"
#define MATRIX_ERR_TOO_FEW_DATA "5 Too few data in matrix."
 
class MatrixException {
private:
std::string message_;
int errorCode_;
public:
MatrixException(std::string message = MATRIX_ERR_UNDEFINED);
 
inline std::string message() {
return message_;
};
 
inline int errorCode() {
return errorCode_;
};
};
 
MatrixException::MatrixException(std::string message) {
errorCode_ = MATRIX_ERROR_CODE_COUNT + 1;
std::stringstream ss(message);
ss >> errorCode_;
if (errorCode_ < 1) {
errorCode_ = MATRIX_ERROR_CODE_COUNT + 1;
}
std::string::size_type pos = message.find(' ');
if (errorCode_ <= MATRIX_ERROR_CODE_COUNT && pos != std::string::npos) {
message_ = message.substr(pos + 1);
} else {
message_ = message + " (This an unknown and unsupported exception!)";
}
}
 
/**
* Generic class for matrices.
*/
template <class T>
class Matrix {
private:
std::vector<T> v; // the data of matrix
unsigned int m; // the number of rows
unsigned int n; // the number of columns
protected:
 
virtual void clear() {
v.clear();
m = n = 0;
}
public:
 
Matrix() {
clear();
}
Matrix(unsigned int, unsigned int, T* = 0, unsigned int = 0);
Matrix(unsigned int, unsigned int, const std::vector<T>&);
 
virtual ~Matrix() {
clear();
}
Matrix& operator=(const Matrix&);
std::vector<T> operator[](unsigned int) const;
Matrix operator*(const Matrix&);
 
inline unsigned int rowNum() const {
return m;
}
 
inline unsigned int colNum() const {
return n;
}
 
inline unsigned int size() const {
return v.size();
}
 
inline void add(const T& t) {
v.push_back(t);
}
};
 
template <class T>
foreach (i, m1_row_i; m1)
Matrix<T>::Matrix(unsigned int row, unsigned int col, T* data, unsigned int dataLength) {
for (int j; j < m2[0].length; j++) {
clear();
T aux = 0;
if (row > 0 && col > 0) foreach (k, m2_row_k; m2){
m aux += m1_row_i[k] * m2_row_k[j]row;
result[i][j]n = auxcol;
unsigned int mxn = m * n;
if (dataLength && data) {
for (unsigned int i = 0; i < dataLength && i < mxn; i++) {
v.push_back(data[i]);
}
} else }
}
throw new Exception("matrixMul Error");
}
 
template <class T>
Matrix<T>::Matrix(unsigned int row, unsigned int col, const std::vector<T>& data) {
clear();
if (row > 0 && col > 0) {
m = row;
n = col;
unsigned int mxn = m * n;
if (data.size() > 0) {
for (unsigned int i = 0; i < mxn && i < data.size(); i++) {
v.push_back(data[i]);
}
}
}
}
 
template<class T>
Matrix<T>& Matrix<T>::operator=(const Matrix<T>& other) {
clear();
if (other.m > 0 && other.n > 0) {
m = other.m;
n = other.n;
unsigned int mxn = m * n;
for (unsigned int i = 0; i < mxn && i < other.size(); i++) {
v.push_back(other.v[i]);
}
}
return *this;
}
 
template<class T>
std::vector<T> Matrix<T>::operator[](unsigned int index) const {
std::vector<T> result;
if (index >= m) {
throw MatrixException(MATRIX_ERR_WRONG_ROW_INDEX);
} else if ((index + 1) * n > size()) {
throw MatrixException(MATRIX_ERR_TOO_FEW_DATA);
} else {
unsigned int begin = index * n;
unsigned int end = begin + n;
for (unsigned int i = begin; i < end; i++) {
result.push_back(v[i]);
}
}
return result;
}
 
template<class T>
string prettyPrint(T)(T[][] matrix) {
Matrix<T> Matrix<T>::operator*(const Matrix<T>& other) {
string[] result;
foreachMatrix result(row;m, matrixother.n);
if (n result ~!= format(rowother.m); {
throw MatrixException(MATRIX_ERR_MUL_ROW_AND_COL_NOT_EQUAL);
return "[" ~ result.join(",\n ") ~ "]";
} else if (m <= 0 || n <= 0 || other.n <= 0) {
throw MatrixException(MATRIX_ERR_MUL_ROW_AND_COL_BE_GREATER_THAN_ZERO);
} else if (m * n > size() || other.m * other.n > other.size()) {
throw MatrixException(MATRIX_ERR_TOO_FEW_DATA);
} else {
for (unsigned int i = 0; i < m; i++) {
for (unsigned int j = 0; j < other.n; j++) {
T temp = v[i * n] * other.v[j];
for (unsigned int k = 1; k < n; k++) {
temp += v[i * n + k] * other.v[k * other.n + j];
}
result.v.push_back(temp);
}
}
}
return result;
}
 
#endif /* _MATRIX_H */
</syntaxhighlight>
 
{{out}}
<pre>
22 28
49 64
</pre>
 
=={{header|Ceylon}}==
<syntaxhighlight lang="ceylon">alias Matrix => Integer[][];
 
void printMatrix(Matrix m) {
value strings = m.collect((row) => row.collect(Integer.string));
value maxLength = max(expand(strings).map(String.size)) else 0;
value padded = strings.collect((row) => row.collect((s) => s.padLeading(maxLength)));
for (row in padded) {
print("[``", ".join(row)``]");
}
}
 
Matrix? multiplyMatrices(Matrix a, Matrix b) {
function rectangular(Matrix m) =>
if (exists firstRow = m.first)
then m.every((row) => row.size == firstRow.size)
else false;
function rowCount(Matrix m) => m.size;
function columnCount(Matrix m) => m[0]?.size else 0;
if (!rectangular(a) || !rectangular(b) || columnCount(a) != rowCount(b)) {
return null;
}
function getNumber(Matrix m, Integer x, Integer y) {
assert (exists number = m[y]?.get(x));
return number;
}
function getRow(Matrix m, Integer rowIndex) {
assert (exists row = m[rowIndex]);
return row;
}
function getColumn(Matrix m, Integer columnIndex) => {
for (y in 0:rowCount(m))
getNumber(m, columnIndex, y)
};
return [
for (y in 0:rowCount(a)) [
for (x in 0:columnCount(b))
sum { 0, for ([a1, b1] in zipPairs(getRow(a, y), getColumn(b, x))) a1 * b1 }
]
];
}
 
shared void run() {
value m = [[1, 2, 3], [4, 5, 6]];
printMatrix(m);
print("---------");
print("multiplied by");
value m2 = [[7, 8], [9, 10], [11, 12]];
printMatrix(m2);
print("---------");
print("equals:");
value result = multiplyMatrices(m, m2);
if (exists result) {
printMatrix(result);
}
else {
print("something went wrong!");
}
}</syntaxhighlight>
{{out}}
<pre>[1, 2, 3]
[4, 5, 6]
---------
multiplied by
[ 7, 8]
[ 9, 10]
[11, 12]
---------
equals:
[ 58, 64]
[139, 154]</pre>
 
=={{header|Chapel}}==
 
Overload the '*' operator for arrays
<syntaxhighlight lang="chapel">proc *(a:[], b:[]) {
 
if (a.eltType != b.eltType) then
writeln("type mismatch: ", a.eltType, " ", b.eltType);
 
var ad = a.domain.dims();
var bd = b.domain.dims();
var (arows, acols) = ad;
var (brows, bcols) = bd;
if (arows != bcols) then
writeln("dimension mismatch: ", ad, " ", bd);
 
var c:[{arows, bcols}] a.eltType = 0;
 
for i in arows do
for j in bcols do
for k in acols do
c(i,j) += a(i,k) * b(k,j);
 
return c;
}</syntaxhighlight>
 
example usage (I could not figure out the syntax for multi-dimensional array literals)
<syntaxhighlight lang="chapel">var m1:[{1..2, 1..2}] int;
m1(1,1) = 1; m1(1,2) = 2;
m1(2,1) = 3; m1(2,2) = 4;
writeln(m1);
 
var m2:[{1..2, 1..2}] int;
m2(1,1) = 2; m2(1,2) = 3;
m2(2,1) = 4; m2(2,2) = 5;
writeln(m2);
 
var m3 = m1 * m2;
writeln(m3);
 
var m4:[{1..2, 1..3}] int;
m4(1, 1) = 1; m4(1, 2) = 2; m4(1, 3) = 3;
m4(2, 1) = 4; m4(2, 2) = 5; m4(2, 3) = 6;
writeln(m4);
 
var m5:[{1..3, 1..2}] int;
m5(1, 1) = 6; m5(1, 2) = -1;
m5(2, 1) = 3; m5(2, 2) = 2;
m5(3, 1) = 0; m5(3, 2) = -3;
writeln(m5);
 
writeln(m4 * m5);</syntaxhighlight>
 
=={{header|Clojure}}==
 
<syntaxhighlight lang="lisp">
(defn transpose
[s]
(apply map vector s))
 
(defn nested-for
[f x y]
(map (fn [a]
(map (fn [b]
(f a b)) y))
x))
 
(defn matrix-mult
[a b]
(nested-for (fn [x y] (reduce + (map * x y))) a (transpose b)))
 
(def ma [[1 1 1 1] [2 4 8 16] [3 9 27 81] [4 16 64 256]])
(def mb [[4 -3 4/3 -1/4] [-13/3 19/4 -7/3 11/24] [3/2 -2 7/6 -1/4] [-1/6 1/4 -1/6 1/24]])</syntaxhighlight>
 
{{out}}
<pre>
=> (matrix-mult ma mb)
((1 0 0 0) (0 1 0 0) (0 0 1 0) (0 0 0 1))
</pre>
 
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defun matrix-multiply (a b)
(flet ((col (mat i) (mapcar #'(lambda (row) (elt row i)) mat))
(row (mat i) (elt mat i)))
(loop for row from 0 below (length a)
collect (loop for col from 0 below (length (row b 0))
collect (apply #'+ (mapcar #'* (row a row) (col b col)))))))
 
;; example use:
(matrix-multiply '((1 2) (3 4)) '((-3 -8 3) (-2 1 4)))</syntaxhighlight>
 
<syntaxhighlight lang="lisp">(defun matrix-multiply (matrix1 matrix2)
(mapcar
(lambda (row)
(apply #'mapcar
(lambda (&rest column)
(apply #'+ (mapcar #'* row column))) matrix2)) matrix1))</syntaxhighlight>
 
The following version uses 2D arrays as inputs.
 
<syntaxhighlight lang="lisp">(defun mmul (A B)
(let* ((m (car (array-dimensions A)))
(n (cadr (array-dimensions A)))
(l (cadr (array-dimensions B)))
(C (make-array `(,m ,l) :initial-element 0)))
(loop for i from 0 to (- m 1) do
(loop for k from 0 to (- l 1) do
(setf (aref C i k)
(loop for j from 0 to (- n 1)
sum (* (aref A i j)
(aref B j k))))))
C))</syntaxhighlight>
 
Example use:
 
<syntaxhighlight lang="lisp">(mmul #2a((1 2) (3 4)) #2a((-3 -8 3) (-2 1 4)))
#2A((-7 -6 11) (-17 -20 25))
</syntaxhighlight>
 
Another version:
 
<syntaxhighlight lang="lisp">(defun mmult (a b)
(loop
with m = (array-dimension a 0)
with n = (array-dimension a 1)
with l = (array-dimension b 1)
with c = (make-array (list m l) :initial-element 0)
for i below m do
(loop for k below l do
(setf (aref c i k)
(loop for j below n
sum (* (aref a i j)
(aref b j k)))))
finally (return c)))</syntaxhighlight>
 
=={{header|D}}==
===Basic Version===
<syntaxhighlight lang="d">import std.stdio, std.string, std.conv, std.numeric,
std.array, std.algorithm;
 
bool isRectangular(T)(in T[][] M) pure nothrow {
return M.all!(row => row.length == M[0].length);
}
 
T[][] matrixMul(T)(in T[][] A, in T[][] B) pure nothrow
in {
assert(A.isRectangular && B.isRectangular &&
!A.empty && !B.empty && A[0].length == B.length);
} body {
auto result = new T[][](A.length, B[0].length);
auto aux = new T[B.length];
 
foreach (immutable j; 0 .. B[0].length) {
foreach (immutable k, const row; B)
aux[k] = row[j];
foreach (immutable i, const ai; A)
result[i][j] = dotProduct(ai, aux);
}
 
return result;
}
 
void main() {
float[][]immutable a = [[1, 2], [3, 4], [3, 6]];
float[][]immutable b = [[-3, -8, 3,], [-2, 1, 4]];
 
writefln("Aimmutable form = \n"[%([%(%d, prettyPrint(a%)],\n %)]]";
writefln("\nBA = \n" ~ form ~ "\n", prettyPrint(b)a);
writefln("\nA * B = \n", prettyPrint(matrixMul(a~ form ~ "\n", b)));
writefln("A * B = \n" ~ form, matrixMul(a, b));
}</syntaxhighlight>
{{out}}
<pre>A =
[[1, 2],
[3, 4],
[3, 6]]
 
B =
[[-3, -8, 3],
[-2, 1, 4]]
 
A * B =
[[-7, -6, 11],
[-17, -20, 25],
[-21, -18, 33]]</pre>
 
===Short Version===
<syntaxhighlight lang="d">import std.stdio, std.range, std.array, std.numeric, std.algorithm;
 
T[][] matMul(T)(in T[][] A, in T[][] B) pure nothrow /*@safe*/ {
const Bt = B[0].length.iota.map!(i=> B.transversal(i).array).array;
return A.map!(a => Bt.map!(b => a.dotProduct(b)).array).array;
}
 
void main() {
immutable a = [[1, 2], [3, 4], [3, 6]];
immutable b = [[-3, -8, 3,], [-2, 1, 4]];
 
immutable form = "[%([%(%d, %)],\n %)]]";
writefln("A = \n" ~ form ~ "\n", a);
writefln("B = \n" ~ form ~ "\n", b);
writefln("A * B = \n" ~ form, matMul(a, b));
}</syntaxhighlight>
The output is the same.
 
===Pure Short Version===
<syntaxhighlight lang="d">import std.stdio, std.range, std.numeric, std.algorithm;
 
T[][] matMul(T)(immutable T[][] A, immutable T[][] B) pure nothrow {
immutable Bt = B[0].length.iota.map!(i=> B.transversal(i).array)
.array;
return A.map!((in a) => Bt.map!(b => a.dotProduct(b)).array).array;
}
 
void main() {
immutable a = [[1, 2], [3, 4], [3, 6]];
immutable b = [[-3, -8, 3,], [-2, 1, 4]];
 
immutable form = "[%([%(%d, %)],\n %)]]";
writefln("A = \n" ~ form ~ "\n", a);
writefln("B = \n" ~ form ~ "\n", b);
writefln("A * B = \n" ~ form, matMul(a, b));
}</syntaxhighlight>
The output is the same.
 
===Stronger Statically Typed Version===
All array sizes are verified at compile-time (and no matrix is copied).
Same output.
<syntaxhighlight lang="d">import std.stdio, std.string, std.numeric, std.algorithm, std.traits;
 
alias TMMul_helper(M1, M2) = Unqual!(ForeachType!(ForeachType!M1))
[M2.init[0].length][M1.length];
 
void matrixMul(T, T2, size_t k, size_t m, size_t n)
(in ref T[m][k] A, in ref T[n][m] B,
/*out*/ ref T2[n][k] result) pure nothrow /*@safe*/ @nogc
if (is(T2 == Unqual!T)) {
static if (hasIndirections!T)
T2[m] aux;
else
T2[m] aux = void;
 
foreach (immutable j; 0 .. n) {
foreach (immutable i, const ref bi; B)
aux[i] = bi[j];
foreach (immutable i, const ref ai; A)
result[i][j] = dotProduct(ai, aux);
}
}
 
void main() {
immutable int[2][3] a = [[1, 2], [3, 4], [3, 6]];
immutable int[3][2] b = [[-3, -8, 3,], [-2, 1, 4]];
 
enum form = "[%([%(%d, %)],\n %)]]";
writefln("A = \n" ~ form ~ "\n", a);
writefln("B = \n" ~ form ~ "\n", b);
TMMul_helper!(typeof(a), typeof(b)) result = void;
matrixMul(a, b, result);
writefln("A * B = \n" ~ form, result);
}</syntaxhighlight>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
<syntaxhighlight lang="delphi">
program Matrix_multiplication;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
type
TMatrix = record
values: array of array of Double;
Rows, Cols: Integer;
constructor Create(Rows, Cols: Integer);
class operator Multiply(a: TMatrix; b: TMatrix): TMatrix;
function ToString: string;
end;
 
{ TMatrix }
 
constructor TMatrix.Create(Rows, Cols: Integer);
var
i: Integer;
begin
Self.Rows := Rows;
self.Cols := Cols;
SetLength(values, Rows);
for i := 0 to High(values) do
SetLength(values[i], Cols);
end;
 
class operator TMatrix.Multiply(a, b: TMatrix): TMatrix;
var
rows, cols, l: Integer;
i, j: Integer;
sum: Double;
k: Integer;
begin
rows := a.Rows;
cols := b.Cols;
l := a.Cols;
if l <> b.Rows then
raise Exception.Create('Illegal matrix dimensions for multiplication');
result := TMatrix.create(a.rows, b.Cols);
for i := 0 to rows - 1 do
for j := 0 to cols - 1 do
begin
sum := 0.0;
for k := 0 to l - 1 do
sum := sum + (a.values[i, k] * b.values[k, j]);
result.values[i, j] := sum;
end;
end;
 
function TMatrix.ToString: string;
var
i, j: Integer;
begin
Result := '[';
for i := 0 to 2 do
begin
if i > 0 then
Result := Result + #10;
Result := Result + '[';
for j := 0 to 2 do
begin
if j > 0 then
Result := Result + ', ';
Result := Result + format('%5.2f', [values[i, j]]);
end;
Result := Result + ']';
end;
Result := Result + ']';
end;
 
var
a, b, r: TMatrix;
i, j: Integer;
 
begin
a := TMatrix.Create(3, 3);
b := TMatrix.Create(3, 3);
a.values := [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
b.values := [[2, 2, 2], [5, 5, 5], [7, 7, 7]];
r := a * b;
 
Writeln('a: ');
Writeln(a.ToString, #10);
Writeln('b: ');
Writeln(b.ToString, #10);
Writeln('a * b:');
Writeln(r.ToString);
readln;
 
end.</syntaxhighlight>
{{out}}
<pre>a:
[[ 1,00, 2,00, 3,00]
[ 4,00, 5,00, 6,00]
[ 7,00, 8,00, 9,00]]
 
b:
[[ 2,00, 2,00, 2,00]
[ 5,00, 5,00, 5,00]
[ 7,00, 7,00, 7,00]]
 
a * b:
[[33,00, 33,00, 33,00]
[75,00, 75,00, 75,00]
[117,00, 117,00, 117,00]]</pre>
=={{header|EasyLang}}==
<syntaxhighlight>
func[][] matmul m1[][] m2[][] .
for i to len m1[][]
r[][] &= [ ]
for j = 1 to len m2[1][]
r[i][] &= 0
for k to len m2[][]
r[i][j] += m1[i][k] * m2[k][j]
.
.
.
return r[][]
.
a[][] = [ [ 1 2 3 ] [ 4 5 6 ] ]
b[][] = [ [ 1 2 ] [ 3 4 ] [ 5 6 ] ]
print matmul a[][] b[][]
</syntaxhighlight>
 
{{out}}
<pre>
[
[ 22 28 ]
[ 49 64 ]
]
</pre>
 
=={{header|EGL}}==
<syntaxhighlight lang="egl">
program Matrix_multiplication type BasicProgram {}
function main()
a float[][] = [[1,2,3],[4,5,6]];
b float[][] = [[1,2],[3,4],[5,6]];
c float[][] = mult(a, b);
end
function mult(a float[][], b float[][]) returns(float[][])
if(a.getSize() == 0)
return (new float[0][0]);
end
if(a[1].getSize() != b.getSize())
return (null); //invalid dims
end
n int = a[1].getSize();
m int = a.getSize();
p int = b[1].getSize();
ans float[0][0];
ans.resizeAll([m, p]);
// Calculate dot product.
for(i int from 1 to m)
for(j int from 1 to p)
for(k int from 1 to n)
ans[i][j] += a[i][k] * b[k][j];
end
end
end
return (ans);
end
end
</syntaxhighlight>
 
=={{header|Ela}}==
 
<syntaxhighlight lang="ela">open list
 
mmult a b = [ [ sum $ zipWith (*) ar bc \\ bc <- (transpose b) ] \\ ar <- a ]
 
[[1, 2],
[3, 4]] `mmult` [[-3, -8, 3],
[-2, 1, 4]]</syntaxhighlight>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">
def mult(m1, m2) do
Enum.map m1, fn (x) -> Enum.map t(m2), fn (y) -> Enum.zip(x, y)
|> Enum.map(fn {x, y} -> x * y end)
|> Enum.sum
end
end
end
 
def t(m) do # transpose
List.zip(m) |> Enum.map(&Tuple.to_list(&1))
end
 
 
</syntaxhighlight>
 
=={{header|Emacs Lisp}}==
<syntaxhighlight lang="lisp">
(defvar M1 '((2 1 4)
(0 1 1)))
 
(defvar M2 '(( 6 3 -1 0)
( 1 1 0 4)
(-2 5 0 2)))
 
(seq-map (lambda (a1)
(seq-map (lambda (a2) (apply #'+ (seq-mapn #'* a1 a2)))
(apply #'seq-mapn #'list M2)))
M1)
</syntaxhighlight>
 
{{out}}
<pre>
((5 27 -2 12) (-1 6 0 6))
</pre>
 
=={{header|ELLA}}==
Sample originally from ftp://ftp.dra.hmg.gb/pub/ella (a now dead link) - Public release.
 
Code for matrix multiplication hardware design verification:
<syntaxhighlight lang="ella">MAC ZIP = ([INT n]TYPE t: vector1 vector2) -> [n][2]t:
[INT k = 1..n](vector1[k], vector2[k]).
MAC TRANSPOSE = ([INT n][INT m]TYPE t: matrix) -> [m][n]t:
[INT i = 1..m] [INT j = 1..n] matrix[j][i].
 
MAC INNER_PRODUCT{FN * = [2]TYPE t -> TYPE s, FN + = [2]s -> s}
= ([INT n][2]t: vector) -> s:
IF n = 1 THEN *vector[1]
ELSE *vector[1] + INNER_PRODUCT {*,+} vector[2..n]
FI.
 
MAC MATRIX_MULT {FN * = [2]TYPE t->TYPE s, FN + = [2]s->s} =
([INT n][INT m]t: matrix1, [m][INT p]t: matrix2) -> [n][p]s:
BEGIN
LET transposed_matrix2 = TRANSPOSE matrix2.
OUTPUT [INT i = 1..n][INT j = 1..p]
INNER_PRODUCT{*,+}ZIP(matrix1[i],transposed_matrix2[j])
END.
 
 
TYPE element = NEW elt/(1..20),
product = NEW prd/(1..1200).
 
FN PLUS = (product: integer1 integer2) -> product:
ARITH integer1 + integer2.
 
FN MULT = (element: integer1 integer2) -> product:
ARITH integer1 * integer2.
 
FN MULT_234 = ([2][3]element:matrix1, [3][4]element:matrix2) ->
[2][4]product:
MATRIX_MULT{MULT,PLUS}(matrix1, matrix2).
 
FN TEST = () -> [2][4]product:
( LET m1 = ((elt/2, elt/1, elt/1),
(elt/3, elt/6, elt/9)),
m2 = ((elt/6, elt/1, elt/3, elt/4),
(elt/9, elt/2, elt/8, elt/3),
(elt/6, elt/4, elt/1, elt/2)).
OUTPUT
MULT_234 (m1, m2)
).
 
COM test: just displaysignal MOC</syntaxhighlight>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
 
%% Multiplies two matrices. Usage example:
%% $ matrix:multiply([[1,2,3],[4,5,6]], [[4,4],[0,0],[1,4]])
%% If the dimentions are incompatible, an error is thrown.
%%
%% The erl shell may encode the lists output as strings. In order to prevent such
%% behaviour, BEFORE running matrix:multiply, run shell:strings(false) to disable
%% auto-encoding. When finished, run shell:strings(true) to reset the defaults.
 
-module(matrix).
-export([multiply/2]).
 
transpose([[]|_]) ->
[];
transpose(B) ->
[lists:map(fun hd/1, B) | transpose(lists:map(fun tl/1, B))].
 
 
red(Pair, Sum) ->
X = element(1, Pair), %gets X
Y = element(2, Pair), %gets Y
X * Y + Sum.
 
%% Mathematical dot product. A x B = d
%% A, B = 1-dimension vector
%% d = scalar
dot_product(A, B) ->
lists:foldl(fun red/2, 0, lists:zip(A, B)).
 
 
%% Exposed function. Expected result is C = A x B.
multiply(A, B) ->
%% First transposes B, to facilitate the calculations (It's easier to fetch
%% row than column wise).
multiply_internal(A, transpose(B)).
 
 
%% This function does the actual multiplication, but expects the second matrix
%% to be transposed.
multiply_internal([Head | Rest], B) ->
% multiply each row by Y
Element = multiply_row_by_col(Head, B),
 
% concatenate the result of this multiplication with the next ones
[Element | multiply_internal(Rest, B)];
 
multiply_internal([], B) ->
% concatenating and empty list to the end of a list, changes nothing.
[].
 
 
multiply_row_by_col(Row, [Col_Head | Col_Rest]) ->
Scalar = dot_product(Row, Col_Head),
 
[Scalar | multiply_row_by_col(Row, Col_Rest)];
 
multiply_row_by_col(Row, []) ->
[].
</syntaxhighlight>
 
{{out}}
<pre>
[[7,16],[22,40]]
</pre>
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
PROGRAM MAT_PROD
 
DIM A[3,1],B[1,2],ANS[3,2]
 
BEGIN
 
DATA(1,2,3,4,5,6,7,8)
DATA(1,2,3,4,5,6)
 
FOR I=0 TO 3 DO
FOR J=0 TO 1 DO
READ(A[I,J])
END FOR
END FOR
 
FOR I=0 TO 1 DO
FOR J=0 TO 2 DO
READ(B[I,J])
END FOR
END FOR
 
FOR I=0 TO UBOUND(ANS,1) DO
FOR J=0 TO UBOUND(ANS,2) DO
FOR K=0 TO UBOUND(A,2) DO
ANS[I,J]=ANS[I,J]+(A[I,K]*B[K,J])
END FOR
END FOR
END FOR
! print answer
FOR I=0 TO UBOUND(ANS,1) DO
FOR J=0 TO UBOUND(ANS,2) DO
PRINT(ANS[I,J],)
END FOR
PRINT
END FOR
 
END PROGRAM
</syntaxhighlight>
{{out}}<pre>
9 12 15
19 26 33
29 40 51
39 54 69
</pre>
 
=={{header|Euphoria}}==
<syntaxhighlight lang="euphoria">function matrix_mul(sequence a, sequence b)
sequence c
if length(a[1]) != length(b) then
return 0
else
c = repeat(repeat(0,length(b[1])),length(a))
for i = 1 to length(a) do
for j = 1 to length(b[1]) do
for k = 1 to length(a[1]) do
c[i][j] += a[i][k]*b[k][j]
end for
end for
end for
return c
end if
end function</syntaxhighlight>
 
=={{header|Excel}}==
Excel's MMULT function yields the matrix product of two arrays.
 
The formula in cell B2 here populates the '''B2:D3''' grid:
{{Out}}
{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="8" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=MMULT(F2#, F6#)
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
| C
| D
| E
| F
| G
| H
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
|
| colspan="3" style="font-weight:bold" | Matrix product
|
| colspan="3" style="font-weight:bold" | M1
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
|
| style="text-align:right; background-color:#cbcefb" | -7
| style="text-align:right" | -6
| style="text-align:right" | 11
|
| style="text-align:right" | 1
| style="text-align:right" | 2
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
|
| style="text-align:right" | -17
| style="text-align:right" | -20
| style="text-align:right" | 25
|
| style="text-align:right" | 3
| style="text-align:right" | 4
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
|
|
|
|
|
| colspan="3" style="font-weight:bold" | M2
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
|
|
|
|
|
| style="text-align:right" | -3
| style="text-align:right" | -8
| style="text-align:right" | 3
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 7
|
|
|
|
|
| style="text-align:right" | -2
| style="text-align:right" | 1
| style="text-align:right" | 4
|}
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
let MatrixMultiply (matrix1 : _[,] , matrix2 : _[,]) =
let result_row = (matrix1.GetLength 0)
let result_column = (matrix2.GetLength 1)
let ret = Array2D.create result_row result_column 0
for x in 0 .. result_row - 1 do
for y in 0 .. result_column - 1 do
let mutable acc = 0
for z in 0 .. (matrix1.GetLength 1) - 1 do
acc <- acc + matrix1.[x,z] * matrix2.[z,y]
ret.[x,y] <- acc
ret
 
</syntaxhighlight>
 
=={{header|Factor}}==
The built-in word <code>m.</code> multiplies matrices:
: m* flip swap [ dupd [ [ * ] 2map sum ] curry map ] map nip ;
 
Example:
( scratchpad ) USE: math.matrices
{ { 1 2 } { 3 4 } } { { -3 -8 3 } { -2 1 4 } } m* .
{ { 1 2 } { 3 4 } } { { -3 -8 3 } { -2 1 4 } } m. .
Result:
{ { -7 -6 11 } { -17 -20 25 } }
 
=={{header|Fantom}}==
 
Using a list of lists representation. The multiplication is done using three nested loops.
 
<syntaxhighlight lang="fantom">
class Main
{
// multiply two matrices (with no error checking)
public static Int[][] multiply (Int[][] m1, Int[][] m2)
{
Int[][] result := [,]
m1.each |Int[] row1|
{
Int[] row := [,]
m2[0].size.times |Int colNumber|
{
Int value := 0
m2.each |Int[] row2, Int index|
{
value += row1[index] * row2[colNumber]
}
row.add (value)
}
result.add (row)
}
return result
}
 
public static Void main ()
{
m1 := [[1,2,3],[4,5,6]]
m2 := [[1,2],[3,4],[5,6]]
 
echo ("${m1} times ${m2} = ${multiply(m1,m2)}")
}
}
</syntaxhighlight>
 
{{out}}
<pre>
[[1, 2, 3], [4, 5, 6]] times [[1, 2], [3, 4], [5, 6]] = [[22, 28], [49, 64]]
</pre>
 
=={{header|Fermat}}==
<syntaxhighlight lang="fermat">
Array a[3,2]
Array b[2,3]
[a]:=[(2,3,5,7,11,13)]
[b]:=[(1,1,2,3,5,8)]
[a]*[b]
</syntaxhighlight>
{{out}}
<pre>
[[ 9, 25, 66, `
14, 39, 103, `
18, 49, 129 ]]
</pre>
 
=={{header|Forth}}==
{{libheader|Forth Scientific Library}}
{{works with|gforth|0.7.9_20170308}}
<pre><nowiki>
<syntaxhighlight lang="forth">S" fsl-util.fs" REQUIRED
include fsl-util.f
S" fsl/dynmem.seq" REQUIRED
: F+! ( addr -- ) ( F: r -- ) DUP F@ F+ F! ;
: FSQR ( F: r1 -- r2 ) FDUP F* ;
S" fsl/gaussj.seq" REQUIRED
3 3 float matrix A{{
A{{ 3 3 }}fread 1e 2e 3e 4e 5e 6e 7e 8e 9e 3 3 A{{ }}fput
3 3 float matrix B{{
B{{ 3 3 }}fread 3e 3e 3e 2e 2e 2e 1e 1e 1e 3 3 B{{ }}fput
3 3 float matrixdmatrix C{{ \ result
A{{ 3 3 B{{ 3 3 & C{{ mat*
3 3 C{{ }}fprint</syntaxhighlight>
C{{ }}print
</nowiki></pre>
 
=={{header|Fortran}}==
In ISO Fortran 90 or later, use the SIZEMATMUL intrinsic function to perform Matrix Multiply; use RESHAPE and MATMULSIZE intrinsic functions to form the matrices themselves:
<syntaxhighlight lang="fortran">real, dimension(n,m) :: a = reshape( (/[ (i, i=1, n*m) /)], (/[ n, m /)] )
real, dimension(m,k) :: b = reshape( (/[ (i, i=1, m*k) /)], (/[ m, k /)] )
real, dimension(size(a,1), size(b,2)) :: c ! C is an array whose first dimension (row) size
! is the same as A's first dimension size, and
! whose second dimension (column) size is the same
! as B's second dimension size.
 
c = matmul( a, b )
c = matmul( a, b )
 
print *, 'A'
do i = 1, n
print *, a(i,:)
end do
 
print *,
print *, 'B'
do i = 1, m
print *, b(i,:)
end do
 
print *,
print *, 'C = AB'
do i = 1, n
print *, c(i,:)
end do</syntaxhighlight>
For Intel 14.x or later (with compiler switch -assume realloc_lhs)
<syntaxhighlight lang="fortran">
program mm
real , allocatable :: a(:,:),b(:,:)
integer :: l=5,m=6,n=4
a = reshape([1:l*m],[l,m])
b = reshape([1:m*n],[m,n])
print'(<n>f15.7)',transpose(matmul(a,b))
end program
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">type Matrix
dim as double m( any , any )
declare constructor ( )
declare constructor ( byval x as uinteger , byval y as uinteger )
end type
 
constructor Matrix ( )
end constructor
 
constructor Matrix ( byval x as uinteger , byval y as uinteger )
redim this.m( x - 1 , y - 1 )
end constructor
 
operator * ( byref a as Matrix , byref b as Matrix ) as Matrix
dim as Matrix ret
dim as uinteger i, j, k
if ubound( a.m , 2 ) = ubound( b.m , 1 ) and ubound( a.m , 1 ) = ubound( b.m , 2 ) then
redim ret.m( ubound( a.m , 1 ) , ubound( b.m , 2 ) )
for i = 0 to ubound( a.m , 1 )
for j = 0 to ubound( b.m , 2 )
for k = 0 to ubound( b.m , 1 )
ret.m( i , j ) += a.m( i , k ) * b.m( k , j )
next k
next j
next i
end if
return ret
end operator
 
'some garbage matrices for demonstration
dim as Matrix a = Matrix(4 , 2)
a.m(0 , 0) = 1 : a.m(0 , 1) = 0
a.m(1 , 0) = 0 : a.m(1 , 1) = 1
a.m(2 , 0) = 2 : a.m(2 , 1) = 3
a.m(3 , 0) = 0.75 : a.m(3 , 1) = -0.5
dim as Matrix b = Matrix( 2 , 4 )
b.m(0 , 0) = 3.1 : b.m(0 , 1) = 1.6 : b.m(0 , 2) = -99 : b.m (0, 3) = -8
b.m(1 , 0) = 2.7 : b.m(1 , 1) = 0.6 : b.m(1 , 2) = 0 : b.m(1,3) = 21
dim as Matrix c = a * b
print c.m(0, 0), c.m(0, 1), c.m(0, 2), c.m(0, 3)
print c.m(1, 0), c.m(1, 1), c.m(1, 2), c.m(1, 3)
print c.m(2, 0), c.m(2, 1), c.m(2, 2), c.m(2, 3)
print c.m(3, 0), c.m(3, 1), c.m(3, 2), c.m(3, 3)
</syntaxhighlight>
 
 
=={{header|Frink}}==
<syntaxhighlight lang="frink">matprod[a is array, b is array] :=
{
c = makeArray[[length[a], length[b@0]], 0]
 
a_row = length[a]-1
a_col = length[a@0]-1
b_col = length[b]-1
 
for row = 0 to a_row
for col = 0 to b_col
for inc = 0 to a_col
c@row@col = c@row@col + (a@row@inc * b@inc@col)
 
return c
}</syntaxhighlight>
 
=={{header|Futhark}}==
{{incorrect|Futhark|Futhark's syntax has changed, so this example will not compile}}
 
Note that the transposition need not be manifested, but is merely a change of indexing.
 
<syntaxhighlight lang="futhark">
fun main(x: [n][m]int, y: [m][p]int): [n][p]int =
map (fn xr => map (fn yc => reduce (+) 0 (zipWith (*) xr yc))
(transpose y))
x
</syntaxhighlight>
 
=={{header|GAP}}==
<syntaxhighlight lang="gap"># Built-in
A := [[1, 2], [3, 4], [5, 6], [7, 8]];
B := [[1, 2, 3], [4, 5, 6]];
 
PrintArray(A);
# [ [ 1, 2 ],
# [ 3, 4 ],
# [ 5, 6 ],
# [ 7, 8 ] ]
 
PrintArray(B);
# [ [ 1, 2, 3 ],
# [ 4, 5, 6 ] ]
 
PrintArray(A * B);
# [ [ 9, 12, 15 ],
# [ 19, 26, 33 ],
# [ 29, 40, 51 ],
# [ 39, 54, 69 ] ]</syntaxhighlight>
 
 
=={{header|Generic}}==
<syntaxhighlight lang="cpp">
generic coordinaat
{
ecs
uuii
 
coordinaat() { ecs=+a uuii=+a}
 
coordinaat(ecs_set uuii_set) { ecs = ecs_set uuii=uuii_set }
 
operaator<(c)
{
iph ecs < c.ecs return troo
iph c.ecs < ecs return phals
iph uuii < c.uuii return troo
return phals
}
 
operaator==(connpair) // eecuuols and not eecuuols deriiu phronn operaator<
{
iph this < connpair return phals
iph connpair < this return phals
return troo
}
 
operaator!=(connpair)
{
iph this < connpair return troo
iph connpair < this return troo
return phals
}
 
too_string()
{
return "(" + ecs.too_string() + "," + uuii.too_string() + ")"
}
 
print()
{
str = too_string()
str.print()
}
 
println()
{
str = too_string()
str.println()
}
}
 
generic nnaatrics
{
s // this is a set of coordinaat/ualioo pairs.
iteraator // this field holds an iteraator phor the nnaatrics.
 
nnaatrics() // no parameters required phor nnaatrics construction.
{
s = nioo set() // create a nioo set of coordinaat/ualioo pairs.
iteraator = nul // the iteraator is initially set to nul.
}
 
nnaatrics(copee) // copee the nnaatrics.
{
s = nioo set() // create a nioo set of coordinaat/ualioo pairs.
iteraator = nul // the iteraator is initially set to nul.
 
r = copee.rouus
c = copee.cols
i = 0
uuiil i < r
{
j = 0
uuiil j < c
{
this[i j] = copee[i j]
j++
}
i++
}
}
 
begin { get { return s.begin } } // property: used to commence manual iteraashon.
 
end { get { return s.end } } // property: used to dephiin the end itenn of iteraashon
 
operaator<(a) // les than operaator is corld bii the avl tree algorithnns
{ // this operaator innpliis phor instance that you could potenshalee hav sets ou nnaatricss.
iph cees < a.cees // connpair the cee sets phurst.
return troo
els iph a.cees < cees
return phals
els // the cee sets are eecuuol thairphor connpair nnaatrics elennents.
{
phurst1 = begin
lahst1 = end
phurst2 = a.begin
lahst2 = a.end
 
uuiil phurst1 != lahst1 && phurst2 != lahst2
{
iph phurst1.daata.ualioo < phurst2.daata.ualioo
return troo
els
{
iph phurst2.daata.ualioo < phurst1.daata.ualioo
return phals
els
{
phurst1 = phurst1.necst
phurst2 = phurst2.necst
}
}
}
 
return phals
}
}
 
operaator==(connpair) // eecuuols and not eecuuols deriiu phronn operaator<
{
iph this < connpair return phals
iph connpair < this return phals
return troo
}
 
operaator!=(connpair)
{
iph this < connpair return troo
iph connpair < this return troo
return phals
}
 
 
operaator[cee_a cee_b] // this is the nnaatrics indexer.
{
set
{
trii { s >> nioo cee_ualioo(new coordinaat(cee_a cee_b)) } catch {}
s << nioo cee_ualioo(new coordinaat(nioo integer(cee_a) nioo integer(cee_b)) ualioo)
}
get
{
d = s.get(nioo cee_ualioo(new coordinaat(cee_a cee_b)))
return d.ualioo
}
}
 
operaator>>(coordinaat) // this operaator reennoous an elennent phronn the nnaatrics.
{
s >> nioo cee_ualioo(coordinaat)
return this
}
 
iteraat() // and this is how to iterate on the nnaatrics.
{
iph iteraator.nul()
{
iteraator = s.lepht_nnohst
iph iteraator == s.heder
return nioo iteraator(phals nioo nun())
els
return nioo iteraator(troo iteraator.daata.ualioo)
}
els
{
iteraator = iteraator.necst
iph iteraator == s.heder
{
iteraator = nul
return nioo iteraator(phals nioo nun())
}
els
return nioo iteraator(troo iteraator.daata.ualioo)
}
}
 
couunt // this property returns a couunt ou elennents in the nnaatrics.
{
get
{
return s.couunt
}
}
 
ennptee // is the nnaatrics ennptee?
{
get
{
return s.ennptee
}
}
 
 
lahst // returns the ualioo of the lahst elennent in the nnaatrics.
{
get
{
iph ennptee
throuu "ennptee nnaatrics"
els
return s.lahst.ualioo
}
}
 
too_string() // conuerts the nnaatrics too aa string
{
return s.too_string()
}
 
print() // prints the nnaatrics to the consohl.
{
out = too_string()
out.print()
}
 
println() // prints the nnaatrics as a liin too the consohl.
{
out = too_string()
out.println()
}
 
cees // return the set ou cees ou the nnaatrics (a set of coordinaats).
{
get
{
k = nioo set()
phor e : s k << e.cee
return k
}
}
 
operaator+(p)
{
ouut = nioo nnaatrics()
phurst1 = begin
lahst1 = end
phurst2 = p.begin
lahst2 = p.end
uuiil phurst1 != lahst1 && phurst2 != lahst2
{
ouut[phurst1.daata.cee.ecs phurst1.daata.cee.uuii] = phurst1.daata.ualioo + phurst2.daata.ualioo
phurst1 = phurst1.necst
phurst2 = phurst2.necst
}
return ouut
}
operaator-(p)
{
ouut = nioo nnaatrics()
phurst1 = begin
lahst1 = end
phurst2 = p.begin
lahst2 = p.end
uuiil phurst1 != lahst1 && phurst2 != lahst2
{
ouut[phurst1.daata.cee.ecs phurst1.daata.cee.uuii] = phurst1.daata.ualioo - phurst2.daata.ualioo
phurst1 = phurst1.necst
phurst2 = phurst2.necst
}
return ouut
}
 
rouus
{
get
{
r = +a
phurst1 = begin
lahst1 = end
uuiil phurst1 != lahst1
{
iph r < phurst1.daata.cee.ecs r = phurst1.daata.cee.ecs
phurst1 = phurst1.necst
}
return r + +b
}
}
 
cols
{
get
{
c = +a
phurst1 = begin
lahst1 = end
uuiil phurst1 != lahst1
{
iph c < phurst1.daata.cee.uuii c = phurst1.daata.cee.uuii
phurst1 = phurst1.necst
}
return c + +b
}
}
 
operaator*(o)
{
iph cols != o.rouus throw "rouus-cols nnisnnatch"
reesult = nioo nnaatrics()
rouu_couunt = rouus
colunn_couunt = o.cols
loop = cols
i = +a
uuiil i < rouu_couunt
{
g = +a
uuiil g < colunn_couunt
{
sunn = +a.a
h = +a
uuiil h < loop
{
a = this[i h]
 
b = o[h g]
nn = a * b
sunn = sunn + nn
h++
}
 
reesult[i g] = sunn
 
g++
}
i++
}
return reesult
}
 
suuop_rouus(a b)
{
c = cols
i = 0
uuiil u < cols
{
suuop = this[a i]
this[a i] = this[b i]
this[b i] = suuop
i++
}
}
 
suuop_colunns(a b)
{
r = rouus
i = 0
uuiil i < rouus
{
suuopp = this[i a]
this[i a] = this[i b]
this[i b] = suuop
i++
}
}
 
transpohs
{
get
{
reesult = new nnaatrics()
 
r = rouus
c = cols
i=0
uuiil i < r
{
g = 0
uuiil g < c
{
reesult[g i] = this[i g]
g++
}
i++
}
 
return reesult
}
}
 
deternninant
{
get
{
rouu_couunt = rouus
colunn_count = cols
 
if rouu_couunt != colunn_count
throw "not a scuuair nnaatrics"
 
if rouu_couunt == 0
throw "the nnaatrics is ennptee"
 
if rouu_couunt == 1
return this[0 0]
 
if rouu_couunt == 2
return this[0 0] * this[1 1] -
this[0 1] * this[1 0]
 
temp = nioo nnaatrics()
 
det = 0.0
parity = 1.0
 
j = 0
uuiil j < rouu_couunt
{
k = 0
uuiil k < rouu_couunt-1
{
skip_col = phals
 
l = 0
uuiil l < rouu_couunt-1
{
if l == j skip_col = troo
 
if skip_col
n = l + 1
els
n = l
 
temp[k l] = this[k + 1 n]
l++
}
k++
}
 
det = det + parity * this[0 j] * temp.deeternninant
 
parity = 0.0 - parity
j++
}
 
return det
}
}
 
ad_rouu(a b)
{
c = cols
i = 0
uuiil i < c
{
this[a i] = this[a i] + this[b i]
i++
}
}
 
ad_colunn(a b)
{
c = rouus
i = 0
uuiil i < c
{
this[i a] = this[i a] + this[i b]
i++
}
}
 
subtract_rouu(a b)
{
c = cols
i = 0
uuiil i < c
{
this[a i] = this[a i] - this[b i]
i++
}
}
 
subtract_colunn(a b)
{
c = rouus
i = 0
uuiil i < c
{
this[i a] = this[i a] - this[i b]
i++
}
}
 
nnultiplii_rouu(rouu scalar)
{
c = cols
i = 0
uuiil i < c
{
this[rouu i] = this[rouu i] * scalar
i++
}
}
 
nnultiplii_colunn(colunn scalar)
{
r = rouus
i = 0
uuiil i < r
{
this[i colunn] = this[i colunn] * scalar
i++
}
}
 
diuiid_rouu(rouu scalar)
{
c = cols
i = 0
uuiil i < c
{
this[rouu i] = this[rouu i] / scalar
i++
}
}
 
diuiid_colunn(colunn scalar)
{
r = rouus
i = 0
uuiil i < r
{
this[i colunn] = this[i colunn] / scalar
i++
}
}
 
connbiin_rouus_ad(a b phactor)
{
c = cols
i = 0
uuiil i < c
{
this[a i] = this[a i] + phactor * this[b i]
i++
}
}
 
connbiin_rouus_subtract(a b phactor)
{
c = cols
i = 0
uuiil i < c
{
this[a i] = this[a i] - phactor * this[b i]
i++
}
}
 
connbiin_colunns_ad(a b phactor)
{
r = rouus
i = 0
uuiil i < r
{
this[i a] = this[i a] + phactor * this[i b]
i++
}
}
 
connbiin_colunns_subtract(a b phactor)
{
r = rouus
i = 0
uuiil i < r
{
this[i a] = this[i a] - phactor * this[i b]
i++
}
}
 
inuers
{
get
{
rouu_couunt = rouus
colunn_couunt = cols
 
iph rouu_couunt != colunn_couunt
throw "nnatrics not scuuair"
 
els iph rouu_couunt == 0
throw "ennptee nnatrics"
 
els iph rouu_couunt == 1
{
r = nioo nnaatrics()
r[0 0] = 1.0 / this[0 0]
return r
}
 
gauss = nioo nnaatrics(this)
 
i = 0
uuiil i < rouu_couunt
{
j = 0
uuiil j < rouu_couunt
{
iph i == j
 
gauss[i j + rouu_couunt] = 1.0
els
gauss[i j + rouu_couunt] = 0.0
j++
}
 
i++
}
 
j = 0
uuiil j < rouu_couunt
{
iph gauss[j j] == 0.0
{
k = j + 1
 
uuiil k < rouu_couunt
{
if gauss[k j] != 0.0 {gauss.nnaat.suuop_rouus(j k) break }
k++
}
 
if k == rouu_couunt throw "nnatrics is singioolar"
}
 
phactor = gauss[j j]
iph phactor != 1.0 gauss.diuiid_rouu(j phactor)
 
i = j+1
uuiil i < rouu_couunt
{
gauss.connbiin_rouus_subtract(i j gauss[i j])
i++
}
 
j++
}
 
i = rouu_couunt - 1
uuiil i > 0
{
k = i - 1
uuiil k >= 0
{
gauss.connbiin_rouus_subtract(k i gauss[k i])
k--
}
i--
}
 
reesult = nioo nnaatrics()
 
i = 0
uuiil i < rouu_couunt
{
j = 0
uuiil j < rouu_couunt
{
reesult[i j] = gauss[i j + rouu_couunt]
j++
}
i++
}
 
return reesult
}
}
 
}
</syntaxhighlight>
 
=={{header|Go}}==
===Library gonum/mat===
<syntaxhighlight lang="go">package main
 
import (
"fmt"
 
"gonum.org/v1/gonum/mat"
)
 
func main() {
a := mat.NewDense(2, 4, []float64{
1, 2, 3, 4,
5, 6, 7, 8,
})
b := mat.NewDense(4, 3, []float64{
1, 2, 3,
4, 5, 6,
7, 8, 9,
10, 11, 12,
})
var m mat.Dense
m.Mul(a, b)
fmt.Println(mat.Formatted(&m))
}</syntaxhighlight>
{{out}}
<pre>
⎡ 70 80 90⎤
⎣158 184 210⎦
</pre>
 
===Library go.matrix===
<syntaxhighlight lang="go">package main
 
import (
"fmt"
 
mat "github.com/skelterjohn/go.matrix"
)
 
func main() {
a := mat.MakeDenseMatrixStacked([][]float64{
{1, 2, 3, 4},
{5, 6, 7, 8},
})
b := mat.MakeDenseMatrixStacked([][]float64{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
{10, 11, 12},
})
fmt.Printf("Matrix A:\n%v\n", a)
fmt.Printf("Matrix B:\n%v\n", b)
p, err := a.TimesDense(b)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Product of A and B:\n%v\n", p)
}</syntaxhighlight>
{{out}}
<pre>
Matrix A:
{1, 2, 3, 4,
5, 6, 7, 8}
Matrix B:
{ 1, 2, 3,
4, 5, 6,
7, 8, 9,
10, 11, 12}
Product of A and B:
{ 70, 80, 90,
158, 184, 210}
</pre>
 
===2D representation===
<syntaxhighlight lang="go">package main
 
import "fmt"
 
type Value float64
type Matrix [][]Value
 
func Multiply(m1, m2 Matrix) (m3 Matrix, ok bool) {
rows, cols, extra := len(m1), len(m2[0]), len(m2)
if len(m1[0]) != extra {
return nil, false
}
m3 = make(Matrix, rows)
for i := 0; i < rows; i++ {
m3[i] = make([]Value, cols)
for j := 0; j < cols; j++ {
for k := 0; k < extra; k++ {
m3[i][j] += m1[i][k] * m2[k][j]
}
}
}
return m3, true
}
 
func (m Matrix) String() string {
rows := len(m)
cols := len(m[0])
out := "["
for r := 0; r < rows; r++ {
if r > 0 {
out += ",\n "
}
out += "[ "
for c := 0; c < cols; c++ {
if c > 0 {
out += ", "
}
out += fmt.Sprintf("%7.3f", m[r][c])
}
out += " ]"
}
out += "]"
return out
}
 
func main() {
A := Matrix{[]Value{1, 2, 3, 4},
[]Value{5, 6, 7, 8}}
B := Matrix{[]Value{1, 2, 3},
[]Value{4, 5, 6},
[]Value{7, 8, 9},
[]Value{10, 11, 12}}
P, ok := Multiply(A, B)
if !ok {
panic("Invalid dimensions")
}
fmt.Printf("Matrix A:\n%s\n\n", A)
fmt.Printf("Matrix B:\n%s\n\n", B)
fmt.Printf("Product of A and B:\n%s\n\n", P)
}</syntaxhighlight>
{{out}}
<pre>
Matrix A:
[[ 1.000, 2.000, 3.000, 4.000 ],
[ 5.000, 6.000, 7.000, 8.000 ]]
 
Matrix B:
[[ 1.000, 2.000, 3.000 ],
[ 4.000, 5.000, 6.000 ],
[ 7.000, 8.000, 9.000 ],
[ 10.000, 11.000, 12.000 ]]
 
Product of A and B:
[[ 70.000, 80.000, 90.000 ],
[ 158.000, 184.000, 210.000 ]]
</pre>
===Flat representation===
<syntaxhighlight lang="go">package main
 
import "fmt"
 
type matrix struct {
stride int
ele []float64
}
 
func (m *matrix) print(heading string) {
if heading > "" {
fmt.Print("\n", heading, "\n")
}
for e := 0; e < len(m.ele); e += m.stride {
fmt.Printf("%8.3f ", m.ele[e:e+m.stride])
fmt.Println()
}
}
 
func (m1 *matrix) multiply(m2 *matrix) (m3 *matrix, ok bool) {
if m1.stride*m2.stride != len(m2.ele) {
return nil, false
}
m3 = &matrix{m2.stride, make([]float64, (len(m1.ele)/m1.stride)*m2.stride)}
for m1c0, m3x := 0, 0; m1c0 < len(m1.ele); m1c0 += m1.stride {
for m2r0 := 0; m2r0 < m2.stride; m2r0++ {
for m1x, m2x := m1c0, m2r0; m2x < len(m2.ele); m2x += m2.stride {
m3.ele[m3x] += m1.ele[m1x] * m2.ele[m2x]
m1x++
}
m3x++
}
}
return m3, true
}
 
func main() {
a := matrix{4, []float64{
1, 2, 3, 4,
5, 6, 7, 8,
}}
b := matrix{3, []float64{
1, 2, 3,
4, 5, 6,
7, 8, 9,
10, 11, 12,
}}
p, ok := a.multiply(&b)
a.print("Matrix A:")
b.print("Matrix B:")
if !ok {
fmt.Println("not conformable for matrix multiplication")
return
}
p.print("Product of A and B:")
}</syntaxhighlight>
Output is similar to 2D version.
 
=={{header|Groovy}}==
=== Without Indexed Loops ===
Uses transposition to avoid indirect element access via ranges of indexes. "assertConformable()" asserts that a & b are both rectangular lists of lists, and that row-length (number of columns) of a is equal to the column-length (number of rows) of b.
<syntaxhighlight lang="groovy">def assertConformable = { a, b ->
assert a instanceof List
assert b instanceof List
assert a.every { it instanceof List && it.size() == b.size() }
assert b.every { it instanceof List && it.size() == b[0].size() }
}
 
def matmulWOIL = { a, b ->
assertConformable(a, b)
printdef *,bt 'A'= b.transpose()
doa.collect i{ =ai 1, n->
printbt.collect *,{ a(i,:)btj ->
[ai, btj].transpose().collect { it[0] * it[1] }.sum()
end do
}
}
}</syntaxhighlight>
 
=== Without Transposition ===
Uses ranges of indexes, the way that matrix multiplication is typically defined. Not as elegant, but it avoids expensive transpositions. Reuses "assertConformable()" from above.
<syntaxhighlight lang="groovy">def matmulWOT = { a, b ->
assertConformable(a, b)
(0..<a.size()).collect { i ->
print *,
(0..<b[0].size()).collect { j ->
print *, 'B'
(0..<b.size()).collect { k -> a[i][k] * b[k][j] }.sum()
do i = 1, m
print *, b(i,:)}
end do}
}</syntaxhighlight>
print *,
print *, 'C = AB'
do i = 1, n
print *, c(i,:)
end do
 
Test:
=={{header|Haskell}}==
<syntaxhighlight lang="groovy">def m4by2 = [ [ 1, 2 ],
[ 3, 4 ],
[ 5, 6 ],
[ 7, 8 ] ]
 
def m2by3 = [ [ 1, 2, 3 ],
[ 4, 5, 6 ] ]
 
matmulWOIL(m4by2, m2by3).each { println it }
println()
matmulWOT(m4by2, m2by3).each { println it }</syntaxhighlight>
 
{{out}}
<pre>[9, 12, 15]
[19, 26, 33]
[29, 40, 51]
[39, 54, 69]
 
[9, 12, 15]
[19, 26, 33]
[29, 40, 51]
[39, 54, 69]</pre>
 
=={{header|Haskell}}==
===With List and transpose===
A somewhat inefficient version with lists (''transpose'' is expensive):
 
<syntaxhighlight lang="haskell">import Data.List
<pre>
import Data.List
 
mmult :: Num a => [[a]] -> [[a]] -> [[a]]
Line 477 ⟶ 3,583:
test = [[1, 2],
[3, 4]] `mmult` [[-3, -8, 3],
[-2, 1, 4]]</syntaxhighlight>
===With Array===
</pre>
 
A more efficient version, based on arrays:
 
<syntaxhighlight lang="haskell">import Data.Array
<pre>
import Data.Array
mmult :: (Ix i, Num a) => Array (i,i) a -> Array (i,i) a -> Array (i,i) a
Line 495 ⟶ 3,599:
jr = range (y1,y1')
kr = range (x1,x1')
l = [((i,j), sum [x!(i,k) * y!(k,j) | k <- kr]) | i <- ir, j <- jr]</syntaxhighlight>
===With List and without transpose===
<syntaxhighlight lang="haskell">multiply :: Num a => [[a]] -> [[a]] -> [[a]]
multiply us vs = map (mult [] vs) us
where
mult xs [] _ = xs
mult xs _ [] = xs
mult [] (zs : zss) (y : ys) = mult (map (y *) zs) zss ys
mult xs (zs : zss) (y : ys) =
mult
(zipWith (\u v -> u + v * y) xs zs)
zss
ys
 
main :: IO ()
main =
mapM_ print $
multiply
[[1, 2], [3, 4]]
[[-3, -8, 3], [-2, 1, 4]]</syntaxhighlight>
{{out}}
<pre>[-7,-6,11]
[-17,-20,25]</pre>
 
===With List and without transpose - shorter===
<syntaxhighlight lang="haskell">mult :: Num a => [[a]] -> [[a]] -> [[a]]
mult uss vss =
let go xs
| null xs = []
| otherwise = foldl1 (zipWith (+)) xs
in go . zipWith (flip (map . (*))) vss <$> uss
 
main :: IO ()
main =
mapM_ print $
mult [[1, 2], [3, 4]] [[-3, -8, 3], [-2, 1, 4]]</syntaxhighlight>
{{out}}
<pre>[-7,-6,11]
[-17,-20,25]</pre>
 
===With Numeric.LinearAlgebra===
<syntaxhighlight lang="haskell">import Numeric.LinearAlgebra
 
a, b :: Matrix I
a = (2 >< 2) [1, 2, 3, 4]
 
b = (2 >< 3) [-3, -8, 3, -2, 1, 4]
 
main :: IO ()
main = print $ a <> b</syntaxhighlight>
{{out}}
<pre>
(2><3)
[ -7, -6, 11
, -17, -20, 25 ]</pre>
 
=={{header|HicEst}}==
<syntaxhighlight lang="hicest">REAL :: m=4, n=2, p=3, a(m,n), b(n,p), res(m,p)
 
a = $ ! initialize to 1, 2, ..., m*n
b = $ ! initialize to 1, 2, ..., n*p
 
res = 0
DO i = 1, m
DO j = 1, p
DO k = 1, n
res(i,j) = res(i,j) + a(i,k) * b(k,j)
ENDDO
ENDDO
ENDDO
 
DLG(DefWidth=4, Text=a, Text=b,Y=0, Text=res,Y=0)</syntaxhighlight>
<syntaxhighlight lang="hicest">a b res
1 2 1 2 3 9 12 15
3 4 4 5 6 19 26 33
5 6 29 40 51
7 8 39 54 69 </syntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
 
Using the provided matrix library:
 
<syntaxhighlight lang="icon">
link matrix
 
procedure main ()
m1 := [[1,2,3], [4,5,6]]
m2 := [[1,2],[3,4],[5,6]]
m3 := mult_matrix (m1, m2)
write ("Multiply:")
write_matrix ("", m1) # first argument is filename, or "" for stdout
write ("by:")
write_matrix ("", m2)
write ("Result: ")
write_matrix ("", m3)
end
</syntaxhighlight>
 
And a hand-crafted multiply procedure:
 
<syntaxhighlight lang="icon">
procedure multiply_matrix (m1, m2)
result := [] # to hold the final matrix
every row1 := !m1 do { # loop through each row in the first matrix
row := []
every colIndex := 1 to *m1 do { # and each column index of the result
value := 0
every rowIndex := 1 to *m2 do {
value +:= row1[rowIndex] * m2[rowIndex][colIndex]
}
put (row, value)
}
put (result, row) # add each row as it is complete
}
return result
end
</syntaxhighlight>
 
{{out}}
<pre>
Multiply:
1 2 3
4 5 6
by:
1 2
3 4
5 6
Result:
22 28
49 64
</pre>
 
=={{header|IDL}}==
 
<syntaxhighlight lang="idl">result = arr1 # arr2</syntaxhighlight>
 
=={{header|JIdris}}==
<syntaxhighlight lang="idris">import Data.Vect
Matrix multiply in J is just <tt>+/ .*</tt>. For example:
 
Matrix : Nat -> xNat -> =: Type +/-> .*Type
Matrix m n t = Vect m (Vect n t)
 
A =: ^/~>:i. 4 NB. Same A as in other examples (1 1 1 1, 2 4 8 16, 3 9 27 81,:4 16 64 256)
multiply : Num B t =: %.A> Matrix m1 n t -> Matrix n m2 NB.t -> Matrix inversem1 ofm2 At
multiply a b = multiply' a (transpose b)
where
'6.2' 8!:2 A x B
dot : Num t => Vect n t -> Vect n t -> t
1.00 0.00 0.00 0.00
dot v1 v2 = sum $ map (\(s1, s2) => (s1 * s2)) (zip v1 v2)
0.00 1.00 0.00 0.00
 
0.00 0.00 1.00 0.00
multiply' : Num t => Matrix m1 n t -> Matrix m2 n t -> Matrix m1 m2 t
0.00 0.00 0.00 1.00
multiply' (a::as) b = map (dot a) b :: multiply' as b
multiply' [] _ = []</syntaxhighlight>
 
=={{header|J}}==
Matrix multiply in J is <code>+/ .*</code>. For example:
<syntaxhighlight lang="j"> mp =: +/ .* NB. Matrix product
A =: ^/~>:i. 4 NB. Same A as in other examples (1 1 1 1, 2 4 8 16, 3 9 27 81,:4 16 64 256)
B =: %.A NB. Matrix inverse of A
'6.2' 8!:2 A mp B
1.00 0.00 0.00 0.00
0.00 1.00 0.00 0.00
0.00 0.00 1.00 0.00
0.00 0.00 0.00 1.00</syntaxhighlight>
The notation is for a generalized inner product so that
<syntaxhighlight lang="j">x ~:/ .*. y NB. boolean inner product (<tt> ~: </tt>is "not equal" (exclusive or) and<tt> *. </tt>is "and")
x *./ .= y NB. which rows of x are the same as vector y?
x + / .= y NB. number of places where eacha rowvalue ofin row x equals vectorthe corresponding value in y</syntaxhighlight>
[[Floyd-Warshall_algorithm#J|etc.]]
etc.
 
The general inner product extends to multidimensional arrays, requiring only that <tt> x </tt>and<tt> y </tt> be conformable (trailing dimension of array <tt>x</tt> equals the leading dimension of array <tt>y</tt>). For example, the matrix multiplication of two dimensional arrays requires <tt>x</tt> to have the same numbers of rows as <tt>y</tt> has columns, as you would expect.
 
Note also that <code>mp=: +/@:*"1 _</code> functions identically.
 
Perhaps it would have made more sense to define something more like <code>dot=: conjunction def 'u/@:v"1 _'</code> so that matrix multiplication would be <code>+dot*</code> -- this would also correspond to the original [[Matrix_multiplication#APL|APL]] implementation.
 
=={{header|Java}}==
<syntaxhighlight lang="java">public static double[][] mult(double a[][], double b[][]){//a[m][n], b[n][p]
if(a.length == 0) return new double[0][0];
if(a[0].length != b.length) return null; //invalid dims
 
int n = a[0].length;
int m = a.length;
int p = b[0].length;
 
double ans[][] = new double[m][p];
 
for(int i = 0;i < m;i++){
for(int j = 0;j < p;j++){
for(int k = 0;k < n;k++){
ans[i][j] += a[i][k] * b[k][j];
}
}
}
return ans;
}</syntaxhighlight>
 
=={{header|JavaScript}}==
===ES5===
====Iterative====
{{works with|SpiderMonkey}} for the <code>print()</code> function
 
Extends [[Matrix Transpose#JavaScript]]
<syntaxhighlight lang="javascript">// returns a new matrix
Matrix.prototype.mult = function(other) {
if (this.width != other.height) {
throw "error: incompatible sizes";
}
 
var result = [];
for (var i = 0; i < this.height; i++) {
result[i] = [];
for (var j = 0; j < other.width; j++) {
var sum = 0;
for (var k = 0; k < this.width; k++) {
sum += this.mtx[i][k] * other.mtx[k][j];
}
result[i][j] = sum;
}
}
return new Matrix(result);
}
 
var a = new Matrix([[1,2],[3,4]])
var b = new Matrix([[-3,-8,3],[-2,1,4]]);
print(a.mult(b));</syntaxhighlight>
{{out}}
<pre>-7,-6,11
-17,-20,25</pre>
 
====Functional====
<syntaxhighlight lang="javascript">(function () {
'use strict';
 
// matrixMultiply:: [[n]] -> [[n]] -> [[n]]
function matrixMultiply(a, b) {
var bCols = transpose(b);
 
return a.map(function (aRow) {
return bCols.map(function (bCol) {
return dotProduct(aRow, bCol);
});
});
}
// [[n]] -> [[n]] -> [[n]]
function dotProduct(xs, ys) {
return sum(zipWith(product, xs, ys));
}
 
return matrixMultiply(
[[-1, 1, 4],
[ 6, -4, 2],
[-3, 5, 0],
[ 3, 7, -2]],
 
[[-1, 1, 4, 8],
[ 6, 9, 10, 2],
[11, -4, 5, -3]]
);
 
// --> [[51, -8, 26, -18], [-8, -38, -6, 34],
// [33, 42, 38, -14], [17, 74, 72, 44]]
 
 
// GENERIC LIBRARY FUNCTIONS
 
// (a -> b -> c) -> [a] -> [b] -> [c]
function zipWith(f, xs, ys) {
return xs.length === ys.length ? (
xs.map(function (x, i) {
return f(x, ys[i]);
})
) : undefined;
}
 
// [[a]] -> [[a]]
function transpose(lst) {
return lst[0].map(function (_, iCol) {
return lst.map(function (row) {
return row[iCol];
});
});
}
 
// sum :: (Num a) => [a] -> a
function sum(xs) {
return xs.reduce(function (a, x) {
return a + x;
}, 0);
}
 
// product :: n -> n -> n
function product(a, b) {
return a * b;
}
 
})();</syntaxhighlight>
{{Out}}
<syntaxhighlight lang="javascript">[[51, -8, 26, -18], [-8, -38, -6, 34],
[33, 42, 38, -14], [17, 74, 72, 44]]</syntaxhighlight>
 
===ES6===
<syntaxhighlight lang="javascript">((() => {
"use strict";
 
// -------------- MATRIX MULTIPLICATION --------------
 
// matrixMultiply :: Num a => [[a]] -> [[a]] -> [[a]]
const matrixMultiply = a =>
b => {
const cols = transpose(b);
 
return a.map(
compose(
f => cols.map(f),
dotProduct
)
);
};
 
 
// ---------------------- TEST -----------------------
const main = () =>
JSON.stringify(matrixMultiply(
[
[-1, 1, 4],
[6, -4, 2],
[-3, 5, 0],
[3, 7, -2]
]
)([
[-1, 1, 4, 8],
[6, 9, 10, 2],
[11, -4, 5, -3]
]));
 
 
// --------------------- GENERIC ---------------------
 
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
 
 
// dotProduct :: Num a => [[a]] -> [[a]] -> [[a]]
const dotProduct = xs =>
// Sum of the products of the corresponding
// values in two lists of the same length.
compose(sum, zipWith(mul)(xs));
 
 
// mul :: Num a => a -> a -> a
const mul = a =>
b => a * b;
 
 
// sum :: (Num a) => [a] -> a
const sum = xs =>
xs.reduce((a, x) => a + x, 0);
 
 
// transpose :: [[a]] -> [[a]]
const transpose = rows =>
// The columns of the input transposed
// into new rows.
// Simpler version of transpose, assuming input
// rows of even length.
Boolean(rows.length) ? rows[0].map(
(_, i) => rows.flatMap(
v => v[i]
)
) : [];
 
 
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f =>
// A list constructed by zipping with a
// custom function, rather than with the
// default tuple constructor.
xs => ys => xs.map(
(x, i) => f(x)(ys[i])
).slice(
0, Math.min(xs.length, ys.length)
);
 
// MAIN ---
return main();
}))();</syntaxhighlight>
{{Out}}
<pre>[[51,-8,26,-18],[-8,-38,-6,34],[33,42,38,-14],[17,74,72,44]]</pre>
 
=={{header|jq}}==
In the following, an m by n matrix is represented by an array of m arrays, each of which is of length n.
 
The function multiply(A;B) assumes its arguments are numeric matrices of the proper dimensions. Note that preallocating the resultant matrix would actually slow things down.
<syntaxhighlight lang="jq">def dot_product(a; b):
a as $a | b as $b
| reduce range(0;$a|length) as $i (0; . + ($a[$i] * $b[$i]) );
 
# transpose/0 expects its input to be a rectangular matrix (an array of equal-length arrays)
def transpose:
if (.[0] | length) == 0 then []
else [map(.[0])] + (map(.[1:]) | transpose)
end ;
 
# A and B should both be numeric matrices, A being m by n, and B being n by p.
def multiply(A; B):
A as $A | B as $B
| ($B[0]|length) as $p
| ($B|transpose) as $BT
| reduce range(0; $A|length) as $i
([]; reduce range(0; $p) as $j
(.; .[$i][$j] = dot_product( $A[$i]; $BT[$j] ) )) ;</syntaxhighlight>
'''Example'''
((2|sqrt)/2) as $r | [ [$r, $r], [(-($r)), $r]] as $R
| multiply($R;$R)
{{Out}}
[[0,1.0000000000000002],[-1.0000000000000002,0]]
 
=={{header|Jsish}}==
Based on Javascript matrix entries.
 
Uses module listed in [[Matrix Transpose#Jsish]]
 
<syntaxhighlight lang="javascript">/* Matrix multiplication, in Jsish */
require('Matrix');
 
if (Interp.conf('unitTest')) {
var a = new Matrix([[1,2],[3,4]]);
var b = new Matrix([[-3,-8,3],[-2,1,4]]);
; a;
; b;
; a.mult(b);
}
 
/*
=!EXPECTSTART!=
a ==> { height:2, mtx:[ [ 1, 2 ], [ 3, 4 ] ], width:2 }
b ==> { height:2, mtx:[ [ -3, -8, 3 ], [ -2, 1, 4 ] ], width:3 }
a.mult(b) ==> { height:2, mtx:[ [ -7, -6, 11 ], [ -17, -20, 25 ] ], width:3 }
=!EXPECTEND!=
*/</syntaxhighlight>
 
{{out}}
<pre>prompt$ jsish -u matrixMultiplication.jsi
[PASS] matrixMultiplication.jsi</pre>
 
=={{header|Julia}}==
The multiplication is denoted by *
<syntaxhighlight lang="julia">julia> [1 2 3 ; 4 5 6] * [1 2 ; 3 4 ; 5 6] # product of a 2x3 by a 3x2
2x2 Array{Int64,2}:
22 28
49 64
 
julia> [1 2 3] * [1,2,3] # product of a row vector by a column vector
1-element Array{Int64,1}:
14
</syntaxhighlight>
 
=={{header|K}}==
<syntaxhighlight lang="k"> (1 2;3 4)_mul (5 6;7 8)
(19 22
43 50)</syntaxhighlight>
 
=={{header|Klong}}==
<syntaxhighlight lang="k"> mul::{[a b];b::+y;{a::x;+/'{a*x}'b}'x}
[[1 2] [3 4]] mul [[5 6] [7 8]]
[[19 22]
[43 50]]</syntaxhighlight>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.3
 
typealias Vector = DoubleArray
typealias Matrix = Array<Vector>
 
operator fun Matrix.times(other: Matrix): Matrix {
val rows1 = this.size
val cols1 = this[0].size
val rows2 = other.size
val cols2 = other[0].size
require(cols1 == rows2)
val result = Matrix(rows1) { Vector(cols2) }
for (i in 0 until rows1) {
for (j in 0 until cols2) {
for (k in 0 until rows2) {
result[i][j] += this[i][k] * other[k][j]
}
}
}
return result
}
 
fun printMatrix(m: Matrix) {
for (i in 0 until m.size) println(m[i].contentToString())
}
 
fun main(args: Array<String>) {
val m1 = arrayOf(
doubleArrayOf(-1.0, 1.0, 4.0),
doubleArrayOf( 6.0, -4.0, 2.0),
doubleArrayOf(-3.0, 5.0, 0.0),
doubleArrayOf( 3.0, 7.0, -2.0)
)
val m2 = arrayOf(
doubleArrayOf(-1.0, 1.0, 4.0, 8.0),
doubleArrayOf( 6.0, 9.0, 10.0, 2.0),
doubleArrayOf(11.0, -4.0, 5.0, -3.0)
)
printMatrix(m1 * m2)
}</syntaxhighlight>
 
{{out}}
<pre>
[51.0, -8.0, 26.0, -18.0]
[-8.0, -38.0, -6.0, 34.0]
[33.0, 42.0, 38.0, -14.0]
[17.0, 74.0, 72.0, 44.0]
</pre>
 
=={{header|Lambdatalk}}==
 
<syntaxhighlight lang="scheme">
{require lib_matrix}
 
1) applying a matrix to a vector
 
{def M
{M.new [[1,2,3],
[4,5,6],
[7,8,-9]]}}
-> M
 
{def V {M.new [1,2,3]} }
-> V
 
{M.multiply {M} {V}}
-> [14,32,-4]
 
2) matrix multiplication
 
{M.multiply {M} {M}}
-> [[ 30, 36,-12],
[ 66, 81,-12],
[-24,-18,150]]
</syntaxhighlight>
 
=={{header|Lang5}}==
<syntaxhighlight lang="lang5">[[1 2 3] [4 5 6]] 'm dress
[[1 2] [3 4] [5 6]] 'm dress * .</syntaxhighlight>
{{out}}
<pre>[
[ 22 28 ]
[ 49 64 ]
]</pre>
 
=={{header|LFE}}==
 
Use the LFE <code>transpose/1</code> function from [[Matrix transposition]].
 
<syntaxhighlight lang="lisp">
(defun matrix* (matrix-1 matrix-2)
(list-comp
((<- a matrix-1))
(list-comp
((<- b (transpose matrix-2)))
(lists:foldl #'+/2 0
(lists:zipwith #'*/2 a b)))))
</syntaxhighlight>
 
Usage example in the LFE REPL:
 
<syntaxhighlight lang="lisp">
> (set ma '((1 2)
(3 4)
(5 6)
(7 8)))
((1 2) (3 4) (5 6) (7 8))
> (set mb (transpose ma))
((1 3 5 7) (2 4 6 8))
> (matrix* ma mb)
((5 11 17 23) (11 25 39 53) (17 39 61 83) (23 53 83 113))
</syntaxhighlight>
 
=={{header|Liberty BASIC}}==
There is no native matrix capability. A set of functions is available at http://www.diga.me.uk/RCMatrixFuncs.bas implementing matrices of arbitrary dimension in a string format.
<syntaxhighlight lang="lb">
MatrixA$ ="4, 4, 1, 1, 1, 1, 2, 4, 8, 16, 3, 9, 27, 81, 4, 16, 64, 256"
MatrixB$ ="4, 4, 4, -3, 4/3, -1/4 , -13/3, 19/4, -7/3, 11/24, 3/2, -2, 7/6, -1/4, -1/6, 1/4, -1/6, 1/24"
 
print "Product of two matrices"
call DisplayMatrix MatrixA$
print " *"
call DisplayMatrix MatrixB$
print " ="
MatrixP$ =MatrixMultiply$( MatrixA$, MatrixB$)
call DisplayMatrix MatrixP$
</syntaxhighlight>
 
{{out}}
<pre>Product of two matrices
| 1.00000 1.00000 1.00000 1.00000 |
| 2.00000 4.00000 8.00000 16.00000 |
| 3.00000 9.00000 27.00000 81.00000 |
| 4.00000 16.00000 64.00000 256.00000 |
 
*
| 4.00000 -3.00000 1.33333 -0.25000 |
| -4.33333 4.75000 -2.33333 0.45833 |
| 1.50000 -2.00000 1.16667 -0.25000 |
| -0.16667 0.25000 -0.16667 0.04167 |
 
=
| 1.00000 0.00000 0.00000 0.00000 |
| 0.00000 1.00000 0.00000 0.00000 |
| 0.00000 0.00000 1.00000 0.00000 |
| 0.00000 0.00000 0.00000 1.00000 |</pre>
 
=={{header|Logo}}==
<syntaxhighlight lang="logo">TO LISTVMD :A :F :C :NV
;PROCEDURE LISTVMD
;A = LIST
;F = ROWS
;C = COLS
;NV = NAME OF MATRIX / VECTOR NEW
;this procedure transform a list in matrix / vector square or rect
(LOCAL "CF "CC "NV "T "W)
int n = a[0].length;
MAKE "CF 1
int m = a.length;
MAKE "CC 1
int p = b[0].length;
MAKE "NV (MDARRAY (LIST :F :C) 1)
MAKE "T :F * :C
FOR [Z 1 :T][MAKE "W ITEM :Z :A
MDSETITEM (LIST :CF :CC) :NV :W
MAKE "CC :CC + 1
IF :CC = :C + 1 [MAKE "CF :CF + 1 MAKE "CC 1]]
OUTPUT :NV
END
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
double ans[][] = new double[m][p];
TO XX
for(int i = 0;i < m;i++){
; MAIN PROGRAM
for(int j = 0;j < p;j++){
;LRCVS 10.04.12
for(int k = 0;k < n;k++){
; THIS PROGRAM multiplies two "square" matrices / vector ONLY!!!
ans[i][j] += a[i][k] * b[k][j];
; THE RECTANGULAR NOT WORK!!!
}
}
CT CS }HT
return ans;
; FIRST DATA MATRIX / VECTOR
}
MAKE "A [1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49]
MAKE "FA 5 ;"ROWS
MAKE "CA 5 ;"COLS
; SECOND DATA MATRIX / VECTOR
MAKE "B [2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50]
MAKE "FB 5 ;"ROWS
MAKE "CB 5 ;"COLS
IF (OR :FA <> :CA :FB <>:CB) [PRINT "Las_matrices/vector_no_son_cuadradas THROW
"TOPLEVEL ]
IFELSE (OR :CA <> :FB :FA <> :CB) [PRINT
"Las_matrices/vector_no_son_compatibles THROW "TOPLEVEL ][MAKE "MA LISTVMD :A
:FA :CA "MA MAKE "MB LISTVMD :B :FB :CB "MB] ;APPLICATION <<< "LISTVMD"
PRINT (LIST "THIS_IS: "ROWS "X "COLS)
PRINT []
PRINT (LIST :MA "=_M1 :FA "ROWS "X :CA "COLS)
PRINT []
PRINT (LIST :MB "=_M2 :FA "ROWS "X :CA "COLS)
PRINT []
MAKE "T :FA * :CB
MAKE "RE (ARRAY :T 1)
MAKE "CO 0
FOR [AF 1 :CA][
FOR [AC 1 :CA][
MAKE "TEMP 0
FOR [I 1 :CA ][
MAKE "TEMP :TEMP + (MDITEM (LIST :I :AF) :MA) * (MDITEM (LIST :AC :I) :MB)]
MAKE "CO :CO + 1
SETITEM :CO :RE :TEMP]]
PRINT []
PRINT (LIST "THIS_IS: :FA "ROWS "X :CB "COLS)
SHOW LISTVMD :RE :FA :CB "TO ;APPLICATION <<< "LISTVMD"
END
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\
M1 * M2 RESULT / SOLUTION
1 3 5 7 9 2 4 6 8 10 830 1880 2930 3980 5030
11 13 15 17 19 12 14 16 18 20 890 2040 3190 4340 5490
21 23 25 27 29 X 22 24 26 28 30 = 950 2200 3450 4700 5950
31 33 35 37 39 32 34 36 38 40 1010 2360 3710 5060 6410
41 43 45 47 49 42 44 46 48 50 1070 2520 3970 5420 6870
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\
NOW IN LOGO!!!!
THIS_IS: ROWS X COLS
{{1 3 5 7 9} {11 13 15 17 19} {21 23 25 27 29} {31 33 35 37 39} {41 43 45 47
49}} =_M1 5 ROWS X 5 COLS
{{2 4 6 8 10} {12 14 16 18 20} {22 24 26 28 30} {32 34 36 38 40} {42 44 46 48
50}} =_M2 5 ROWS X 5 COLS
THIS_IS: 5 ROWS X 5 COLS
{{830 1880 2930 3980 5030} {890 2040 3190 4340 5490} {950 2200 3450 4700 5950}
{1010 2360 3710 5060 6410} {1070 2520 3970 5420 6870}}</syntaxhighlight>
 
=={{header|MathematicaLua}}==
<syntaxhighlight lang="lua">function MatMul( m1, m2 )
M1 = {{1, 2},
if #m1[1] ~= #m2 then -- inner matrix-dimensions must agree
{3, 4},
{5, 6},return nil
end {7, 8}}
M2 = {{1, 2, 3},
{4, 5, 6}}
M = M1.M2
 
local res = {}
Or without the variables:
for i = 1, #m1 do
res[i] = {}
for j = 1, #m2[1] do
res[i][j] = 0
for k = 1, #m2 do
res[i][j] = res[i][j] + m1[i][k] * m2[k][j]
end
end
end
return res
end
 
-- Test for MatMul
{{1, 2}, {3, 4}, {5, 6}, {7, 8}}.{{1, 2, 3}, {4, 5, 6}}
mat1 = { { 1, 2, 3 }, { 4, 5, 6 } }
mat2 = { { 1, 2 }, { 3, 4 }, { 5, 6 } }
erg = MatMul( mat1, mat2 )
for i = 1, #erg do
for j = 1, #erg[1] do
io.write( erg[i][j] )
io.write(" ")
end
io.write("\n")
end </syntaxhighlight>
 
===SciLua===
The result is:
Using the sci.alg library from scilua.org
{{9, 12, 15}, {19, 26, 33}, {29, 40, 51}, {39, 54, 69}}
<syntaxhighlight lang="lua">local alg = require("sci.alg")
mat1 = alg.tomat{{1, 2, 3}, {4, 5, 6}}
mat2 = alg.tomat{{1, 2}, {3, 4}, {5, 6}}
mat3 = mat1[] ** mat2[]
print(mat3)</syntaxhighlight>
{{out}}
<pre>+22.00000,+28.00000
+49.00000,+64.00000</pre>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module CheckMatMult {
\\ Matrix Multiplication
\\ we use array pointers so we pass arrays byvalue but change this by reference
\\ this can be done because always arrays passed by reference,
\\ and Read statement decide if this goes to a pointer of array or copied to a local array
\\ the first line of code for MatMul is: Read a as array, b as array
\\ interpreter insert this at function construction.
\\ if a pointer inside function change to point to a new array, the this has no reflect to the passed array.
Function MatMul(a as array, b as array) {
if dimension(a)<>2 or dimension(b)<>2 then Error "Need two 2D arrays "
let a2=dimension(a,2), b1=dimension(b,1)
if a2<>b1 then Error "Need columns of first array equal to rows of second array"
let a1=dimension(a,1), b2=dimension(b,2)
let aBase=dimension(a,1,0)-1, bBase=dimension(b,1,0)-1
let aBase1=dimension(a,2,0)-1, bBase1=dimension(b,2,0)-1
link a,b to a(), b() ' change interface for arrays
dim base 1, c(a1, b2)
for i=1 to a1 : let ia=i+abase : for j=1 to b2 : let jb=j+bBase1 : for k=1 to a2
c(i,j)+=a(ia,k+aBase1)*b(k+bBase,jb)
next k : next j : next i
\\ redim to base 0
dim base 0, c(a1, b2)
=c()
}
\\ define arrays with different base per dimension
\\ res() defined as empty array
dim a(10 to 13, 4), b(4, 2 to 5), res()
\\ numbers from ADA task
a(10,0)= 1, 1, 1, 1, 2, 4, 8, 16, 3, 9, 27, 81, 4, 16, 64, 256
b(0,2)= 4, -3, 4/3, -1/4, -13/3, 19/4, -7/3, 11/24, 3/2, -2, 7/6, -1/4, -1/6, 1/4, -1/6, 1/24
res()=MatMul(a(), b())
for i=0 to 3 :for j=0 to 3
Print res(i,j),
next j : Print : next i
}
CheckMatMult
Module CheckMatMult2 {
\\ Matrix Multiplication
\\ pass arrays by reference
\\ if we change a passed array here, to a new array then this change also the reference array.
Function MatMul(&a(),&b()) {
if dimension(a())<>2 or dimension(b())<>2 then Error "Need two 2D arrays "
let a2=dimension(a(),2), b1=dimension(b(),1)
if a2<>b1 then Error "Need columns of first array equal to rows of second array"
let a1=dimension(a(),1), b2=dimension(b(),2)
let aBase=dimension(a(),1,0)-1, bBase=dimension(b(),1,0)-1
let aBase1=dimension(a(),2,0)-1, bBase1=dimension(b(),2,0)-1
dim base 1, c(a1, b2)
for i=1 to a1 : let ia=i+abase : for j=1 to b2 : let jb=j+bBase1 : for k=1 to a2
c(i,j)+=a(ia,k+aBase1)*b(k+bBase,jb)
next k : next j : next i
\\ redim to base 0
dim base 0, c(a1, b2)
=c()
}
\\ define arrays with different base per dimension
\\ res() defined as empty array
dim a(10 to 13, 4), b(4, 2 to 5), res()
\\ numbers from ADA task
a(10,0)= 1, 1, 1, 1, 2, 4, 8, 16, 3, 9, 27, 81, 4, 16, 64, 256
b(0,2)= 4, -3, 4/3, -1/4, -13/3, 19/4, -7/3, 11/24, 3/2, -2, 7/6, -1/4, -1/6, 1/4, -1/6, 1/24
res()=MatMul(&a(), &b())
for i=0 to 3 :for j=0 to 3
Print res(i,j),
next j : Print : next i
}
CheckMatMult2
</syntaxhighlight>
 
{{out}}
<pre>
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
</pre>
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">A := <<1|2|3>,<4|5|6>>;
 
B := <<1,2,3>|<4,5,6>|<7,8,9>|<10,11,12>>;
 
A . B;</syntaxhighlight>
{{out}}
<pre> [1 2 3]
A := [ ]
[4 5 6]
 
[1 4 7 10]
[ ]
B := [2 5 8 11]
[ ]
[3 6 9 12]
 
[14 32 50 68]
[ ]
[32 77 122 167]</pre>
 
=={{header|MathCortex}}==
<syntaxhighlight lang="mathcortex">
>> A = [2,3; -2,1]
2 3
-2 1
 
>> B = [1,2;4,2]
1 2
4 2
 
>> A * B
14 10
2 -2
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
 
The Wolfram Language supports both dot products and element-wise multiplication of matrices.
 
This computes a dot product:
 
<syntaxhighlight lang="mathematica">Dot[{{a, b}, {c, d}}, {{w, x}, {y, z}}]</syntaxhighlight>
 
With the following output:
 
<syntaxhighlight lang="mathematica">{{a w + b y, a x + b z}, {c w + d y, c x + d z}}</syntaxhighlight>
 
This also computes a dot product, using the infix . notation:
 
<syntaxhighlight lang="mathematica">{{a, b}, {c, d}} . {{w, x}, {y, z}}</syntaxhighlight>
 
This does element-wise multiplication of matrices:
 
<syntaxhighlight lang="mathematica">Times[{{a, b}, {c, d}}, {{w, x}, {y, z}}]</syntaxhighlight>
 
With the following output:
 
<syntaxhighlight lang="mathematica">{{a w, b x}, {c y, d z}}</syntaxhighlight>
 
Alternative infix notations '*' and ' ' (space, indicating multiplication):
 
<syntaxhighlight lang="mathematica">{{a, b}, {c, d}}*{{w, x}, {y, z}}</syntaxhighlight>
<syntaxhighlight lang="mathematica">{{a, b}, {c, d}} {{w, x}, {y, z}}</syntaxhighlight>
 
In all cases matrices can be fully symbolic or numeric or mixed symbolic and numeric.
Numeric matrices support arbitrary numerical magnitudes, arbitrary precision as well
as complex numbers:
 
<syntaxhighlight lang="mathematica">Dot[{{85, 60, 65}, {54, 99, 33}, {46, 52, 87}}, {{89, 77, 98}, {55, 27, 25}, {80, 68, 85}}]</syntaxhighlight>
 
With the following output:
 
<syntaxhighlight lang="mathematica">{{16065, 12585, 15355}, {12891, 9075, 10572}, {13914, 10862, 13203}}</syntaxhighlight>
 
=={{header|MATLAB}}==
Matlab contains two methods of multiplying matrices: by using the "mtimes(matrix,matrix)" function, or the "*" operator.
 
<syntaxhighlight lang="matlab">>> A = [1 2;3 4]
 
A =
 
1 2
3 4
 
>> B = [5 6;7 8]
 
B =
 
5 6
7 8
 
>> A * B
 
ans =
 
19 22
43 50
 
>> mtimes(A,B)
 
ans =
 
19 22
43 50</syntaxhighlight>
 
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">a: matrix([1, 2],
[3, 4],
[5, 6],
[7, 8])$
 
b: matrix([1, 2, 3],
[4, 5, 6])$
 
a . b;
/* matrix([ 9, 12, 15],
[19, 26, 33],
[29, 40, 51],
[39, 54, 69]) */</syntaxhighlight>
 
=={{header|Nial}}==
<syntaxhighlight lang="nial">|A := 4 4 reshape 1 1 1 1 2 4 8 16 3 9 27 81 4 16 64 256
=1 1 1 1
=2 4 8 16
=3 9 27 81
=4 16 64 256
|B := inverse A
 
|A innerproduct B
=1. 0. 8.3e-17 -2.9e-16
=1.3e-15 1. -4.4e-16 -3.3e-16
=0. 0. 1. 4.4e-16
=0. 0. 0. 1.</syntaxhighlight>
 
=={{header|Nim}}==
{{libheader|strfmt}}
<syntaxhighlight lang="nim">import strfmt
 
type Matrix[M, N: static[int]] = array[M, array[N, float]]
 
let a = [[1.0, 1.0, 1.0, 1.0],
[2.0, 4.0, 8.0, 16.0],
[3.0, 9.0, 27.0, 81.0],
[4.0, 16.0, 64.0, 256.0]]
 
let b = [[ 4.0, -3.0 , 4/3.0, -1/4.0],
[-13/3.0, 19/4.0, -7/3.0, 11/24.0],
[ 3/2.0, -2.0 , 7/6.0, -1/4.0],
[ -1/6.0, 1/4.0, -1/6.0, 1/24.0]]
 
proc `$`(m: Matrix): string =
result = "(["
for r in m:
if result.len > 2: result.add "]\n ["
for val in r: result.add val.format("8.2f")
result.add "])"
 
proc `*`[M, P, N](a: Matrix[M, P]; b: Matrix[P, N]): Matrix[M, N] =
for i in result.low .. result.high:
for j in result[0].low .. result[0].high:
for k in a[0].low .. a[0].high:
result[i][j] += a[i][k] * b[k][j]
 
echo a
echo b
echo a * b
echo b * a</syntaxhighlight>
 
{{out}}
|A innerproduct B
=1.<pre>([ 1.00 01.00 81.3e-1700 -21.9e-1600]
=1.3e-15[ 1 2.00 -4.4e-1600 -38.3e-00 16.00]
=0.[ 3.00 09.00 127.00 481.4e-1600]
=0.[ 4.00 016.00 064.00 1256.00])
([ 4.00 -3.00 1.33 -0.25]
[ -4.33 4.75 -2.33 0.46]
[ 1.50 -2.00 1.17 -0.25]
[ -0.17 0.25 -0.17 0.04])
([ 1.00 0.00 -0.00 -0.00]
[ 0.00 1.00 -0.00 -0.00]
[ 0.00 0.00 1.00 0.00]
[ 0.00 0.00 0.00 1.00])
([ 1.00 0.00 0.00 0.00]
[ 0.00 1.00 -0.00 0.00]
[ 0.00 0.00 1.00 0.00]
[ 0.00 0.00 -0.00 1.00])</pre>
 
=={{header|OCaml}}==
 
This version works on arrays of arrays of ints:
<syntaxhighlight lang="ocaml">let matrix_multiply x y =
let x0 = Array.length x
and y0 = Array.length y in
Line 590 ⟶ 4,655:
done
done;
z</ocamlsyntaxhighlight>
 
# matrix_multiply [|[|1;2|];[|3;4|]|] [|[|-3;-8;3|];[|-2;1;4|]|];;
Line 597 ⟶ 4,662:
{{trans|Scheme}}
This version works on lists of lists of ints:
<syntaxhighlight lang="ocaml">(* equivalent to (apply map ...) *)
let rec mapn f lists =
assert (lists <> []);
Line 613 ⟶ 4,678:
(List.map2 ( * ) row column))
m2)
m1</ocamlsyntaxhighlight>
 
# matrix_multiply [[1;2];[3;4]] [[-3;-8;3];[-2;1;4]];;
- : int list list = [[-7; -6; 11]; [-17; -20; 25]]
 
=={{header|Octave}}==
<syntaxhighlight lang="octave">a = zeros(4);
% prepare the matrix
% 1 1 1 1
% 2 4 8 16
% 3 9 27 81
% 4 16 64 256
for i = 1:4
for j = 1:4
a(i, j) = i^j;
endfor
endfor
b = inverse(a);
a * b</syntaxhighlight>
 
=={{header|Ol}}==
This short version works on lists of lists length less than 253 rows and less than 253 columns.
<syntaxhighlight lang="scheme">; short version based on 'apply'
(define (matrix-multiply matrix1 matrix2)
(map
(lambda (row)
(apply map
(lambda column
(apply + (map * row column)))
matrix2))
matrix1))
</syntaxhighlight>
 
> (matrix-multiply '((1 2) (3 4)) '((-3 -8 3) (-2 1 4)))
((-7 -6 11) (-17 -20 25))
 
This long version works on lists of lists with any matrix dimensions.
<syntaxhighlight lang="scheme">; long version based on recursive cycles
(define (matrix-multiply A B)
(define m (length A))
(define n (length (car A)))
(assert (eq? (length B) n) ===> #true)
(define q (length (car B)))
(define (at m x y)
(lref (lref m x) y))
 
 
(let mloop ((i (- m 1)) (rows #null))
(if (< i 0)
rows
(mloop
(- i 1)
(cons
(let rloop ((j (- q 1)) (r #null))
(if (< j 0)
r
(rloop
(- j 1)
(cons
(let loop ((k 0) (c 0))
(if (eq? k n)
c
(loop (+ k 1) (+ c (* (at A i k) (at B k j))))))
r))))
rows)))))
</syntaxhighlight>
 
Testing large matrices:
<syntaxhighlight lang="scheme">; [372x17] * [17x372]
(define M 372)
(define N 17)
 
; [0 1 2 ... 371]
; [1 2 3 ... 372]
; [2 3 4 ... 373]
; ...
; [16 17 ... 387]
(define A (map (lambda (i)
(iota M i))
(iota N)))
 
; [0 1 2 ... 16]
; [1 2 3 ... 17]
; [2 3 4 ... 18]
; ...
; [371 372 ... 387]
(define B (map (lambda (i)
(iota N i))
(iota M)))
 
(for-each print (matrix-multiply A B))
</syntaxhighlight>
{{Out}}
<pre>
(17090486 17159492 17228498 17297504 17366510 17435516 17504522 17573528 17642534 17711540 17780546 17849552 17918558 17987564 18056570 18125576 18194582)
(17159492 17228870 17298248 17367626 17437004 17506382 17575760 17645138 17714516 17783894 17853272 17922650 17992028 18061406 18130784 18200162 18269540)
(17228498 17298248 17367998 17437748 17507498 17577248 17646998 17716748 17786498 17856248 17925998 17995748 18065498 18135248 18204998 18274748 18344498)
(17297504 17367626 17437748 17507870 17577992 17648114 17718236 17788358 17858480 17928602 17998724 18068846 18138968 18209090 18279212 18349334 18419456)
(17366510 17437004 17507498 17577992 17648486 17718980 17789474 17859968 17930462 18000956 18071450 18141944 18212438 18282932 18353426 18423920 18494414)
(17435516 17506382 17577248 17648114 17718980 17789846 17860712 17931578 18002444 18073310 18144176 18215042 18285908 18356774 18427640 18498506 18569372)
(17504522 17575760 17646998 17718236 17789474 17860712 17931950 18003188 18074426 18145664 18216902 18288140 18359378 18430616 18501854 18573092 18644330)
(17573528 17645138 17716748 17788358 17859968 17931578 18003188 18074798 18146408 18218018 18289628 18361238 18432848 18504458 18576068 18647678 18719288)
(17642534 17714516 17786498 17858480 17930462 18002444 18074426 18146408 18218390 18290372 18362354 18434336 18506318 18578300 18650282 18722264 18794246)
(17711540 17783894 17856248 17928602 18000956 18073310 18145664 18218018 18290372 18362726 18435080 18507434 18579788 18652142 18724496 18796850 18869204)
(17780546 17853272 17925998 17998724 18071450 18144176 18216902 18289628 18362354 18435080 18507806 18580532 18653258 18725984 18798710 18871436 18944162)
(17849552 17922650 17995748 18068846 18141944 18215042 18288140 18361238 18434336 18507434 18580532 18653630 18726728 18799826 18872924 18946022 19019120)
(17918558 17992028 18065498 18138968 18212438 18285908 18359378 18432848 18506318 18579788 18653258 18726728 18800198 18873668 18947138 19020608 19094078)
(17987564 18061406 18135248 18209090 18282932 18356774 18430616 18504458 18578300 18652142 18725984 18799826 18873668 18947510 19021352 19095194 19169036)
(18056570 18130784 18204998 18279212 18353426 18427640 18501854 18576068 18650282 18724496 18798710 18872924 18947138 19021352 19095566 19169780 19243994)
(18125576 18200162 18274748 18349334 18423920 18498506 18573092 18647678 18722264 18796850 18871436 18946022 19020608 19095194 19169780 19244366 19318952)
(18194582 18269540 18344498 18419456 18494414 18569372 18644330 18719288 18794246 18869204 18944162 19019120 19094078 19169036 19243994 19318952 19393910)
</pre>
 
=={{header|ooRexx}}==
<syntaxhighlight lang="ooRexx">/*REXX program multiplies two matrices together, */
/* displays the matrices and the result. */
Signal On syntax
x.=0
a=.matrix~new('A',4,2,1 2 3 4 5 6 7 8) /* create matrix A */
b=.matrix~new('B',2,3,1 2 3 4 5 6) /* create matrix B */
If a~cols<>b~rows Then
Call exit 'Matrices are incompatible for matrix multiplication',
'a~cols='a~cols'<>b~rows='||b~rows
-- say a~name'[2,2] changed from' a~set(2,2,4711) 'to 4711' ; Pull .
c=multMat(a,b) /* multiply A x B */
a~show
b~show
c~show
Exit
 
multMat: Procedure
Use Arg a,b
c.=0
Do i=1 To a~rows
Do j=1 To b~cols
Do k=1 To a~cols
c.i.j=c.i.j+a~element(i,k)*b~element(k,j)
End /*k*/
End /*j*/
End /*i*/
mm=''
Do i=1 To a~rows
Do j=1 To b~cols
mm=mm C.i.j
End /*j*/
End /*i*/
c=.matrix~new('C',a~rows,b~cols,mm)
Return c
/*--------------------------------------------------------------------*/
Exit:
Say arg(1)
Exit
Syntax:
Say 'Syntax raised in line' sigl
Say sourceline(sigl)
Say 'rc='rc '('errortext(rc)')'
Say '***** There was a problem!'
Exit
 
::class Matrix
/********************************************************************
* Matrix is implemented as an array of rows
* where each row is an arryay of elements.
********************************************************************/
::Attribute name
::Attribute rows
::Attribute cols
 
::Method init
expose m name rows cols
Use Arg name,rows,cols,elements
If words(elements)<>(rows*cols) Then Do
Say 'incorrect number of elements ('words(elements)')<>'||(rows*cols)
m=.nil
Return
End
m=.array~new
Do r=1 To rows
ro=.array~new
Do c=1 To cols
Parse Var elements e elements
ro~append(e)
End
m~append(ro)
End
 
::Method element /* get an element's value */
expose m
Use Arg r,c
ro=m[r]
Return ro[c]
 
::Method set /* set an element's value and return its previous */
expose m
Use Arg r,c,new
ro=m[r]
old=ro[c]
ro[c]=new
Return old
 
::Method show /* display the matrix */
expose m name rows cols
z='+'
b6=left('',6)
Say ''
Say b6 copies('-',7) 'matrix' name copies('-',7)
w=0
Do r=1 To rows
ro=m[r]
Do c=1 To cols
x=ro[c]
w=max(w,length(x))
End
End
Say b6 b6 '+'copies('-',cols*(w+1)+1)'+' /* top border */
Do r=1 To rows
ro=m[r]
line='|' right(ro[1],w) /* element of first colsumn */ /* start with long vertical bar */
Do c=2 To cols /* loop for other columns */
line=line right(ro[c],w) /* append the elements */
End /* c */
Say b6 b6 line '|' /* append a long vertical bar. */
End /* r */
Say b6 b6 '+'copies('-',cols*(w+1)+1)'+' /* bottom border */
Return</syntaxhighlight>
{{Out}}
<pre>
------- matrix A -------
+-----+
| 1 2 |
| 3 4 |
| 5 6 |
| 7 8 |
+-----+
 
------- matrix B -------
+-------+
| 1 2 3 |
| 4 5 6 |
+-------+
 
------- matrix C -------
+----------+
| 9 12 15 |
| 19 26 33 |
| 29 40 51 |
| 39 54 69 |
+----------+ </pre>
 
 
 
=={{header|OxygenBasic}}==
Generic MatMul:
<syntaxhighlight lang="text">
'generic with striding pointers
'def typ float
typedef float typ
'
function MatMul(typ *r,*a,*b, int n=4) 'NxN MATRIX : N=1..
============================================================
int ystep=sizeof typ
int xstep=n*sizeof typ
int i,j,k
sys px
for i=1 to n
px=@a
for j=1 to n
r=0
for k=1 to n
r+=(a*b)
@a+=xstep
@b+=ystep
next
@r+=ystep
px+=ystep
@a=px
@b-=xstep
next
@a-=xstep
@b+=xstep
next
end function
</syntaxhighlight>
 
When using matrices in Video graphics, speed is important. Here is a matrix multiplier written in OxygenBasics's x86 Assembly code.
<syntaxhighlight lang="oxygenbasic">
'Example of matrix layout mapped to an array of 4x4 cells
'
' 0 4 8 C
' 1 5 9 D
' 2 6 A E
' 3 7 B F
'
 
% MatrixType double
 
sub MatrixMul(MatrixType *A,*B,*C, sys n)
'========================================
'
'
#if leftmatch matrixtype single
% OneStep 4
% mtype single
#endif
'
#if leftmatch matrixtype double
% OneStep 8
% mtype double
#endif
 
sys pa=@A, pb=@B, pc=@C
sys ColStep=OneStep*n
 
mov ecx,pa
mov edx,pb
mov eax,pc
 
mov esi,n
(
call column : dec esi : jg repeat
)
exit sub
 
column:
'======
 
mov edi,n
(
call cell : dec edi : jg repeat
)
add edx,ColStep
sub ecx,ColStep
ret
 
cell: ' row A * column B
'=======================
 
'matrix data is stored ascending vertically then horizontally
'thus rows are minor, columns are major
'
push ecx
push edx
push eax
mov eax,4
fldz
(
fld mtype [ecx]
fmul mtype [edx]
faddp st1
add ecx,ColStep 'next column of matrix A
add edx,OneStep 'next row of matrix B
dec eax
jnz repeat
)
pop eax
fstp mtype [eax] 'assign to next row of matrix C
'
pop edx
pop ecx
add eax,OneStep 'next cell in column of matrix C (columns then rows)
add ecx,OneStep 'next row of matrix A
ret
'
end sub
 
 
function ShowMatrix(MatrixType*A,sys n) as string
'================================================
string cr=chr(13)+chr(10), tab=chr(9)
function="MATRIX " n "x" n cr cr
sys i,j,m
'
for i=1 to n
m=0
for j=1 to n
function+=str( A[m+i] ) tab
m+=n
next
function+=cr
next
end function
 
'TEST
'====
 
% n 4
MatrixType A[n*n],B[n*n],C[n*n]
 
 
'reading vertically (minor) then left to right (major)
 
A <= 4,0,0,1, 0,4,0,0, 0,0,4,0, 0,0,0,4
 
B <= 2,0,0,2, 0,2,0,0, 0,0,2,0, 0,0,0,2
 
 
MatrixMul A,B,C,n
 
Print ShowMatrix C,n
</syntaxhighlight>
 
=={{header|PARI/GP}}==
<syntaxhighlight lang="parigp">M*N</syntaxhighlight>
 
=={{header|Perl}}==
For most applications involving extensive matrix arithmetic, using the CPAN module called "PDL" (that stands for "Perl Data Language") would probably be the easiest and most efficient approach. That said, here's an implementation of matrix multiplication in plain Perl.
 
This function takes two references to arrays of arrays and returns the product as a reference to a new anonymous array of arrays.
<perl>sub mmult
 
{our @a; local *a = shift;
<syntaxhighlight lang="perl">sub mmult
{
our @a; local *a = shift;
our @b; local *b = shift;
my @p = [];
my $rows = @a;
my $cols = @{ $b[0] };
my $n = @b - 1;
for (my $r = 0 ; $r < $rows ; ++$r)
{
{for (my $c = 0 ; $c < $cols ; ++$c)
for (my {$p[$r][$c] += $a[$r][$_]0 *; $b[$_][$c] foreach< 0$cols ..; ++$n;}}c)
{
return [@p];}</perl>
$p[$r][$c] += $a[$r][$_] * $b[$_][$c]
foreach 0 .. $n;
}
}
return [@p];
}
 
sub display { join("\n" => map join(" " => map(sprintf("%4d", $_), @$_)), @{+shift})."\n" }
This function takes two references to arrays of arrays and returns the product as a reference to a new anonymous array of arrays.
 
@a =
=={{header|Pop11}}==
(
[1, 2],
[3, 4]
);
 
@b =
(
[-3, -8, 3],
[-2, 1, 4]
);
 
$c = mmult(\@a,\@b);
display($c)</syntaxhighlight>
{{out}}
<pre> -7 -6 11
-17 -20 25</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ha</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">hb</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]},</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">wa</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">hb</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"invalid aguments"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">),</span><span style="color: #000000;">ha</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ha</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">wb</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">wa</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">ppOpt</span><span style="color: #0000FF;">({</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_IntFmt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%3d"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_FltFmt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%3.0f"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_IntCh</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">A</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span> <span style="color: #0000FF;">}},</span>
<span style="color: #000000;">B</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span> <span style="color: #0000FF;">}}</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">A</span><span style="color: #0000FF;">,</span><span style="color: #000000;">B</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">C</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">16</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">27</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">81</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">64</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">256</span> <span style="color: #0000FF;">}},</span>
<span style="color: #000000;">D</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span> <span style="color: #000000;">4</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{-</span><span style="color: #000000;">13</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">19</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">7</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">/</span><span style="color: #000000;">24</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">/</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span> <span style="color: #000000;">4</span> <span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">24</span> <span style="color: #0000FF;">}}</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">C</span><span style="color: #0000FF;">,</span><span style="color: #000000;">D</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">F</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">}},</span>
<span style="color: #000000;">G</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}}</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">F</span><span style="color: #0000FF;">,</span><span style="color: #000000;">G</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">H</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}},</span>
<span style="color: #000000;">I</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">}}</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">H</span><span style="color: #0000FF;">,</span><span style="color: #000000;">I</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">R</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{-</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">}}</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">R</span><span style="color: #0000FF;">,</span><span style="color: #000000;">R</span><span style="color: #0000FF;">))</span>
<span style="color: #000080;font-style:italic;">-- large matrix example from OI:</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">J</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">row</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span><span style="color: #000000;">371</span><span style="color: #0000FF;">}),</span>
<span style="color: #000000;">K</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">row</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">371</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span><span style="color: #000000;">16</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">J</span><span style="color: #0000FF;">,</span><span style="color: #000000;">K</span><span style="color: #0000FF;">),{</span><span style="color: #008000;">""</span><span style="color: #0000FF;">},</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}),</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{{ 9, 12, 15},
define matmul(a, b) -> c;
{ 19, 26, 33},
{ 29, 40, 51},
{ 39, 54, 69}}
{{ 1, 0, 0, 0},
{ 0, 1, 0, 0},
{ 0, 0, 1, 0},
{ 0, 0, 0, 1}}
{{ 1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}}
{{ 19, 22},
{ 43, 50}}
{{ 0, 1},
{ -1, 0}}
{{17090486,17159492, `...`, 18125576,18194582},
{17159492,17228870, `...`, 18200162,18269540},
`...`,
{18125576,18200162, `...`, 19244366,19318952},
{18194582,18269540, `...`, 19318952,19393910}}
</pre>
Note that you get some "-0" in the second result under p2js due to differences in rounding behaviour between JavaScript and desktop/Phix.
 
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(de matMul (Mat1 Mat2)
(mapcar
'((Row)
(apply mapcar Mat2
'(@ (sum * Row (rest))) ) )
Mat1 ) )
 
(matMul
'((1 2 3) (4 5 6))
'((6 -1) (3 2) (0 -3)) )</syntaxhighlight>
{{out}}
<pre>-> ((12 -6) (39 -12))</pre>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
/* Matrix multiplication of A by B, yielding C */
MMULT: procedure (a, b, c);
declare (a, b, c)(*,*) float controlled;
declare (i, j, m, n, p) fixed binary;
 
if hbound(a,2) ^= hbound(b,1) then
do;
put skip list
('Matrices are incompatible for matrix multiplication');
signal error;
end;
 
m = hbound(a, 1); p = hbound(b, 2);
if allocation(c) > 0 then free c;
 
allocate c(m,p);
 
do i = 1 to m;
do j = 1 to p;
c(i,j) = sum(a(i,*) * b(*,j) );
end;
end;
end MMULT;
</syntaxhighlight>
 
=={{header|Pop11}}==
 
<syntaxhighlight lang="pop11">define matmul(a, b) -> c;
lvars ba = boundslist(a), bb = boundslist(b);
lvars i, i0 = ba(1), i1 = ba(2);
Line 660 ⟶ 5,278:
endfor;
endfor;
enddefine;</syntaxhighlight>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function multarrays($a, $b) {
$n,$m,$p = ($a.Count - 1), ($b.Count - 1), ($b[0].Count - 1)
if ($a[0].Count -ne $b.Count) {throw "Multiplication impossible"}
$c = @(0)*($a[0].Count)
foreach ($i in 0..$n) {
$c[$i] = foreach ($j in 0..$p) {
$sum = 0
foreach ($k in 0..$m){$sum += $a[$i][$k]*$b[$k][$j]}
$sum
}
}
$c
}
 
function show($a) { $a | foreach{"$_"}}
 
$a = @(@(1,2),@(3,4))
$b = @(@(5,6),@(7,8))
$c = @(5,6)
"`$a ="
show $a
""
"`$b ="
show $b
""
"`$c ="
$c
""
"`$a * `$b ="
show (multarrays $a $b)
" "
"`$a * `$c ="
show (multarrays $a $c)
</syntaxhighlight>
<b>Output:</b>
<pre>
$a =
1 2
3 4
 
$b =
5 6
7 8
 
$c =
5
6
 
$a * $b =
19 22
43 50
$a * $c =
17
39
</pre>
 
=={{header|Prolog}}==
{{trans|Scheme}}
{{works with|SWI Prolog|5.9.9}}
<syntaxhighlight lang="prolog">% SWI-Prolog has transpose/2 in its clpfd library
:- use_module(library(clpfd)).
 
% N is the dot product of lists V1 and V2.
dot(V1, V2, N) :- maplist(product,V1,V2,P), sumlist(P,N).
product(N1,N2,N3) :- N3 is N1*N2.
 
% Matrix multiplication with matrices represented
% as lists of lists. M3 is the product of M1 and M2
mmult(M1, M2, M3) :- transpose(M2,MT), maplist(mm_helper(MT), M1, M3).
mm_helper(M2, I1, M3) :- maplist(dot(I1), M2, M3).</syntaxhighlight>
 
=={{header|PureBasic}}==
Matrices represented as integer arrays with rows in the first dimension and columns in the second.
<syntaxhighlight lang="purebasic">Procedure multiplyMatrix(Array a(2), Array b(2), Array prd(2))
Protected ar = ArraySize(a()) ;#rows for matrix a
Protected ac = ArraySize(a(), 2) ;#cols for matrix a
Protected br = ArraySize(b()) ;#rows for matrix b
Protected bc = ArraySize(b(), 2) ;#cols for matrix b
If ac = br
Dim prd(ar, bc)
Protected i, j, k
For i = 0 To ar
For j = 0 To bc
For k = 0 To br ;ac
prd(i, j) = prd(i, j) + (a(i, k) * b(k, j))
Next
Next
Next
ProcedureReturn #True ;multiplication performed, product in prd()
Else
ProcedureReturn #False ;multiplication not performed, dimensions invalid
EndIf
EndProcedure</syntaxhighlight>
Additional code to demonstrate use.
<syntaxhighlight lang="purebasic">DataSection
Data.i 2,3 ;matrix a (#rows, #cols)
Data.i 1,2,3, 4,5,6 ;elements by row
Data.i 3,1 ;matrix b (#rows, #cols)
Data.i 1, 5, 9 ;elements by row
EndDataSection
 
Procedure displayMatrix(Array a(2), text.s)
Protected i, j
Protected columns = ArraySize(a(), 2), rows = ArraySize(a(), 1)
PrintN(text + ": (" + Str(rows + 1) + ", " + Str(columns + 1) + ")")
For i = 0 To rows
For j = 0 To columns
Print(LSet(Str(a(i, j)), 4, " "))
Next
PrintN("")
Next
PrintN("")
EndProcedure
 
Procedure loadMatrix(Array a(2))
Protected rows, columns, i, j
Read.i rows
Read.i columns
Dim a(rows - 1, columns - 1)
For i = 0 To rows - 1
For j = 0 To columns - 1
Read.i a(i, j)
Next
Next
EndProcedure
 
Dim a(0,0)
Dim b(0,0)
Dim c(0,0)
 
If OpenConsole()
loadMatrix(a()): displayMatrix(a(), "matrix a")
loadMatrix(b()): displayMatrix(b(), "matrix b")
If multiplyMatrix(a(), b(), c())
displayMatrix(c(), "product of a * b")
Else
PrintN("product of a * b is undefined")
EndIf
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
Input()
CloseConsole()
EndIf</syntaxhighlight>
{{out}}
<pre>matrix a: (2, 3)
1 2 3
4 5 6
 
matrix b: (3, 1)
1
5
9
 
product of a * b: (2, 1)
38
83</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">a=((1, 1, 1, 1), # matrix A #
<Python>
a=((1, 1, 1, 1), # matrix A #
(2, 4, 8, 16),
(3, 9, 27, 81),
Line 679 ⟶ 5,463:
def MatrixMul( mtx_a, mtx_b):
tpos_b = zip( *mtx_b)
rtn = [[ sum( map(lambda ea,eb:ea*eb for ea,eb in zip(a,b)) for b in tpos_b] for a in mtx_a]
return rtn
 
Line 702 ⟶ 5,486:
print '%8.2f '%val,
print ']'
print ')'</syntaxhighlight>
 
</Python>
 
Another one, {{trans|Scheme}}
<syntaxhighlight lang="python">from operator import mul
 
def matrixMul(m1, m2):
return map(
return map(lambda row: map(lambda *column: sum(map(mul, row, column)),
lambda row:
*m2),
m1)</python>map(
lambda *column:
sum(map(mul, row, column)),
*m2),
m1)</syntaxhighlight>
 
Using list comprehensions, multiplying matrices represented as lists of lists. (Input is not validated):
<syntaxhighlight lang="python">def mm(A, B):
return [[sum(x * B[i][col] for i,x in enumerate(row)) for col in range(len(B[0]))] for row in A]</syntaxhighlight>
 
Another one, use numpy the most popular array package for python
<syntaxhighlight lang="python">
import numpy as np
np.dot(a,b)
#or if a is an array
a.dot(b)</syntaxhighlight>
 
=={{header|R}}==
<syntaxhighlight lang="r">a %*% b</syntaxhighlight>
a %*% b
 
=={{header|Racket}}==
{{trans|Scheme}}
 
<syntaxhighlight lang="racket">
#lang racket
(define (m-mult m1 m2)
(for/list ([r m1])
(for/list ([c (apply map list m2)])
(apply + (map * r c)))))
(m-mult '((1 2) (3 4)) '((5 6) (7 8)))
;; -> '((19 22) (43 50))
</syntaxhighlight>
 
Alternative:
<syntaxhighlight lang="racket">
#lang racket
(require math)
(matrix* (matrix [[1 2] [3 4]]) (matrix [[5 6] [7 8]]))
;; -> (array #[#[19 22] #[43 50]])
</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
 
{{trans|Perl 5}}
 
{{works with|Rakudo|2015-09-22}}
 
There are three ways in which this example differs significantly from the original Perl&nbsp;5 code. These are not esoteric differences; all three of these features typically find heavy use in Raku.
 
First, we can use a real signature that can bind two arrays as arguments, because the default in Raku is not to flatten arguments unless the signature specifically requests it.
We don't need to pass the arrays with backslashes because the binding choice is made lazily
by the signature itself at run time; in Perl&nbsp;5 this choice must be made at compile time.
Also, we can bind the arrays to formal parameters that are really lexical variable names; in Perl&nbsp;5 they can only be bound to global array objects (via a typeglob assignment).
 
Second, we use the X cross operator in conjunction with a two-parameter closure to avoid writing
nested loops. The X cross operator, along with Z, the zip operator, is a member of a class of operators that expect lists on both sides, so we call them "list infix" operators. We tend to define these operators using capital letters so that they stand out visually from the lists on both sides. The cross operator makes every possible combination of the one value from the first list followed by one value from the second. The right side varies most rapidly, just like an inner loop. (The X and Z operators may both also be used as meta-operators, Xop or Zop, distributing some other operator "op" over their generated list. All metaoperators in Raku may be applied to user-defined operators as well.)
 
Third is the use of prefix <tt>^</tt> to generate a list of numbers in a range. Here it is
used on an array to generate all the indexes of the array. We have a way of indicating a range by the infix <tt>..</tt> operator, and you can put a <tt>^</tt> on either end to exclude that endpoint. We found ourselves writing <tt>0 ..^ @a</tt> so often that we made <tt>^@a</tt> a shorthand for that. It's pronounced "upto". The array is evaluated in a numeric context, so it returns the number of elements it contains, which is exactly what you want for the exclusive limit of the range.
 
<syntaxhighlight lang="raku" line>sub mmult(@a,@b) {
my @p;
for ^@a X ^@b[0] -> ($r, $c) {
@p[$r][$c] += @a[$r][$_] * @b[$_][$c] for ^@b;
}
@p;
}
 
my @a = [1, 1, 1, 1],
[2, 4, 8, 16],
[3, 9, 27, 81],
[4, 16, 64, 256];
 
my @b = [ 4 , -3 , 4/3, -1/4 ],
[-13/3, 19/4, -7/3, 11/24],
[ 3/2, -2 , 7/6, -1/4 ],
[ -1/6, 1/4, -1/6, 1/24];
 
.say for mmult(@a,@b);</syntaxhighlight>
 
{{out}}
<pre>[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]</pre>
 
Note that these are not rounded values, but exact, since all the math was done in rationals.
Hence we need not rely on format tricks to hide floating-point inaccuracies.
 
Just for the fun of it, here's a functional version that uses no temp variables or side effects.
Some people will find this more readable and elegant, and others will, well, not.
 
<syntaxhighlight lang="raku" line>sub mmult(\a,\b) {
[
for ^a -> \r {
[
for ^b[0] -> \c {
[+] a[r;^b] Z* b[^b;c]
}
]
}
]
}</syntaxhighlight>
 
Here we use Z with an "op" of <tt>*</tt>, which is a zip with multiply. This, along with the <tt>[+]</tt> reduction operator, replaces the inner loop. We chose to split the outer X loop back into two loops to make it convenient to collect each subarray value in <tt>[...]</tt>. It just collects all the returned values from the inner loop and makes an array of them. The outer loop simply returns the outer array.
 
For conciseness, the above could be written as:
 
<syntaxhighlight lang="raku" line>multi infix:<×> (@A, @B) {
@A.map: -> @a { do [+] @a Z× @B[*;$_] for ^@B[0] }
}</syntaxhighlight>
 
Which overloads the built-in <code>×</code> operator for <code>Positional</code> operands. You’ll notice we are using <code>×</code> inside of the definition; since the arguments there are <code>Scalar</code>, it multiplies two numbers. Also, <code>do</code> is an alternative to parenthesising the loop for getting its result.
 
{{works with|Rakudo|2022.07-3}}
 
Here is a more functional version, expressing the product of two matrices as the cross dot product of the first matrix with the transpose of the second :
 
<syntaxhighlight lang="raku" line>sub infix:<·> { [+] @^a Z* @^b }
sub infix:<×>(@A, @B) { (@A X· [Z] @B).rotor(@B) }
</syntaxhighlight>
 
=={{header|Rascal}}==
<syntaxhighlight lang="rascal">public rel[real, real, real] matrixMultiplication(rel[real x, real y, real v] matrix1, rel[real x, real y, real v] matrix2){
if (max(matrix1.x) == max(matrix2.y)){
p = {<x1,y1,x2,y2, v1*v2> | <x1,y1,v1> <- matrix1, <x2,y2,v2> <- matrix2};
 
result = {};
for (y <- matrix1.y){
for (x <- matrix2.x){
v = (0.0 | it + v | <x1, y1, x2, y2, v> <- p, x==x2 && y==y1, x1==y2 && y2==x1);
result += <x,y,v>;
}
}
return result;
}
else throw "Matrix sizes do not match.";
 
//a matrix, given by a relation of the x-coordinate, y-coordinate and value.
public rel[real x, real y, real v] matrixA = {
<0.0,0.0,12.0>, <0.0,1.0, 6.0>, <0.0,2.0,-4.0>,
<1.0,0.0,-51.0>, <1.0,1.0,167.0>, <1.0,2.0,24.0>,
<2.0,0.0,4.0>, <2.0,1.0,-68.0>, <2.0,2.0,-41.0>
};</syntaxhighlight>
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX program calculates the Kronecker product of two arbitrary size matrices. */
Signal On syntax
x.=0
amat=4X2 1 2 3 4 5 6 7 8 /* define A matrix size and elements */
bmat=2X3 1 2 3 4 5 6 /* " B " " " " */
Call makeMat 'A',amat /* construct A matrix from elements */
Call makeMat 'B',bmat /* " B " " " */
If cols.A<>rows.B Then
Call exit 'Matrices are incompatible for matrix multiplication',
'cols.A='cols.A'<>rows.B='rows.B
Call multMat /* multiply A x B */
Call showMat 'A',amat /* display matrix A */
Call showMat 'B',bmat /* " " B */
Call showMat 'C',mm /* " " C */
Exit
/*--------------------------------------------------------------------*/
makeMat:
Parse Arg what,size elements /*elements: e.1.1 e.1.2 - e.rows cols*/
Parse Var size rows 'X' cols
x.what.shape=rows cols
Parse Value rows cols With rows.what cols.what
n=0
Do r=1 To rows
Do c=1 To cols
n=n+1
element=word(elements,n)
x.what.r.c=element
End
End
Return
/*--------------------------------------------------------------------*/
multMat:
/* x.C.*.* = x.A.*.* x x.B.*.* */
Do i=1 To rows.A
Do j=1 To cols.B
Do k=1 To cols.A
x.C.i.j=x.C.i.j+x.A.i.k*x.B.k.j
End /*k*/
End /*j*/
End /*i*/
mm=rows.A||'X'||cols.B
Do i=1 To rows.A
Do j=1 To cols.B
mm=mm x.C.i.j
End /*j*/
End /*i*/
Call makeMat 'C',mm
Return
/*--------------------------------------------------------------------*/
showMat:
Parse Arg what,size .
Parse Var size rows 'X' cols
z='+'
b6=left('',6)
Say ''
Say b6 copies('-',7) 'matrix' what copies('-',7)
w=0
Do r=1 To rows
Do c=1 To cols
w=max(w,length(x.what.r.c))
End
End
Say b6 b6 '+'copies('-',cols*(w+1)+1)'+' /* top border */
Do r=1 To rows
line='|' right(x.what.r.1,w) /* element of first colsumn */ /* start with long vertical bar */
Do c=2 To cols /* loop for other columns */
line=line right(x.what.r.c,w) /* append the elements */
End /* c */
Say b6 b6 line '|' /* append a long vertical bar. */
End /* r */
Say b6 b6 '+'copies('-',cols*(w+1)+1)'+' /* bottom border */
Return
exit:
Say arg(1)
Exit
 
Syntax:
Say 'Syntax raised in line' sigl
Say sourceline(sigl)
Say 'rc='rc '('errortext(rc)')'
Say '***** There was a problem!'
Exit</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
<pre>
------- matrix A -------
+-----+
| 1 2 |
| 3 4 |
| 5 6 |
| 7 8 |
+-----+
 
------- matrix B -------
+-------+
| 1 2 3 |
| 4 5 6 |
+-------+
 
------- matrix C -------
+----------+
| 9 12 15 |
| 19 26 33 |
| 29 40 51 |
| 39 54 69 |
+----------+
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
load "stdlib.ring"
n = 3
C = newlist(n,n)
A = [[1,2,3], [4,5,6], [7,8,9]]
B = [[1,0,0], [0,1,0], [0,0,1]]
for i = 1 to n
for j = 1 to n
for k = 1 to n
C[i][k] += A[i][j] * B[j][k]
next
next
next
for i = 1 to n
for j = 1 to n
see C[i][j] + " "
next
see nl
next
</syntaxhighlight>
Output:
<pre>
123
456
789
</pre>
 
=={{header|RPL}}==
The <code>*</code> operator can multiply numbers of any kind together, matrices - and even lists in latest RPL versions.
[[1 2 3][4 5 6]] [[3 1][4 1][5 9]] *
{{out}}
<pre>
1: [[ 26 30 ]
[ 62 63 ]]
</pre>
 
=={{header|Ruby}}==
Using 'matrix' from the standard library:
<syntaxhighlight lang="ruby">require 'matrix'
 
Matrix[[1, 2],
[3, 4]] * Matrix[[-3, -8, 3],
[-2, 1, 4]]</syntaxhighlight>
{{out}}
Matrix[[-7, -6, 11], [-17, -20, 25]]
 
Version for lists: {{trans|Haskell}}
<syntaxhighlight lang="ruby">def matrix_mult(a, b)
a.map do |ar|
b.transpose.map { |bc| ar.zip(bc).map{ |x| x.inject(&:*) }.sum }
end
end</syntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
struct Matrix {
dat: [[f32; 3]; 3]
}
 
impl Matrix {
pub fn mult_m(a: Matrix, b: Matrix) -> Matrix
{
let mut out = Matrix {
dat: [[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]
]
};
 
for i in 0..3{
for j in 0..3 {
for k in 0..3 {
out.dat[i][j] += a.dat[i][k] * b.dat[k][j];
}
}
}
 
out
}
 
pub fn print(self)
{
for i in 0..3 {
for j in 0..3 {
print!("{} ", self.dat[i][j]);
}
print!("\n");
}
}
}
 
fn main()
{
let a = Matrix {
dat: [[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]
]
};
 
let b = Matrix {
dat: [[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]
};
 
let c = Matrix::mult_m(a, b);
 
c.print();
}
 
</syntaxhighlight>
 
=={{header|S-lang}}==
<syntaxhighlight lang="c">% Matrix multiplication is a built-in with the S-Lang octothorpe operator.
variable A = [1,2,3,4,5,6];
reshape(A, [2,3]); % reshape 1d array to 2 rows, 3 columns
printf("A is %S\n", A); print(A);
 
variable B = [1:6]; % index range, 1 to 6 same as above in A
reshape(B, [3,2]); % reshape to 3 rows, 2 columns
printf("\nB is %S\n", B); print(B);
 
printf("\nA # B is %S\n", A#B);
print(A#B);
 
% Multiply binary operator is different, dimensions need to be equal
reshape(B, [2,3]);
printf("\nA * B is %S (with reshaped B to match A)\n", A*B);
print(A*B);</syntaxhighlight>
 
{{out}}
<pre>prompt$ slsh matrix_mul.sl
A is Integer_Type[2,3]
1 2 3
4 5 6
 
B is Integer_Type[3,2]
1 2
3 4
5 6
 
A # B is Float_Type[2,2]
22.0 28.0
49.0 64.0
 
A * B is Integer_Type[2,3] (with B reshaped to match A)
1 4 9
16 25 36</pre>
 
=={{header|Scala}}==
{{works with|Scala|2.8}}
Assuming an array of arrays representation:
 
<syntaxhighlight lang="scala">def mult[A](a: Array[Array[A]], b: Array[Array[A]])(implicit n: Numeric[A]) = {
import n._
for (row <- a)
yield for(col <- b.transpose)
yield row zip col map Function.tupled(_*_) reduceLeft (_+_)
}</syntaxhighlight>
 
For any subclass of <code>Seq</code> (which does not include Java-specific arrays):
 
<syntaxhighlight lang="scala">def mult[A, CC[X] <: Seq[X], DD[Y] <: Seq[Y]](a: CC[DD[A]], b: CC[DD[A]])
(implicit n: Numeric[A]): CC[DD[A]] = {
import n._
for (row <- a)
yield for(col <- b.transpose)
yield row zip col map Function.tupled(_*_) reduceLeft (_+_)
}</syntaxhighlight>
 
Examples:
 
<pre>
scala> Array(Array(1, 2), Array(3, 4))
res0: Array[Array[Int]] = Array(Array(1, 2), Array(3, 4))
 
scala> Array(Array(-3, -8, 3), Array(-2, 1, 4))
res1: Array[Array[Int]] = Array(Array(-3, -8, 3), Array(-2, 1, 4))
 
scala> mult(res0, res1)
res2: Array[scala.collection.mutable.GenericArray[Int]] = Array(GenericArray(-7, -6, 11), GenericArray(-17, -20, 25))
 
scala> res0.map(_.toList).toList
res5: List[List[Int]] = List(List(1, 2), List(3, 4))
 
scala> res1.map(_.toList).toList
res6: List[List[Int]] = List(List(-3, -8, 3), List(-2, 1, 4))
 
scala> mult(res5, res6)
res7: Seq[Seq[Int]] = List(List(-7, -6, 11), List(-17, -20, 25))
</pre>
 
A fully generic multiplication that returns the same collection as received is possible,
but much more verbose.
 
=={{header|Scheme}}==
{{trans|Common Lisp}}
This version works on lists of lists:
<syntaxhighlight lang="scheme">(define (matrix-multiply matrix1 matrix2)
(map
(lambda (row)
Line 727 ⟶ 5,958:
(apply + (map * row column)))
matrix2))
matrix1))</schemesyntaxhighlight>
 
> (matrix-multiply '((1 2) (3 4)) '((-3 -8 3) (-2 1 4)))
Line 733 ⟶ 5,964:
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">const type: matrix is array array float;
 
const func matrix: (in matrix: left) * (in matrix: right) is func
result
var matrix: result is matrix.value;
local
var integer: i is 0;
var integer: j is 0;
var integer: k is 0;
var float: accumulator is 0.0;
begin
begin
if length(left[1]) <> length(right) then
if length(left[1]) <> length(right) then
raise RANGE_ERROR;
else raise RANGE_ERROR;
else
result := length(left) times length(right[1]) times 0.0;
result for:= ilength(left) range 1 totimes length(leftright[1]) dotimes 0.0;
for ji range 1 to length(rightleft) do
for kj range 1 to length(leftright) do
accumulator result[i][j] +:= left[i][k] * right[k][j]0.0;
for endk for;range 1 to length(left) do
accumulator +:= left[i][k] * right[k][j];
end for;
end for;
result[i][j] := accumulator;
end if;
end funcfor;
end for;
end if;
end func;</syntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/math.htm#mmult]
 
=={{header|SequenceL}}==
 
:The product of the ''m''×''p'' matrix ''A'' with the ''p''×''n'' matrix ''B'' is the ''m''×''n'' matrix whose (''i'',''j'')'th entry is
::<math>\sum_{k=1}^p A(i,k)B(k,j)</math>
 
The SequenceL definition mirrors that definition more or less exactly:
 
<syntaxhighlight lang="sequencel">matmul(A(2), B(2)) [i,j] :=
let k := 1...size(B);
in sum( A[i,k] * B[k,j] );
//Example Use
a := [[1, 2],
[3, 4]];
b := [[-3, -8, 3],
[-2, 1, 4]];
test := matmul(a, b);</syntaxhighlight>
 
It can be written a little more simply using the all keyword:
 
<syntaxhighlight lang="sequencel">matmul(A(2), B(2)) [i,j] := sum( A[i,all] * B[all,j] );</syntaxhighlight>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func matrix_multi(a, b) {
var m = [[]]
for r in ^a {
for c in ^b[0] {
for i in ^b {
m[r][c] := 0 += (a[r][i] * b[i][c])
}
}
}
return m
}
 
var a = [
[1, 2],
[3, 4],
[5, 6],
[7, 8]
]
 
var b = [
[1, 2, 3],
[4, 5, 6]
]
 
for line in matrix_multi(a, b) {
say line.map{|i|'%3d' % i }.join(', ')
}</syntaxhighlight>
{{out}}
<pre> 9, 12, 15
19, 26, 33
29, 40, 51
39, 54, 69</pre>
 
=={{header|SPAD}}==
{{works with|FriCAS}}
{{works with|OpenAxiom}}
{{works with|Axiom}}
<syntaxhighlight lang="spad">(1) -> A:=matrix [[1,2],[3,4],[5,6],[7,8]]
 
+1 2+
| |
|3 4|
(1) | |
|5 6|
| |
+7 8+
Type: Matrix(Integer)
(2) -> B:=matrix [[1,2,3],[4,5,6]]
 
+1 2 3+
(2) | |
+4 5 6+
Type: Matrix(Integer)
(3) -> A*B
 
+9 12 15+
| |
|19 26 33|
(3) | |
|29 40 51|
| |
+39 54 69+
Type: Matrix(Integer)</syntaxhighlight>
 
Domain:[http://fricas.github.io/api/Matrix.html?highlight=matrix Matrix(R)]
 
=={{header|SQL}}==
<syntaxhighlight lang="sql">CREATE TABLE a (x integer, y integer, e real);
CREATE TABLE b (x integer, y integer, e real);
 
-- test data
-- A is a 2x2 matrix
INSERT INTO a VALUES(0,0,1); INSERT INTO a VALUES(1,0,2);
INSERT INTO a VALUES(0,1,3); INSERT INTO a VALUES(1,1,4);
 
-- B is a 2x3 matrix
INSERT INTO b VALUES(0,0,-3); INSERT INTO b VALUES(1,0,-8); INSERT INTO b VALUES(2,0,3);
INSERT INTO b VALUES(0,1,-2); INSERT INTO b VALUES(1,1, 1); INSERT INTO b VALUES(2,1,4);
 
-- C is 2x2 * 2x3 so will be a 2x3 matrix
SELECT rhs.x, lhs.y, (SELECT sum(a.e*b.e) FROM a, b
WHERE a.y = lhs.y
AND b.x = rhs.x
AND a.x = b.y)
INTO TABLE c
FROM a AS lhs, b AS rhs
WHERE lhs.x = 0 AND rhs.y = 0;</syntaxhighlight>
 
=={{header|Standard ML}}==
<syntaxhighlight lang="sml">structure IMatrix = struct
fun dot(x,y) = Vector.foldli (fn (i,xi,agg) => agg+xi*Vector.sub(y,i)) 0 x
fun x*y =
let
open Array2
in
tabulate ColMajor (nRows x, nCols y, fn (i,j) => dot(row(x,i),column(y,j)))
end
end;
(* for display *)
fun toList a =
let
open Array2
in
List.tabulate(nRows a, fn i => List.tabulate(nCols a, fn j => sub(a,i,j)))
end;
(* example *)
let
open IMatrix
val m1 = Array2.fromList [[1,2],[3,4]]
val m2 = Array2.fromList [[~3,~8,3],[~2,1,4]]
in
toList (m1*m2)
end;</syntaxhighlight>
'''Output:'''
<syntaxhighlight lang="sml">val it = [[~7,~6,11],[~17,~20,25]] : int list list</syntaxhighlight>
 
=={{header|Stata}}==
=== Stata matrices ===
<syntaxhighlight lang="stata">. mat a=1,2,3\4,5,6
. mat b=1,1,0,0\1,0,0,1\0,0,1,1
. mat c=a*b
. mat list c
 
c[2,4]
c1 c2 c3 c4
r1 3 1 3 5
r2 9 4 6 11</syntaxhighlight>
=== Mata ===
<syntaxhighlight lang="stata">: a=1,2,3\4,5,6
: b=1,1,0,0\1,0,0,1\0,0,1,1
: a*b
1 2 3 4
+---------------------+
1 | 3 1 3 5 |
2 | 9 4 6 11 |
+---------------------+</syntaxhighlight>
 
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">@inlinable
public func matrixMult<T: Numeric>(_ m1: [[T]], _ m2: [[T]]) -> [[T]] {
let n = m1[0].count
let m = m1.count
let p = m2[0].count
 
guard m != 0 else {
return []
}
 
precondition(n == m2.count)
 
var ret = Array(repeating: Array(repeating: T.zero, count: p), count: m)
 
for i in 0..<m {
for j in 0..<p {
for k in 0..<n {
ret[i][j] += m1[i][k] * m2[k][j]
}
}
}
 
return ret
}
 
@inlinable
public func printMatrix<T>(_ matrix: [[T]]) {
guard !matrix.isEmpty else {
print()
 
return
}
 
let rows = matrix.count
let cols = matrix[0].count
 
for i in 0..<rows {
for j in 0..<cols {
print(matrix[i][j], terminator: " ")
}
 
print()
}
}
 
let m1 = [
[6.5, 2, 3],
[4.5, 1, 5]
]
 
let m2 = [
[10.0, 16, 23, 50],
[12, -8, 16, -4],
[70, 60, -1, -2]
]
 
let m3 = matrixMult(m1, m2)
 
printMatrix(m3)</syntaxhighlight>
 
{{out}}
 
<pre>299.0 268.0 178.5 311.0
407.0 364.0 114.5 211.0 </pre>
 
=={{header|Tailspin}}==
<syntaxhighlight lang="tailspin">
operator (A matmul B)
$A -> \[i](
$B(1) -> \[j](@: 0;
1..$B::length -> @: $@ + $A($i;$) * $B($;$j);
$@ !\) !
\) !
end matmul
 
templates printMatrix&{w:}
templates formatN
@: [];
$ -> #
'$@ -> $::length~..$w -> ' ';$@(last..1:-1)...;' !
when <1..> do ..|@: $ mod 10; $ ~/ 10 -> #
when <=0?($@ <[](0)>)> do ..|@: 0;
end formatN
$... -> '|$(1) -> formatN;$(2..last)... -> ', $ -> formatN;';|
' !
end printMatrix
 
def a: [[1, 2, 3], [4, 5, 6]];
'a:
' -> !OUT::write
$a -> printMatrix&{w:2} -> !OUT::write
 
def b: [[0, 1], [2, 3], [4, 5]];
'
b:
' -> !OUT::write
$b -> printMatrix&{w:2} -> !OUT::write
'
axb:
' -> !OUT::write
($a matmul $b) -> printMatrix&{w:2} -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
a:
| 1, 2, 3|
| 4, 5, 6|
 
b:
| 0, 1|
| 2, 3|
| 4, 5|
 
axb:
|16, 22|
|34, 49|
</pre>
 
=={{header|Tcl}}==
{{works with|Tcl|8.5}}
<syntaxhighlight lang="tcl">package require Tcl 8.5
namespace path ::tcl::mathop
proc matrix_multiply {a b} {
lassign [size $a] a_rows a_cols
lassign [size $b] b_rows b_cols
if {$a_cols != $b_rows} {
error "incompatible sizes: a($a_rows, $a_cols), b($b_rows, $b_cols)"
}
set temp [lrepeat $a_rows [lrepeat $b_cols 0]]
for {set i 0} {$i < $a_rows} {incr i} {
for {set j 0} {$j < $b_cols} {incr j} {
set sum 0
for {set k 0} {$k < $a_cols} {incr k} {
set sum [+ $sum [* [lindex $a $i $k] [lindex $b $k $j]]]
}
lset temp $i $j $sum
}
}
return $temp
}</syntaxhighlight>
Using the <code>print_matrix</code> procedure defined in [[Matrix Transpose#Tcl]]
<pre>% print_matrix [matrix_multiply {{1 2} {3 4}} {{-3 -8 3} {-2 1 4}}]
-7 -6 11
-17 -20 25 </pre>
 
=={{header|TI-83 BASIC}}==
Store your matrices in <tt>[A]</tt> and <tt>[B]</tt>.
<syntaxhighlight lang="ti83b">Disp [A]*[B]</syntaxhighlight>
Disp [A]*[B]
An error will show if the matrices have invalid dimensions for multiplication.
<br><br>'''Other way:''' enter directly your matrices:
<syntaxhighlight lang="ti83b">[[1,2][3,4][5,6][7,8]]*[[1,2,3][4,5,6]]</syntaxhighlight>
{{out}}
[[9 12 15]
[19 26 33]
[29 40 51]
[39 54 69]]]
 
=={{header|TI-89 BASIC}}==
 
{{trans|Mathematica}}
 
<syntaxhighlight lang="ti89b">[1,2; 3,4; 5,6; 7,8] → m1
[1,2,3; 4,5,6] → m2
m1 * m2</syntaxhighlight>
 
Or without the variables:
 
<syntaxhighlight lang="ti89b">[1,2; 3,4; 5,6; 7,8] * [1,2,3; 4,5,6]</syntaxhighlight>
 
The result (without prettyprinting) is:
 
<syntaxhighlight lang="ti89b">[[9,12,15][19,26,33][29,40,51][39,54,69]]</syntaxhighlight>
 
=={{header|Transd}}==
<syntaxhighlight lang="scheme">#lang transd
 
 
MainModule: {
_start: (λ (with n 5
A (for i in Range(n) project (for k in Range(n) project k))
B (for i in Range(n) project (for k in Range(n) project (- n k)))
C (for i in Range(n) project (for k in Range(n) project 0))
 
(for i in Range( n ) do
(for j in Range( n ) do
(for k in Range( n ) do
(+= (get (get C i) j) (* (get (get A i) k) (get (get B k) j)))
)))
(lout C))
)
}</syntaxhighlight>{{out}}
<pre>
[[50, 40, 30, 20, 10],
[50, 40, 30, 20, 10],
[50, 40, 30, 20, 10],
[50, 40, 30, 20, 10],
[50, 40, 30, 20, 10]]
</pre>
 
=={{header|UNIX Shell}}==
<syntaxhighlight lang="bash">
#!/bin/bash
 
DELAY=0 # increase this if printing of matrices should be slower
 
echo "This script takes two matrices, henceforth called A and B,
and returns their product, AB.
 
For the time being, matrices can have integer components only.
 
"
 
read -p "Number of rows of matrix A: " arows
read -p "Number of columns of matrix A: " acols
brows="$acols"
echo
echo "Number of rows of matrix B: "$brows
read -p "Number of columns of matrix B: " bcols
 
crows="$arows"
ccols="$bcols"
echo
 
echo "Number of rows of matrix AB: " $crows
echo "Number of columns of matrix AB: " $ccols
echo
echo
 
matrixa=( )
matrixb=( )
 
# input matrix A
 
maxlengtha=0
for ((row=1; row<=arows; row++)); do
for ((col=1; col<=acols; col++)); do
checkentry="false"
while [ "$checkentry" != "true" ]; do
read -p "Enter component A[$row, $col]: " number
index=$(((row-1)*acols+col))
matrixa[$index]="$number"
[ "${matrixa[$index]}" -eq "$number" ] && checkentry="true"
echo
done
entry="${matrixa[$index]}"
[ "${#entry}" -gt "$maxlengtha" ] && maxlengtha="${#entry}"
done
echo
done
 
# print matrix A to guard against errors
 
if [ "$maxlengtha" -le "5" ]; then
width=8
else
width=$((maxlengtha + 3))
fi
 
echo "This is matrix A:
 
"
 
for ((row=1; row<=arows; row++)); do
for ((col=1; col<=acols; col++)); do
 
index=$(((row-1)*acols+col))
printf "%${width}d" "${matrixa[$index]}"
sleep "$DELAY"
 
done
echo; echo # printf %s "\n\n" does not work...
done
 
echo
echo
 
# input matrix B
 
maxlengthb=0
for ((row=1; row<=brows; row++)); do
for ((col=1; col<=bcols; col++)); do
checkentry="false"
while [ "$checkentry" != "true" ]; do
read -p "Enter component B[$row, $col]: " number
index=$(((row-1)*bcols+col))
matrixb[$index]="$number"
[ "${matrixb[$index]}" -eq "$number" ] && checkentry="true"
echo
done
entry="${matrixb[$index]}"
[ "${#entry}" -gt "$maxlengthb" ] && maxlengthb="${#entry}"
done
echo
done
 
# print matrix B to guard against errors
 
if [ "$maxlengthb" -le "5" ]; then
width=8
else
width=$((maxlengthb + 3))
fi
 
echo "This is matrix B:
 
"
 
for ((row=1; row<=brows; row++)); do
for ((col=1; col<=bcols; col++)); do
 
index=$(((row-1)*bcols+col))
printf "%${width}d" "${matrixb[$index]}"
sleep "$DELAY"
 
done
echo; echo # printf %s "\n\n" does not work...
done
 
read -p "Hit enter to continue"
 
# calculate matrix C := AB
 
maxlengthc=0
time for ((row=1; row<=crows; row++)); do
for ((col=1; col<=ccols; col++)); do
# calculate component C[$row, $col]
 
runningtotal=0
for ((j=1; j<=acols; j++)); do
rowa="$row"
cola="$j"
indexa=$(((rowa-1)*acols+cola))
rowb="$j"
colb="$col"
indexb=$(((rowb-1)*bcols+colb))
entry_from_A=${matrixa[$indexa]}
entry_from_B=${matrixb[$indexb]}
 
subtotal=$((entry_from_A * entry_from_B))
((runningtotal+=subtotal))
done
number="$runningtotal"
 
# store component in the result array
index=$(((row-1)*ccols+col))
matrixc[$index]="$number"
 
entry="${matrixc[$index]}"
[ "${#entry}" -gt "$maxlengthc" ] && maxlengthc="${#entry}"
done
done
 
echo
read -p "Hit enter to continue"
echo
 
# print the matrix C
 
if [ "$maxlengthc" -le "5" ]; then
width=8
else
width=$((maxlengthc + 3))
fi
 
echo "The product matrix is:
 
"
 
for ((row=1; row<=crows; row++)); do
for ((col=1; col<=ccols; col++)); do
 
index=$(((row-1)*ccols+col))
printf "%${width}d" "${matrixc[$index]}"
sleep "$DELAY"
 
done
echo; echo # printf %s "\n\n" does not work...
done
 
echo
echo
</syntaxhighlight>
 
=={{header|Ursala}}==
There is a library function for matrix multiplication of IEEE double precision floating point
numbers. This example shows how to define and use a matrix multiplication function over
any chosen field given only the relevant product and sum functions, in this case for
the built in rational number type.
 
<syntaxhighlight lang="ursala">#import rat
 
a =
 
<
<1/1, 1/1, 1/1, 1/1>,
<2/1, 4/1, 8/1, 16/1>,
<3/1, 9/1, 27/1, 81/1>,
<4/1, 16/1, 64/1, 256/1>>
 
b =
 
<
< 4/1, -3/1, 4/3, -1/4>,
<-13/3, 19/4, -7/3, 11/24>,
< 3/2, -2/1, 7/6, -1/4>,
< -1/6, 1/4, -1/6, 1/24>>
 
mmult = *rK7lD *rlD sum:-0.+ product*p
 
#cast %qLL
 
test = mmult(a,b)</syntaxhighlight>
{{out}}
<pre><
<1/1,0/1,0/1,0/1>,
<0/1,1/1,0/1,0/1>,
<0/1,0/1,1/1,0/1>,
<0/1,0/1,0/1,1/1>></pre>
 
=={{header|VBA}}==
Using Excel. The resulting matrix should be smaller than 5461 elements.
<syntaxhighlight lang="vb">Function matrix_multiplication(a As Variant, b As Variant) As Variant
matrix_multiplication = WorksheetFunction.MMult(a, b)
End Function</syntaxhighlight>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
Dim matrix1(2,2)
matrix1(0,0) = 3 : matrix1(0,1) = 7 : matrix1(0,2) = 4
matrix1(1,0) = 5 : matrix1(1,1) = -2 : matrix1(1,2) = 9
matrix1(2,0) = 8 : matrix1(2,1) = -6 : matrix1(2,2) = -5
Dim matrix2(2,2)
matrix2(0,0) = 9 : matrix2(0,1) = 2 : matrix2(0,2) = 1
matrix2(1,0) = -7 : matrix2(1,1) = 3 : matrix2(1,2) = -10
matrix2(2,0) = 4 : matrix2(2,1) = 5 : matrix2(2,2) = -6
 
Call multiply_matrix(matrix1,matrix2)
 
Sub multiply_matrix(arr1,arr2)
For i = 0 To UBound(arr1)
For j = 0 To 2
WScript.StdOut.Write (arr1(i,j) * arr2(i,j)) & vbTab
Next
WScript.StdOut.WriteLine
Next
End Sub
</syntaxhighlight>
 
{{Out}}
<pre>
27 14 4
-35 -6 -90
32 -30 30
</pre>
 
=={{header|Visual FoxPro}}==
<syntaxhighlight lang="vfp">
LOCAL ARRAY a[4,2], b[2,3], c[4,3]
CLOSE DATABASES ALL
*!* The arrays could be created directly but I prefer to do this:
CREATE CURSOR mat1 (c1 I, c2 I)
CREATE CURSOR mat2 (c1 I, c2 I, c3 I)
*!* Since matrix multiplication of integer arrays
*!* involves only multiplication and addition,
*!* the result will contain integers
CREATE CURSOR result (c1 I, c2 I, c3 I)
INSERT INTO mat1 VALUES (1, 2)
INSERT INTO mat1 VALUES (3, 4)
INSERT INTO mat1 VALUES (5, 6)
INSERT INTO mat1 VALUES (7, 8)
SELECT * FROM mat1 INTO ARRAY a
 
INSERT INTO mat2 VALUES (1, 2, 3)
INSERT INTO mat2 VALUES (4, 5, 6)
SELECT * FROM mat2 INTO ARRAY b
STORE 0 TO c
MatMult(@a,@b,@c)
SELECT result
APPEND FROM ARRAY c
BROWSE
 
 
PROCEDURE MatMult(aa, bb, cc)
LOCAL n As Integer, m As Integer, p As Integer, i As Integer, j As Integer, k As Integer
IF ALEN(aa,2) = ALEN(bb,1)
n = ALEN(aa,2)
m = ALEN(aa,1)
p = ALEN(bb,2)
FOR i = 1 TO m
FOR j = 1 TO p
FOR k = 1 TO n
cc[i,j] = cc[i,j] + aa[i,k]*bb[k,j]
ENDFOR
ENDFOR
ENDFOR
ELSE
? "Invalid dimensions"
ENDIF
ENDPROC
</syntaxhighlight>
 
=={{header|Wren}}==
{{libheader|Wren-matrix}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./matrix" for Matrix
import "./fmt" for Fmt
 
var a = Matrix.new([
[1, 2],
[3, 4],
[5, 6],
[7, 8]
])
 
var b = Matrix.new([
[1, 2, 3],
[4, 5, 6]
])
 
System.print("Matrix A:\n")
Fmt.mprint(a, 2, 0)
System.print("\nMatrix B:\n")
Fmt.mprint(b, 2, 0)
System.print("\nMatrix A x B:\n")
Fmt.mprint(a * b, 3, 0)</syntaxhighlight>
 
{{out}}
<pre>
Matrix A:
 
| 1 2|
| 3 4|
| 5 6|
| 7 8|
 
Matrix B:
 
| 1 2 3|
| 4 5 6|
 
Matrix A x B:
 
| 9 12 15|
| 19 26 33|
| 29 40 51|
| 39 54 69|
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">proc Mat4x1Mul(M, V); \Multiply matrix M times column vector V
real M, \4x4 matrix [M] * [V] -> [V]
V; \column vector
real W(4); \working copy of column vector
int R; \row
[for R:= 0 to 4-1 do
W(R):= M(R,0)*V(0) + M(R,1)*V(1) + M(R,2)*V(2) + M(R,3)*V(3);
for R:= 0 to 4-1 do V(R):= W(R);
];
 
proc Mat4x4Mul(M, N); \Multiply matrix M times matrix N
real M, N; \4x4 matrices [M] * [N] -> [N]
real W(4,4); \working copy of matrix N
int C; \column
[for C:= 0 to 4-1 do
[W(0,C):= M(0,0)*N(0,C) + M(0,1)*N(1,C) + M(0,2)*N(2,C) + M(0,3)*N(3,C);
W(1,C):= M(1,0)*N(0,C) + M(1,1)*N(1,C) + M(1,2)*N(2,C) + M(1,3)*N(3,C);
W(2,C):= M(2,0)*N(0,C) + M(2,1)*N(1,C) + M(2,2)*N(2,C) + M(2,3)*N(3,C);
W(3,C):= M(3,0)*N(0,C) + M(3,1)*N(1,C) + M(3,2)*N(2,C) + M(3,3)*N(3,C);
];
for C:= 0 to 4-1 do
[N(0,C):= W(0,C);
N(1,C):= W(1,C);
N(2,C):= W(2,C);
N(3,C):= W(3,C);
];
];</syntaxhighlight>
 
=={{header|XSLT 1.0}}==
With input document ...
 
<syntaxhighlight lang="xml"><?xml-stylesheet href="matmul.templ.xsl" type="text/xsl"?>
<mult>
<A>
<r><c>1</c><c>2</c></r>
<r><c>3</c><c>4</c></r>
<r><c>5</c><c>6</c></r>
<r><c>7</c><c>8</c></r>
</A>
<B>
<r><c>1</c><c>2</c><c>3</c></r>
<r><c>4</c><c>5</c><c>6</c></r>
</B>
</mult></syntaxhighlight>
 
... and this referenced stylesheet ...
 
<syntaxhighlight lang="xml"><xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="html"/>
<xsl:template match="/mult">
<table>
<tr><td>╭</td><td colspan="{count(*[2]/*[1]/*)}"/><td>╮</td></tr>
<xsl:call-template name="prodMM">
<xsl:with-param name="A" select="*[1]/*"/>
<xsl:with-param name="B" select="*[2]/*"/>
</xsl:call-template>
<tr><td>╰</td><td colspan="{count(*[2]/*[1]/*)}"/><td>╯</td></tr>
</table>
</xsl:template>
<xsl:template name="prodMM">
<xsl:param name="A"/>
<xsl:param name="B"/>
 
<xsl:if test="$A/*">
<tr>
<td>│</td>
<xsl:call-template name="prodVM">
<xsl:with-param name="a" select="$A[1]/*"/>
<xsl:with-param name="B" select="$B"/>
</xsl:call-template>
<td>│</td>
</tr>
 
<xsl:call-template name="prodMM">
<xsl:with-param name="A" select="$A[position()>1]"/>
<xsl:with-param name="B" select="$B"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
 
<xsl:template name="prodVM">
<xsl:param name="a"/>
<xsl:param name="B"/>
<xsl:param name="col" select="1"/>
 
<xsl:if test="$B/*[$col]">
<td align="right">
<xsl:call-template name="prod">
<xsl:with-param name="a" select="$a"/>
<xsl:with-param name="b" select="$B/*[$col]"/>
</xsl:call-template>
</td>
 
<xsl:call-template name="prodVM">
<xsl:with-param name="a" select="$a"/>
<xsl:with-param name="B" select="$B"/>
<xsl:with-param name="col" select="$col+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
 
<xsl:template name="prod">
<xsl:param name="a"/>
<xsl:param name="b"/>
 
<xsl:if test="not($a)">0</xsl:if>
 
<xsl:if test="$a">
<xsl:variable name="res">
<xsl:call-template name="prod">
<xsl:with-param name="a" select="$a[position()>1]"/>
<xsl:with-param name="b" select="$b[position()>1]"/>
</xsl:call-template>
</xsl:variable>
 
<xsl:value-of select="$a[1] * $b[1] + $res"/>
</xsl:if>
</xsl:template>
 
</xsl:stylesheet></syntaxhighlight>
{{out}} (in a browser):
<pre>
╭ ╮
│ 9 12 15 │
│ 19 26 33 │
│ 29 40 51 │
│ 39 54 69 │
╰ ╯
</pre>
 
You may try in your browser: [[http://www.stamm-wilbrandt.de/en/blog/matmul.templ.xml]]
 
A slightly smaller version of above stylesheet making use of (Non-"XSLT 1.0") EXSLT functions can be founde here: [[https://www.ibm.com/developerworks/mydeveloperworks/blogs/HermannSW/entry/matrix_multiplication30]]
 
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">dim a(4, 2)
a(0, 0) = 1 : a(0, 1) = 2
a(1, 0) = 3 : a(1, 1) = 4
a(2, 0) = 5 : a(2, 1) = 6
a(3, 0) = 7 : a(3, 1) = 8
dim b(2, 3)
b(0, 0) = 1 : b(0, 1) = 2 : b(0, 2) = 3
b(1, 0) = 4 : b(1, 1) = 5 : b(1, 2) = 6
dim prod(arraysize(a(),1), arraysize(b(),2))
 
if (arraysize(a(),2) = arraysize(b(),1)) then
for i = 0 to arraysize(a(),1)
for j = 0 to arraysize(b(),2)
for k = 0 to arraysize(a(),2)
prod(i, j) = prod(i, j) + (a(i, k) * b(k, j))
next k
next j
next i
 
for i = 0 to arraysize(prod(),1)-1
for j = 0 to arraysize(prod(),2)-1
print prod(i, j),
next j
print
next i
else
print "invalid dimensions"
end if
end</syntaxhighlight>
 
 
=={{header|zkl}}==
Using the GNU Scientific Library:
<syntaxhighlight lang="zkl">var [const] GSL=Import("zklGSL"); // libGSL (GNU Scientific Library)
A:=GSL.Matrix(4,2).set(1,2, 3,4, 5,6, 7,8);
B:=GSL.Matrix(2,3).set(1,2,3, 4,5,6);
(A*B).format().println(); // creates a new matrix</syntaxhighlight>
{{out}}
<pre>
9.00, 12.00, 15.00
19.00, 26.00, 33.00
29.00, 40.00, 51.00
39.00, 54.00, 69.00
</pre>
Or, using lists:
{{trans|BASIC}}
<syntaxhighlight lang="zkl">fcn matMult(a,b){
n,m,p:=a[0].len(),a.len(),b[0].len();
ans:=(0).pump(m,List().write, (0).pump(p,List,0).copy); // matrix of zeros
foreach i,j,k in (m,p,n){ ans[i][j]+=a[i][k]*b[k][j]; }
ans
}</syntaxhighlight>
<syntaxhighlight lang="zkl">a:=L( L(1,2,), L(3,4,), L(5,6,), L(7,8) );
b:=L( L(1,2,3,), L(4,5,6) );
printM(matMult(a,b));
 
fcn printM(m){ m.pump(Console.println,rowFmt) }
fcn rowFmt(row){ ("%4d "*row.len()).fmt(row.xplode()) }</syntaxhighlight>
{{out}}
<pre>
9 12 15
19 26 33
29 40 51
39 54 69
</pre>
 
=={{header|zonnon}}==
<syntaxhighlight lang="zonnon">
module MatrixOps;
type
Matrix = array {math} *,* of integer;
 
 
procedure WriteMatrix(x: array {math} *,* of integer);
var
i,j: integer;
begin
for i := 0 to len(x,0) - 1 do
for j := 0 to len(x,1) - 1 do
write(x[i,j]);
end;
writeln;
end
end WriteMatrix;
 
procedure Multiplication;
var
a,b: Matrix;
begin
a := [[1,2],[3,4],[5,6],[7,8]];
b := [[1,2,3],[4,5,6]];
WriteMatrix(a * b);
end Multiplication;
 
begin
Multiplication;
end MatrixOps.
</syntaxhighlight>
 
=={{header|ZPL}}==
<syntaxhighlight lang="zpl">
program matmultSUMMA;
 
prototype GetSingleDim(infile:file):integer;
prototype GetInnerDim(infile1:file; infile2:file):integer;
 
config var
Afilename: string = "";
Bfilename: string = "";
 
Afile: file = open(Afilename,file_read);
Bfile: file = open(Bfilename,file_read);
 
default_size:integer = 4;
m:integer = GetSingleDim(Afile);
n:integer = GetInnerDim(Afile,Bfile);
p:integer = GetSingleDim(Bfile);
 
iters: integer = 1;
 
printinput: boolean = false;
verbose: boolean = true;
dotiming: boolean = false;
 
region
RA = [1..m,1..n];
RB = [1..n,1..p];
RC = [1..m,1..p];
FCol = [1..m,*];
FRow = [*,1..p];
 
var
A : [RA] double;
B : [RB] double;
C : [RC] double;
Aflood : [FCol] double;
Bflood : [FRow] double;
 
procedure ReadA();
var step:double;
[RA] begin
if (Afile != znull) then
read(Afile,A);
else
step := 1.0/(m*n);
A := ((Index1-1)*n + Index2)*step + 1.0;
end;
end;
 
 
procedure ReadB();
var step:double;
[RB] begin
if (Bfile != znull) then
read(Bfile,B);
else
step := 1.0/(n*p);
B := ((Index1-1)*p + Index2)*step + 1.0;
end;
end;
 
 
procedure matmultSUMMA();
var
i: integer;
it: integer;
runtime: double;
[RC] begin
ReadA();
ReadB();
 
if (printinput) then
[RA] writeln("A is:\n",A);
[RB] writeln("B is:\n",B);
end;
 
ResetTimer();
 
for it := 1 to iters do
C := 0.0; -- zero C
for i := 1 to n do
[FCol] Aflood := >>[,i] A; -- flood A col
[FRow] Bflood := >>[i,] B; -- flood B row
 
C += (Aflood * Bflood); -- multiply
end;
end;
 
runtime := CheckTimer();
 
if (verbose) then
writeln("C is:\n",C);
end;
 
if (dotiming) then
writeln("total runtime = %12.6f":runtime);
writeln("actual runtime = %12.6f":runtime/iters);
end;
end;
 
 
procedure GetSingleDim(infile:file):integer;
var dim:integer;
begin
if (infile != znull) then
read(infile,dim);
else
dim := default_size;
end;
return dim;
end;
 
 
procedure GetInnerDim(infile1:file; infile2:file):integer;
var
col:integer;
row:integer;
retval:integer;
begin
retval := -1;
if (infile1 != znull) then
read(infile1,col);
retval := col;
end;
if (infile2 != znull) then
read(infile2,row);
if (retval = -1) then
retval := row;
else
if (row != col) then
halt("ERROR: Inner dimensions don't match");
end;
end;
end;
if (retval = -1) then
retval := default_size;
end;
return retval;
end;
</syntaxhighlight>
2,042

edits