Matrix multiplication: Difference between revisions
Content deleted Content added
No edit summary |
→{{header|Go}}: improve test data. mix of rows and column shows that code works on rectangular and different shaped matrices. |
||
Line 1,315: | Line 1,315: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
===Library go.matrix=== |
|||
<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) |
|||
}</lang> |
|||
{{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=== |
===2D representation=== |
||
<lang go>package main |
<lang go>package main |
||
Line 1,324: | Line 1,368: | ||
func Multiply(m1, m2 Matrix) (m3 Matrix, ok bool) { |
func Multiply(m1, m2 Matrix) (m3 Matrix, ok bool) { |
||
rows, cols, extra := len(m1), len(m2[0]), len(m2) |
rows, cols, extra := len(m1), len(m2[0]), len(m2) |
||
if len(m1[0]) != extra { |
if len(m1[0]) != extra { |
||
return nil, false |
|||
} |
|||
for i := 0; i < rows; i++ { |
|||
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 { |
func (m Matrix) String() string { |
||
rows := len(m) |
rows := len(m) |
||
cols := len(m[0]) |
cols := len(m[0]) |
||
out := "[" |
out := "[" |
||
for r := 0; r < rows; r++ { |
for r := 0; r < rows; r++ { |
||
if r > 0 { |
if r > 0 { |
||
out += " |
out += ",\n " |
||
} |
|||
out += "[ " |
|||
for c := 0; c < cols; c++ { |
|||
if c > 0 { |
|||
out += " |
out += ", " |
||
} |
} |
||
out += " |
out += fmt.Sprintf("%7.3f", m[r][c]) |
||
} |
|||
out += " ]" |
|||
} |
|||
out += "]" |
|||
return out |
|||
} |
} |
||
func main() { |
func main() { |
||
A := Matrix{[]Value{1, |
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) |
|||
[]Value{ 3.0/2, -2.0 , 7.0/6, -1.0/4 }, |
|||
if !ok { |
|||
[]Value{ -1.0/6, 1.0/4, -1.0/6, 1.0/24}} |
|||
panic("Invalid dimensions") |
|||
P,ok := Multiply(A,B) |
|||
} |
|||
if !ok { panic("Invalid dimensions") } |
|||
fmt.Printf("Matrix A:\n%s\n\n", A) |
fmt.Printf("Matrix A:\n%s\n\n", A) |
||
fmt.Printf("Matrix B:\n%s\n\n", B) |
fmt.Printf("Matrix B:\n%s\n\n", B) |
||
fmt.Printf("Product of A and B:\n%s\n\n", P) |
fmt.Printf("Product of A and B:\n%s\n\n", P) |
||
}</lang> |
}</lang> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Matrix A: |
Matrix A: |
||
[[ 1.000, |
[[ 1.000, 2.000, 3.000, 4.000 ], |
||
[ |
[ 5.000, 6.000, 7.000, 8.000 ]] |
||
[ 3.000, 9.000, 27.000, 81.000 ], |
|||
[ 4.000, 16.000, 64.000, 256.000 ]] |
|||
Matrix B: |
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: |
Product of A and B: |
||
[[ |
[[ 70.000, 80.000, 90.000 ], |
||
[ |
[ 158.000, 184.000, 210.000 ]] |
||
[ 0.000, 0.000, 1.000, -0.000 ], |
|||
[ 0.000, 0.000, 0.000, 1.000 ]] |
|||
</pre> |
</pre> |
||
===Flat representation=== |
===Flat representation=== |
||
Line 1,396: | Line 1,442: | ||
type matrix struct { |
type matrix struct { |
||
stride int |
|||
ele []float64 |
ele []float64 |
||
stride int |
|||
} |
|||
func matrixFromRows(rows [][]float64) *matrix { |
|||
if len(rows) == 0 { |
|||
return &matrix{nil, 0} |
|||
} |
|||
m := &matrix{make([]float64, len(rows)*len(rows[0])), len(rows[0])} |
|||
for rx, row := range rows { |
|||
copy(m.ele[rx*m.stride:(rx+1)*m.stride], row) |
|||
} |
|||
return m |
|||
} |
} |
||
Line 1,416: | Line 1,451: | ||
} |
} |
||
for e := 0; e < len(m.ele); e += m.stride { |
for e := 0; e < len(m.ele); e += m.stride { |
||
fmt.Printf("% |
fmt.Printf("%8.3f ", m.ele[e:e+m.stride]) |
||
fmt.Println() |
fmt.Println() |
||
} |
} |
||
Line 1,425: | Line 1,460: | ||
return nil, false |
return nil, false |
||
} |
} |
||
m3 = &matrix{make([]float64, (len(m1.ele)/m1.stride)*m2.stride) |
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 m1c0, m3x := 0, 0; m1c0 < len(m1.ele); m1c0 += m1.stride { |
||
for m2r0 := 0; m2r0 < m2.stride; m2r0++ { |
for m2r0 := 0; m2r0 < m2.stride; m2r0++ { |
||
Line 1,439: | Line 1,474: | ||
func main() { |
func main() { |
||
a := |
a := matrix{4, []float64{ |
||
1, 2, 3, 4, |
|||
5, 6, 7, 8, |
|||
}} |
|||
b := matrix{3, []float64{ |
|||
1, 2, 3, |
|||
4, 5, 6, |
|||
b := matrixFromRows([][]float64{ |
|||
7, 8, 9, |
|||
10, 11, 12, |
|||
}} |
|||
p, ok := a.multiply(&b) |
|||
-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, |
|||
}, |
|||
}) |
|||
p, ok := a.multiply(b) |
|||
a.print("Matrix A:") |
a.print("Matrix A:") |
||
b.print("Matrix B:") |
b.print("Matrix B:") |
||
Line 1,481: | Line 1,494: | ||
}</lang> |
}</lang> |
||
Output is similar to 2D version. |
Output is similar to 2D version. |
||
===Library=== |
|||
<lang go>package main |
|||
import ( |
|||
"fmt" |
|||
mat "github.com/skelterjohn/go.matrix" |
|||
) |
|||
func main() { |
|||
a := mat.MakeDenseMatrixStacked([][]float64{ |
|||
{1, 1, 1, 1}, |
|||
{2, 4, 8, 16}, |
|||
{3, 9, 27, 81}, |
|||
{4, 16, 64, 256}, |
|||
}) |
|||
b := mat.MakeDenseMatrixStacked([][]float64{ |
|||
{ |
|||
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, |
|||
}, |
|||
}) |
|||
p, err := a.TimesDense(b) |
|||
fmt.Printf("Matrix A:\n%v\n", a) |
|||
fmt.Printf("Matrix B:\n%v\n", b) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
return |
|||
} |
|||
fmt.Printf("Product of A and B:\n%v\n", p) |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
Matrix A: |
|||
{ 1, 1, 1, 1, |
|||
2, 4, 8, 16, |
|||
3, 9, 27, 81, |
|||
4, 16, 64, 256} |
|||
Matrix B: |
|||
{ 4, -3, 1.333333, -0.25, |
|||
-4.333333, 4.75, -2.333333, 0.458333, |
|||
1.5, -2, 1.166667, -0.25, |
|||
-0.166667, 0.25, -0.166667, 0.041667} |
|||
Product of A and B: |
|||
{ 1, 0, -0, -0, |
|||
0, 1, -0, -0, |
|||
0, 0, 1, 0, |
|||
0, 0, 0, 1} |
|||
</pre> |
|||
=={{header|Groovy}}== |
=={{header|Groovy}}== |