# Matrix multiplication

Matrix multiplication
You are encouraged to solve this task according to the task description, using any language you may know.

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.

## 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: <ada> with Ada.Text_IO; use Ada.Text_IO; with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;

procedure Matrix_Product is

```  procedure Put (X : Real_Matrix) is
type Fixed is delta 0.01 range -100.0..100.0;
begin
for I in X'Range (1) loop
for J in X'Range (2) loop
Put (Fixed'Image (Fixed (X (I, J))));
end loop;
New_Line;
end loop;
end Put;

A : constant Real_Matrix :=
(  ( 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 : constant Real_Matrix :=
(  (  4.0,     -3.0,      4.0/3.0,  -1.0/4.0 ),
(-13.0/3.0, 19.0/4.0, -7.0/3.0,  11.0/24.0),
(  3.0/2.0, -2.0,      7.0/6.0,  -1.0/4.0 ),
( -1.0/6.0,  1.0/4.0, -1.0/6.0,   1.0/24.0)
);
```

begin

```  Put (A * B);
```

end Matrix_Product; </ada> Sample output:

``` 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
```

The following code illustrates how matrix multiplication could be implemented from scratch: <ada>

```package Matrix_Ops is
type Matrix is array (Natural range <>, Natural range <>) of Float;
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;
```

</ada>

## ALGOL 68

An example of user defined Vector and Matrix Multiplication Operators:

```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 #
OP * = (MATRIX a, b)MATRIX: ( # overload matrix times matrix #
[LWB a:UPB a, 2 LWB b:2 UPB b]FIELD result;
IF 2 LWB a/=LWB b OR 2 UPB a/=UPB b THEN raise index error FI;
FOR k FROM LWB result TO UPB result DO result[k,]:=a[k,]*b OD;
result
);
```
```# Some sample matrices to test #
MATRIX a=((1,  1,  1,   1), # matrix A #
(2,  4,  8,  16),
(3,  9, 27,  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\$)
```

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));
```

Alternatively, for multicore CPUs, the following recursive algorithm can be used:

```int default upb := 3;
mode field = long real;
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;

sema idle cpus = level ( 8 - 1 ); ¢ 8 = number of CPU cores minus parent CPU ¢

¢ define an operator to slice array into quarters ¢
op top = (matrix m)int: ( ⌊m + ⌈m ) %2,
bot = (matrix m)int: top m + 1,
left = (matrix m)int: ( 2 ⌊m + 2 ⌈m ) %2,
right = (matrix m)int: left m + 1,
left = (vector v)int: ( ⌊v + ⌈v ) %2,
right = (vector v)int: left v + 1;
prio top = 8, bot = 8, left = 8, right = 8; ¢ Operator priority - same as LWB & UPB ¢

op × = (vector a, b)field: ( ¢ dot product ¢
if (⌊a, ⌈a) ≠ (⌊b, ⌈b) then raise index error fi;
if ⌊a = ⌈a then
a[⌈a] × b[⌈b]
else
field begin, end;
[]proc void schedule=(
void: begin:=a[:left a] × b[:left b],
void: end  :=a[right a:] × b[right b:]
);
if level idle cpus = 0 then ¢ use current CPU ¢
for thread to ⌈schedule do schedule[thread] od
else
par ( ¢ run vector in parallel ¢
schedule[1], ¢ assume parent CPU ¢
( ↓idle cpus; schedule[2]; ↑idle cpus)
)
fi;
begin+end
fi
);

op × = (matrix a, b)matrix: ¢ matrix multiply ¢
if (⌊a, 2 ⌊b) = (⌈a, 2 ⌈b) then
a[⌊a, ] × b[, 2 ⌈b] ¢ dot product ¢
else
[⌈a, 2 ⌈b] field out;
if (2 ⌊a, 2 ⌈a) ≠ (⌊b, ⌈b) then raise index error fi;
[]struct(bool required, proc void thread) schedule = (
( true, ¢ calculate top left corner ¢
void: out[:top a, :left b] := a[:top a, ] × b[, :left b]),
( ⌊a ≠ ⌈a, ¢ calculate bottom left corner ¢
void: out[bot a:, :left b] := a[bot a:, ] × b[, :left b]),
( 2 ⌊b ≠ 2 ⌈b, ¢ calculate top right corner ¢
void: out[:top a, right b:] := a[:top a, ] × b[, right b:]),
( (⌊a, 2 ⌊b) ≠ (⌈a, 2 ⌈b) , ¢ calculate bottom right corner ¢
void: out[bot a:, right b:] := a[bot a:, ] × b[, right b:])
);
if level idle cpus = 0 then ¢ use current CPU ¢
for thread to ⌈schedule do (required →schedule[thread] | thread →schedule[thread] ) od
else
par ( ¢ run vector in parallel ¢
thread →schedule[1], ¢ thread is always required, and assume parent CPU ¢
( required →schedule[4] | ↓idle cpus; thread →schedule[4]; ↑idle cpus),
¢ try to do opposite corners of matrix in parallel if CPUs are limited ¢
( required →schedule[3] | ↓idle cpus; thread →schedule[3]; ↑idle cpus),
( required →schedule[2] | ↓idle cpus; thread →schedule[2]; ↑idle cpus)
)
fi;
out
fi;

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 ⌈m-1)(f(real fmt)",")f(real fmt)")"\$;
format matrix fmt = \$x"("n(⌈m-1)(f(vector fmt)","lxx)f(vector fmt)");"\$;
¢ finally print the result ¢
printf((matrix fmt,m))
);

¢ Some sample matrices to test ¢
matrix a=((1,  1,  1,   1), ¢ matrix A ¢
(2,  4,  8,  16),
(3,  9, 27,  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 c = a × b; ¢ actual multiplication example of A x B ¢

print((" A x B =",new line));
real matrix printf(real fmt, c) ∎

exception index error:
putf(stand error, \$x"Exception: index error."l\$)
```

## APL

Matrix multiply in APL is just +.×. For example:

```      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
```

## BASIC

Works with: QuickBasic version 4.5
Translation of: Java

Assume the matrices to be multiplied are a and b

```IF (LEN(a,2) = LEN(b)) 'if valid dims
n = LEN(a,2)
m = LEN(a)
p = LEN(b,2)

DIM ans(0 TO m - 1, 0 TO p - 1)

FOR i = 0 TO m - 1
FOR j = 0 TO p - 1
FOR k = 0 TO n - 1
ans(i, j) = ans(i, j) + (a(i, k) * b(k, j))
NEXT k, j, i

'print answer
FOR i = 0 TO m - 1
FOR j = 0 TO p - 1
PRINT ans(i, j);
NEXT j
PRINT
NEXT i
ELSE
PRINT "invalid dimensions"
END IF
```

## C

Works with: gcc version 4.1.2 20070925 (Red Hat 4.1.2-27) Options: gcc -std=gnu99

<c>

1. include <stdio.h>
2. define dim 4 /* fixed length square matrices */

const int SLICE=0; /* coder hints */ typedef double field_t; /* field_t type is long float */ typedef field_t vec_t[dim]; typedef field_t *ref_vec_t; /* address of first element */ typedef vec_t matrix_t[dim]; typedef field_t *ref_matrix_t; /* address of first element */ typedef char* format;

/* define the vector/matrix_t operators */

field_t v_times_v (vec_t a, vec_t b, int step_b){

```   /* basically the dot product if step_b==1*/
field_t result=0;
for( int i=0; i<sizeof a; i++ )
result+= a[i]*b[i*step_b];
return result;
}
```

ref_vec_t v_eq_v_times_m(vec_t result, vec_t a, matrix_t b){

```   for( int j=0; j<sizeof b; j++ )
result[j]=v_times_v(a,&b[SLICE][j],sizeof b[SLICE] / sizeof (field_t));
return &result[SLICE];
}
```

ref_matrix_t m_eq_m_times_m (matrix_t result, matrix_t a, matrix_t b){

```   for( int k=0; k<sizeof result; k++ )
v_eq_v_times_m(&result[k][SLICE],&a[k][SLICE],b);
return &result[SLICE][SLICE];
}
```

/* Some sample matrices to test */ matrix_t a={{1, 1, 1, 1}, /* matrix_t A */

```           {2,  4,  8,  16},
{3,  9, 27,  81},
{4, 16, 64, 256}};
```

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},
{  3.0/2, -2.0  ,  7.0/6,  -1.0/4 },
{ -1.0/6,  1.0/4, -1.0/6,   1.0/24}};
```

int main(){

``` matrix_t prod;
m_eq_m_times_m(prod,a,b); /* actual multiplication example of A x B */
```
``` #define field_fmt "%6.2f" /* width of 6, with no '+' sign, 2 decimals */
#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";
```
``` /* finally print the result */
vprintf(result_fmt,(void*)&prod);
```

} </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}};
```

## Common 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)))
```

```(defun matrix-multiply (matrix1 matrix2)
(mapcar
(lambda (row)
(apply #'mapcar
(lambda (&rest column)
(apply #'+ (mapcar #'* row column))) matrix2)) matrix1))
```

## D

```import std.stdio: writefln;
import std.string: format, join;

T[][] matrixMul(T)(T[][] m1, T[][] m2) {
bool isRectangular(T[][] matrix) {
foreach (row; matrix)
if (row.length != matrix[0].length)
return false;
return true;
}

T[][] result;
if (isRectangular(m1) && isRectangular(m2) && m1[0].length == m2.length) {
result = new T[][](m1.length, m2[0].length);

foreach (i, m1_row_i; m1)
for (int j; j < m2[0].length; j++) {
T aux = 0;
foreach (k, m2_row_k; m2)
aux += m1_row_i[k] * m2_row_k[j];
result[i][j] = aux;
}
} else
throw new Exception("matrixMul Error");
return result;
}

string prettyPrint(T)(T[][] matrix) {
string[] result;
foreach (row; matrix)
result ~= format(row);
return "[" ~ result.join(",\n ") ~ "]";
}

void main() {
float[][] a = [[1, 2], [3, 4], [3, 6]];
float[][] b = [[-3, -8, 3,], [-2, 1, 4]];

writefln("A = \n", prettyPrint(a));
writefln("\nB = \n", prettyPrint(b));
writefln("\nA * B = \n", prettyPrint(matrixMul(a, b)));
}
```

## Factor

``` : m* flip swap [ dupd [ [ * ] 2map sum ] curry map ] map nip ;
```

Example:

``` { { 1 2 } { 3 4 } }  { { -3 -8 3 } { -2 1 4 } } m* .
```

Result:

``` { { -7 -6 11 } { -17 -20 25 } }
```

## Forth

``` include fsl-util.f

3 3 float matrix A{{
A{{ 3 3 }}fread  1e 2e 3e  4e 5e 6e  7e 8e 9e
3 3 float matrix B{{
B{{ 3 3 }}fread  3e 3e 3e  2e 2e 2e  1e 1e 1e
3 3 float matrix C{{    \ result

A{{ B{{ C{{ mat*
C{{ }}print
```

## Fortran

In ISO Fortran 90 or later, use the SIZE and MATMUL intrinsic functions:

```   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 )

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
```

## Haskell

A somewhat inefficient version with lists (transpose is expensive):

``` import Data.List

mmult :: Num a => [[a]] -> [[a]] -> [[a]]
mmult a b = [ [ sum \$ zipWith (*) ar bc | bc <- (transpose b) ] | ar <- a ]

-- Example use:
test = [[1, 2],
[3, 4]] `mmult` [[-3, -8, 3],
[-2,  1, 4]]
```

A more efficient version, based on arrays:

``` import Data.Array

mmult :: (Ix i, Num a) => Array (i,i) a -> Array (i,i) a -> Array (i,i) a
mmult x y
| x1 /= y0 || x1' /= y0'  = error "range mismatch"
| otherwise               = array ((x0,y1),(x0',y1')) l
where
((x0,x1),(x0',x1')) = bounds x
((y0,y1),(y0',y1')) = bounds y
ir = range (x0,x0')
jr = range (y1,y1')
kr = range (x1,x1')
l  = [((i,j), sum [x!(i,k) * y!(k,j) | k <- kr]) | i <- ir, j <- jr]
```

## IDL

```result = arr1 # arr2
```

## J

Matrix multiply in J is just +/ .*. For example:

```   x  =:  +/ .*

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 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

```

The notation is for a generalized inner product so that

```   x ~:/ .*. y   NB. boolean inner product (~: is "not equal" (exclusive or) and *. is "and")
x *./ .=  y   NB. which rows of x are the same as vector y?
x + / .=  y   NB. number of places where each row of x equals vector y
```

etc.

The general inner product extends to multidimensional arrays, requiring only that x and y be conformable (trailing dimension of array x equals the leading dimension of array y). For example, the matrix multiplication of two dimensional arrays requires x to have the same numbers of rows as y has columns, as you would expect.

## 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;
}
```

## Mathematica

```M1 = {{1, 2},
{3, 4},
{5, 6},
{7, 8}}
M2 = {{1, 2, 3},
{4, 5, 6}}
M = M1.M2
```

Or without the variables:

```{{1, 2}, {3, 4}, {5, 6}, {7, 8}}.{{1, 2, 3}, {4, 5, 6}}
```

The result is:

```{{9, 12, 15}, {19, 26, 33}, {29, 40, 51}, {39, 54, 69}}
```

## 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.
```

## OCaml

This version works on arrays of arrays of ints: <ocaml>let matrix_multiply x y =

``` let x0 = Array.length x
and y0 = Array.length y in
let y1 = if y0 = 0 then 0 else Array.length y.(0) in
let z = Array.make_matrix x0 y1 0 in
for i = 0 to x0-1 do
for j = 0 to y1-1 do
for k = 0 to y0-1 do
z.(i).(j) <- z.(i).(j) + x.(i).(k) * y.(k).(j)
done
done
done;
z</ocaml>
```
```# matrix_multiply [|[|1;2|];[|3;4|]|] [|[|-3;-8;3|];[|-2;1;4|]|];;
- : int array array = [|[|-7; -6; 11|]; [|-17; -20; 25|]|]
```
Translation of: Scheme

This version works on lists of lists of ints: <ocaml>(* equivalent to (apply map ...) *) let rec mapn f lists =

``` assert (lists <> []);
if List.mem [] lists then
[]
else
f (List.map List.hd lists) :: mapn f (List.map List.tl lists)
```

let matrix_multiply m1 m2 =

``` List.map
(fun row ->
mapn
(fun column ->
List.fold_left (+) 0
(List.map2 ( * ) row column))
m2)
m1</ocaml>
```
```# matrix_multiply [[1;2];[3;4]] [[-3;-8;3];[-2;1;4]];;
- : int list list = [[-7; -6; 11]; [-17; -20; 25]]
```

## 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.

<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)
{\$p[\$r][\$c] += \$a[\$r][\$_] * \$b[\$_][\$c] foreach 0 .. \$n;}}
return [@p];}</perl>
```

This function takes two references to arrays of arrays and returns the product as a reference to a new anonymous array of arrays.

## Pop11

```define matmul(a, b) -> c;
lvars ba = boundslist(a), bb = boundslist(b);
lvars i, i0 = ba(1), i1 = ba(2);
lvars j, j0 = bb(1), j1 = bb(2);
lvars k, k0 = bb(3), k1 = bb(4);
if length(ba) /= 4 then
throw([need_2d_array ^a])
endif;
if length(bb) /= 4 then
throw([need_2d_array ^b])
endif;
if ba(3) /= j0 or ba(4) /= j1 then
throw([dimensions_do_not_match ^a ^b]);
endif;
newarray([^i0 ^i1 ^k0 ^k1], 0) -> c;
for i from i0 to i1 do
for k from k0 to k1 do
for j from j0 to j1 do
c(i, k) + a(i, j)*b(j, k) -> c(i, k);
endfor;
endfor;
endfor;
enddefine;

```

## Python

<Python> a=((1, 1, 1, 1), # matrix A #

```    (2,  4,  8,  16),
(3,  9, 27,  81),
(4, 16, 64, 256))
```

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.))
```

def MatrixMul( mtx_a, mtx_b):

```   tpos_b = zip( *mtx_b)
rtn = [[ sum( map(lambda ea,eb:ea*eb, a,b)) for b in tpos_b] for a in mtx_a]
return rtn
```

v = MatrixMul( a, b )

print 'v = (' for r in v:

```   print '[',
for val in r:
print '%8.2f '%val,
print ']'
```

print ')'

u = MatrixMul(b,a)

print 'u = ' for r in u:

```   print '[',
for val in r:
print '%8.2f '%val,
print ']'
```

print ')'

</Python>

Another one,

Translation of: Scheme

<python>from operator import mul

def matrixMul(m1, m2):

``` return map(
lambda row:
map(
lambda *column:
sum(map(mul, row, column)),
*m2),
m1)</python>
```

## R

```a %*% b
```

## Ruby

Using the Matrix class: require 'matrix'

Matrix[[1, 2],

```      [3, 4]] * Matrix[[-3, -8, 3],
[-2,  1, 4]]
```

Output:

```Matrix[[-7, -6, 11], [-17, -20, 25]]
```

Version for lists:

Translation of: Haskell

def matrix_mult(a, b)

``` a.map do |ar|
b.transpose.map do |bc|
ar.zip(bc).map {|x,y| x*y}.inject {|z,w| z+w}
end
end
```

end

## Scheme

Translation of: Common Lisp

This version works on lists of lists: <scheme>(define (matrix-multiply matrix1 matrix2)

``` (map
(lambda (row)
(apply map
(lambda column
(apply + (map * row column)))
matrix2))
matrix1))</scheme>
```
```> (matrix-multiply '((1 2) (3 4)) '((-3 -8 3) (-2 1 4)))
((-7 -6 11) (-17 -20 25))
```

## 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;
begin
if length(left[1]) <> length(right) then
raise RANGE_ERROR;
else
result := length(left) times length(right[1]) times 0.0;
for i range 1 to length(left) do
for j range 1 to length(right) do
for k range 1 to length(left) do
result[i][j] +:= left[i][k] * right[k][j];
end for;
end for;
end for;
end if;
end func;
```

## 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;
```

## TI-83 BASIC

Store your matrices in [A] and [B].

```Disp [A]*[B]
```

An error will show if the matrices have invalid dimensions for multiplication.