Matrix multiplication: Difference between revisions

Content deleted Content added
Blek (talk | contribs)
No edit summary
Sonia (talk | contribs)
→‎{{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 { return nil, false }
if len(m1[0]) != extra {
m3 = make(Matrix, rows)
return nil, false
}
for i := 0; i < rows; i++ {
m3[i] = make([]Value,cols)
m3 = make(Matrix, rows)
for j := 0; j < cols; j++ {
for i := 0; i < rows; i++ {
for k := 0; k < extra; k++ {
m3[i] = make([]Value, cols)
m3[i][j] += m1[i][k] * m2[k][j]
for j := 0; j < cols; j++ {
}
for k := 0; k < extra; k++ {
m3[i][j] += m1[i][k] * m2[k][j]
}
}
}
return m3, true
}
}
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 { out += ",\n " }
if r > 0 {
out += "[ "
out += ",\n "
for c := 0; c < cols; c++ {
}
if c > 0 { out += ", " }
out += "[ "
out += fmt.Sprintf("%7.3f", m[r][c])
for c := 0; c < cols; c++ {
}
if c > 0 {
out += " ]"
out += ", "
}
}
out += "]"
out += fmt.Sprintf("%7.3f", m[r][c])
return out
}
out += " ]"
}
out += "]"
return out
}
}


func main() {
func main() {
A := Matrix{[]Value{1, 1, 1, 1},
A := Matrix{[]Value{1, 2, 3, 4},
[]Value{2, 4, 8, 16},
[]Value{5, 6, 7, 8}}
[]Value{3, 9, 27, 81},
B := Matrix{[]Value{1, 2, 3},
[]Value{4, 16, 64, 256}}
[]Value{4, 5, 6},
B := Matrix{[]Value{ 4.0 , -3.0 , 4.0/3, -1.0/4 },
[]Value{7, 8, 9},
[]Value{-13.0/3, 19.0/4, -7.0/3, 11.0/24},
[]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, 1.000, 1.000 ],
[[ 1.000, 2.000, 3.000, 4.000 ],
[ 2.000, 4.000, 8.000, 16.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:
[[ 4.000, -3.000, 1.333, -0.250 ],
[[ 1.000, 2.000, 3.000 ],
[ -4.333, 4.750, -2.333, 0.458 ],
[ 4.000, 5.000, 6.000 ],
[ 1.500, -2.000, 1.167, -0.250 ],
[ 7.000, 8.000, 9.000 ],
[ -0.167, 0.250, -0.167, 0.042 ]]
[ 10.000, 11.000, 12.000 ]]


Product of A and B:
Product of A and B:
[[ 1.000, 0.000, -0.000, -0.000 ],
[[ 70.000, 80.000, 90.000 ],
[ 0.000, 1.000, -0.000, -0.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("%6.3f ", m.ele[e:e+m.stride])
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), 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 := matrixFromRows([][]float64{
a := matrix{4, []float64{
{1, 1, 1, 1},
1, 2, 3, 4,
{2, 4, 8, 16},
5, 6, 7, 8,
{3, 9, 27, 81},
}}
{4, 16, 64, 256},
b := matrix{3, []float64{
})
1, 2, 3,
4, 5, 6,
b := matrixFromRows([][]float64{
{
7, 8, 9,
4,
10, 11, 12,
-3,
}}
4. / 3,
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}}==