Jump to content

Matrix multiplication: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
(→‎With List and without transpose: Applied hlint and hindent)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 363:
exception index error:
putf(stand error, $x"Exception: index error."l$)
 
=={{header|APL}}==
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>
 
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}}==
Line 517 ⟶ 533:
{{Out}}
<lang AppleScript>{{51, -8, 26, -18}, {-8, -38, -6, 34}, {33, 42, 38, -14}, {17, 74, 72, 44}}</lang>
 
=={{header|APL}}==
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>
 
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|AutoHotkey}}==
Line 779:
29 40 51
39 54 69</pre>
 
 
=={{header|Burlesque}}==
Line 1,251 ⟶ 1,250:
[ 58, 64]
[139, 154]</pre>
 
=={{header|Chapel}}==
 
Overload the '*' operator for arrays
<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;
}</lang>
 
example usage (I could not figure out the syntax for multi-dimensional array literals)
<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);</lang>
 
=={{header|Clojure}}==
Line 1,333 ⟶ 1,384:
(aref b j k)))))
finally (return c)))</lang>
 
=={{header|Chapel}}==
 
Overload the '*' operator for arrays
<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;
}</lang>
 
example usage (I could not figure out the syntax for multi-dimensional array literals)
<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);</lang>
 
=={{header|D}}==
Line 1,512 ⟶ 1,511:
writefln("A * B = \n" ~ form, result);
}</lang>
 
=={{header|EGL}}==
<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
</lang>
 
=={{header|Ela}}==
Line 1,522 ⟶ 1,559:
[3, 4]] `mmult` [[-3, -8, 3],
[-2, 1, 4]]</lang>
 
=={{header|Elixir}}==
<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
 
 
</lang>
 
=={{header|ELLA}}==
Line 1,572 ⟶ 1,626:
 
COM test: just displaysignal MOC</lang>
 
=={{header|Euphoria}}==
<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</lang>
 
=={{header|EGL}}==
<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
</lang>
 
=={{header|Elixir}}==
<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
 
 
</lang>
 
=={{header|Erlang}}==
Line 1,712 ⟶ 1,693:
[[7,16],[22,40]]
</pre>
 
 
=={{header|ERRE}}==
Line 1,760 ⟶ 1,740:
39 54 69
</pre>
 
=={{header|Euphoria}}==
<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</lang>
 
=={{header|F#}}==
Line 1,826 ⟶ 1,824:
[[1, 2, 3], [4, 5, 6]] times [[1, 2], [3, 4], [5, 6]] = [[22, 28], [49, 64]]
</pre>
 
 
=={{header|Forth}}==
Line 2,899 ⟶ 2,896:
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}}</lang>
 
=={{header|Lua}}==
Line 2,944 ⟶ 2,941:
<pre>+22.00000,+28.00000
+49.00000,+64.00000</pre>
 
=={{header|M2000 Interpreter}}==
<lang M2000 Interpreter>
Line 3,022 ⟶ 3,020:
0 0 0 1
</pre>
 
=={{header|Maple}}==
<lang Maple>A := <<1|2|3>,<4|5|6>>;
Line 3,042 ⟶ 3,041:
[ ]
[32 77 122 167]</pre>
 
 
=={{header|MathCortex}}==
Line 3,248 ⟶ 3,246:
b = inverse(a);
a * b</lang>
 
 
=={{header|Ol}}==
Line 3,431 ⟶ 3,428:
<pre> -7 -6 11
-17 -20 25</pre>
 
=={{header|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 Perl&nbsp;6.
 
First, we can use a real signature that can bind two arrays as arguments, because the default in Perl&nbsp;6 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 Perl&nbsp;6 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.
 
<lang perl6>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);</lang>
 
{{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.
 
<lang perl6>sub mmult(\a,\b) {
[
for ^a -> \r {
[
for ^b[0] -> \c {
[+] a[r;^b] Z* b[^b;c]
}
]
}
]
}</lang>
 
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.
 
=={{header|Phix}}==
Line 3,582 ⟶ 3,514:
endfor;
enddefine;</lang>
 
=={{header|PowerShell}}==
<lang PowerShell>
Line 3,655 ⟶ 3,588:
mmult(M1, M2, M3) :- transpose(M2,MT), maplist(mm_helper(MT), M1, M3).
mm_helper(M2, I1, M3) :- maplist(dot(I1), M2, M3).</lang>
 
=={{header|PureBasic}}==
Matrices represented as integer arrays with rows in the first dimension and columns in the second.
Line 3,835 ⟶ 3,769:
;; -> (array #[#[19 22] #[43 50]])
</lang>
 
=={{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 Perl&nbsp;6.
 
First, we can use a real signature that can bind two arrays as arguments, because the default in Perl&nbsp;6 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 Perl&nbsp;6 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.
 
<lang perl6>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);</lang>
 
{{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.
 
<lang perl6>sub mmult(\a,\b) {
[
for ^a -> \r {
[
for ^b[0] -> \c {
[+] a[r;^b] Z* b[^b;c]
}
]
}
]
}</lang>
 
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.
 
=={{header|Rascal}}==
Line 4,251:
'''Output:'''
<lang sml>val it = [[~7,~6,11],[~17,~20,25]] : int list list</lang>
 
=={{header|Stata}}==
=== Stata matrices ===
Line 4,271 ⟶ 4,272:
2 | 9 4 6 11 |
+---------------------+</lang>
 
 
=={{header|Swift}}==
Line 4,676:
matrix_multiplication = WorksheetFunction.MMult(a, b)
End Function</lang>
 
=={{header|VBScript}}==
<lang vb>
10,339

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.