Matrix multiplication: Difference between revisions
Content added Content deleted
m (Fixed lang tags.) |
|||
Line 3: | Line 3: | ||
=={{header|Ada}}== |
=={{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: |
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: |
||
⚫ | |||
⚫ | |||
⚫ | |||
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays; |
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays; |
||
Line 34: | Line 33: | ||
begin |
begin |
||
Put (A * B); |
Put (A * B); |
||
end Matrix_Product; |
end Matrix_Product;</lang> |
||
⚫ | |||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 44: | Line 42: | ||
</pre> |
</pre> |
||
The following code illustrates how matrix multiplication could be implemented from scratch: |
The following code illustrates how matrix multiplication could be implemented from scratch: |
||
<lang ada> |
<lang ada>package Matrix_Ops is |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
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;</lang> |
|||
⚫ | |||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 97: | Line 93: | ||
result |
result |
||
); |
); |
||
⚫ | |||
<pre style="background-color:#ffe"> |
|||
⚫ | |||
OP * = (MATRIX a, b)MATRIX: ( # overload matrix times matrix # |
OP * = (MATRIX a, b)MATRIX: ( # overload matrix times matrix # |
||
[LWB a:UPB a, 2 LWB b:2 UPB b]FIELD result; |
[LWB a:UPB a, 2 LWB b:2 UPB b]FIELD result; |
||
Line 104: | Line 99: | ||
FOR k FROM LWB result TO UPB result DO result[k,]:=a[k,]*b OD; |
FOR k FROM LWB result TO UPB result DO result[k,]:=a[k,]*b OD; |
||
result |
result |
||
); |
);</lang> |
||
</pre> |
|||
# Some sample matrices to test # |
# Some sample matrices to test # |
||
MATRIX a=((1, 1, 1, 1), # matrix A # |
MATRIX a=((1, 1, 1, 1), # matrix A # |
||
Line 245: | Line 239: | ||
Matrix multiply in APL is just <tt>+.×</tt>. For example: |
Matrix multiply in APL is just <tt>+.×</tt>. For example: |
||
<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</lang> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
ahk [http://www.autohotkey.com/forum/topic44657-150.html discussion] |
ahk [http://www.autohotkey.com/forum/topic44657-150.html discussion] |
||
Line 341: | Line 335: | ||
=={{header|C}}== |
=={{header|C}}== |
||
{{works with|gcc|<nowiki>4.1.2 20070925 (Red Hat 4.1.2-27) Options: gcc -std=gnu99</nowiki>}} |
{{works with|gcc|<nowiki>4.1.2 20070925 (Red Hat 4.1.2-27) Options: gcc -std=gnu99</nowiki>}} |
||
<lang c> |
<lang c>#include <stdio.h> |
||
#include <stdio.h> |
|||
#define dim 4 /* fixed length square matrices */ |
#define dim 4 /* fixed length square matrices */ |
||
const int SLICE=0; /* coder hints */ |
const int SLICE=0; /* coder hints */ |
||
Line 397: | Line 390: | ||
/* finally print the result */ |
/* finally print the result */ |
||
vprintf(result_fmt,(void*)&prod); |
vprintf(result_fmt,(void*)&prod); |
||
⚫ | |||
} |
|||
</lang> |
|||
Output: |
Output: |
||
Product of a and b: |
Product of a and b: |
||
Line 407: | Line 399: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
<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))))))) |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
(defun matrix-multiply (matrix1 matrix2) |
|||
(mapcar |
|||
(lambda (row) |
|||
(apply #'mapcar |
|||
(lambda (&rest column) |
|||
(lambda (&rest column) |
|||
(apply #'+ (mapcar #'* row column))) matrix2)) matrix1))</lang> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
⚫ | |||
<pre> |
|||
⚫ | |||
import std.string: format, join; |
import std.string: format, join; |
||
Line 468: | Line 459: | ||
writefln("\nB = \n", prettyPrint(b)); |
writefln("\nB = \n", prettyPrint(b)); |
||
writefln("\nA * B = \n", prettyPrint(matrixMul(a, b))); |
writefln("\nA * B = \n", prettyPrint(matrixMul(a, b))); |
||
⚫ | |||
} |
|||
</pre> |
|||
=={{header|ELLA}}== |
=={{header|ELLA}}== |
||
Sample originally from ftp://ftp.dra.hmg.gb/pub/ella (a now dead link) - Public release. |
Sample originally from ftp://ftp.dra.hmg.gb/pub/ella (a now dead link) - Public release. |
||
Code for matrix multiplication hardware design verification: |
Code for matrix multiplication hardware design verification: |
||
⚫ | |||
<pre> |
|||
⚫ | |||
[INT k = 1..n](vector1[k], vector2[k]). |
[INT k = 1..n](vector1[k], vector2[k]). |
||
Line 519: | Line 508: | ||
). |
). |
||
COM test: just displaysignal MOC |
COM test: just displaysignal MOC</lang> |
||
</pre> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
<lang factor>: m* flip swap [ dupd [ [ * ] 2map sum ] curry map ] map nip ;</lang> |
|||
Example: |
Example: |
||
<lang factor>{ { 1 2 } { 3 4 } } { { -3 -8 3 } { -2 1 4 } } m* .</lang> |
|||
Result: |
Result: |
||
<lang factor>{ { -7 -6 11 } { -17 -20 25 } }</lang> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
{{libheader|Forth Scientific Library}} |
{{libheader|Forth Scientific Library}} |
||
⚫ | |||
<pre><nowiki> |
|||
⚫ | |||
3 3 float matrix A{{ |
3 3 float matrix A{{ |
||
Line 540: | Line 527: | ||
A{{ B{{ C{{ mat* |
A{{ B{{ C{{ mat* |
||
C{{ }}print |
C{{ }}print</lang> |
||
</nowiki></pre> |
|||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
In ISO Fortran 90 or later, use the SIZE and MATMUL intrinsic functions: |
In ISO Fortran 90 or later, use the SIZE and MATMUL intrinsic functions: |
||
<lang fortran> |
<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 ) |
|||
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</lang> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Line 574: | Line 560: | ||
A somewhat inefficient version with lists (''transpose'' is expensive): |
A somewhat inefficient version with lists (''transpose'' is expensive): |
||
⚫ | |||
<pre> |
|||
⚫ | |||
mmult :: Num a => [[a]] -> [[a]] -> [[a]] |
mmult :: Num a => [[a]] -> [[a]] -> [[a]] |
||
Line 583: | Line 568: | ||
test = [[1, 2], |
test = [[1, 2], |
||
[3, 4]] `mmult` [[-3, -8, 3], |
[3, 4]] `mmult` [[-3, -8, 3], |
||
[-2, 1, 4]] |
[-2, 1, 4]]</lang> |
||
</pre> |
|||
A more efficient version, based on arrays: |
A more efficient version, based on arrays: |
||
⚫ | |||
<pre> |
|||
⚫ | |||
mmult :: (Ix i, Num a) => Array (i,i) a -> Array (i,i) a -> Array (i,i) a |
mmult :: (Ix i, Num a) => Array (i,i) a -> Array (i,i) a -> Array (i,i) a |
||
Line 601: | Line 584: | ||
jr = range (y1,y1') |
jr = range (y1,y1') |
||
kr = range (x1,x1') |
kr = range (x1,x1') |
||
l = [((i,j), sum [x!(i,k) * y!(k,j) | k <- kr]) | i <- ir, j <- jr] |
l = [((i,j), sum [x!(i,k) * y!(k,j) | k <- kr]) | i <- ir, j <- jr]</lang> |
||
</pre> |
|||
=={{header|IDL}}== |
=={{header|IDL}}== |
||
<lang idl>result = arr1 # arr2</lang> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
Matrix multiply in J is just <code>+/ .*</code>. For example: |
Matrix multiply in J is just <code>+/ .*</code>. For example: |
||
⚫ | |||
<lang j> |
|||
⚫ | |||
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) |
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) |
||
Line 620: | Line 601: | ||
0.00 1.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 1.00 0.00 |
||
0.00 0.00 0.00 1.00 |
0.00 0.00 0.00 1.00</lang> |
||
</lang> |
|||
The notation is for a generalized inner product so that |
The notation is for a generalized inner product so that |
||
<lang j>x ~:/ .*. y NB. boolean inner product ( ~: is "not equal" (exclusive or) and *. is "and") |
|||
<lang j> |
|||
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</lang> |
|||
x + / .= y NB. number of places where each row of x equals vector y |
|||
</lang> |
|||
etc. |
etc. |
||
Line 633: | Line 611: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
<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; |
|||
⚫ | |||
} |
|||
=={{header|Mathematica}}== |
=={{header|Mathematica}}== |
||
<lang mathematica>M1 = {{1, 2}, |
|||
{3, 4}, |
|||
{5, 6}, |
|||
{7, 8}} |
|||
M2 = {{1, 2, 3}, |
|||
{4, 5, 6}} |
|||
M = M1.M2</lang> |
|||
Or without the variables: |
Or without the variables: |
||
<lang mathematica>{{1, 2}, {3, 4}, {5, 6}, {7, 8}}.{{1, 2, 3}, {4, 5, 6}}</lang> |
|||
The result is: |
The result is: |
||
<lang mathematica>{{9, 12, 15}, {19, 26, 33}, {29, 40, 51}, {39, 54, 69}}</lang> |
|||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
Line 673: | Line 651: | ||
=={{header|Nial}}== |
=={{header|Nial}}== |
||
<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.</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 764: | Line 742: | ||
=={{header|Pop11}}== |
=={{header|Pop11}}== |
||
⚫ | |||
<pre> |
|||
⚫ | |||
lvars ba = boundslist(a), bb = boundslist(b); |
lvars ba = boundslist(a), bb = boundslist(b); |
||
lvars i, i0 = ba(1), i1 = ba(2); |
lvars i, i0 = ba(1), i1 = ba(2); |
||
Line 787: | Line 764: | ||
endfor; |
endfor; |
||
endfor; |
endfor; |
||
enddefine; |
enddefine;</lang> |
||
</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
<lang python> |
<lang python>a=((1, 1, 1, 1), # matrix A # |
||
a=((1, 1, 1, 1), # matrix A # |
|||
(2, 4, 8, 16), |
(2, 4, 8, 16), |
||
(3, 9, 27, 81), |
(3, 9, 27, 81), |
||
Line 829: | Line 803: | ||
print '%8.2f '%val, |
print '%8.2f '%val, |
||
print ']' |
print ']' |
||
print ')' |
print ')'</lang> |
||
</lang> |
|||
Another one, {{trans|Scheme}} |
Another one, {{trans|Scheme}} |
||
Line 846: | Line 818: | ||
=={{header|R}}== |
=={{header|R}}== |
||
<lang r>a %*% b</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 913: | Line 885: | ||
=={{header|SQL}}== |
=={{header|SQL}}== |
||
<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;</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 963: | Line 935: | ||
=={{header|TI-83 BASIC}}== |
=={{header|TI-83 BASIC}}== |
||
Store your matrices in <tt>[A]</tt> and <tt>[B]</tt>. |
Store your matrices in <tt>[A]</tt> and <tt>[B]</tt>. |
||
<lang ti83b>Disp [A]*[B]</lang> |
|||
An error will show if the matrices have invalid dimensions for multiplication. |
An error will show if the matrices have invalid dimensions for multiplication. |
||
Line 970: | Line 942: | ||
{{trans|Mathematica}} |
{{trans|Mathematica}} |
||
<lang ti89b>[1,2; 3,4; 5,6; 7,8] → m1 |
|||
[1,2,3; 4,5,6] → m2 |
|||
m1 * m2</lang> |
|||
Or without the variables: |
Or without the variables: |
||
<lang ti89b>[1,2; 3,4; 5,6; 7,8] * [1,2,3; 4,5,6]</lang> |
|||
The result (without prettyprinting) is: |
The result (without prettyprinting) is: |
||
<lang ti89b>[[9,12,15][19,26,33][29,40,51][39,54,69]]</lang> |
|||
=={{header|Ursala}}== |
=={{header|Ursala}}== |