LoginSignup
3
0

More than 3 years have passed since last update.

Goで行列計算をいくつか実装してみる

Last updated at Posted at 2019-12-10

この記事はtomowarkar ひとりAdvent Calendar 2019の10日目の記事です。

行列計算がしたかった...

行列の構造体定義

// Matrix ...
type Matrix struct {
    height int
    width  int
    field  [][]float64
}

ゼロ行列生成

// ZerosMatrix ...
func (m *Matrix) ZerosMatrix(h, w int) {
    m.field = make([][]float64, h)
    for i := 0; i < h; i++ {
        m.field[i] = make([]float64, w)
    }
    m.height = h
    m.width = w
}
m.ZerosMatrix(2, 3) //  {2 3 [[0 0 0] [0 0 0]]}

$$
\left[
\begin{array}{rrr}
0 & 0 & 0 \\
0 & 0 & 0 \\
\end{array}
\right]
$$

任意の行列生成

// CreateMatrix ...
func (m *Matrix) CreateMatrix(h, w int, arr []float64) error {
    if h*w != len(arr) {
        return xerrors.New("Mattrix size error")
    }
    m.field = make([][]float64, h)
    for i := 0; i < h; i++ {
        m.field[i] = arr[w*i : w*(i+1)]
    }
    m.height = h
    m.width = w
    return nil
}
m.CreateMatrix(2, 3, []float64{1,2,3,4,5,6}) //  {2 3 [[1 2 3] [4 5 6]]}

$$
\left[
\begin{array}{rrr}
1 & 2 & 3 \\
4 & 5 & 6 \\
\end{array}
\right]
$$

転置

// T ...
func T(m Matrix) Matrix {
    var ans Matrix
    var arr []float64
    for i := 0; i < m.width; i++ {
        for j := 0; j < m.height; j++ {
            arr = append(arr, m.field[j][i])
        }
    }
    ans.CreateMatrix(m.width, m.height, arr)
    return ans
}
T(m.CreateMatrix(2, 3, []float64{1,2,3,4,5,6})) //  {3 2 [[1 4] [2 5] [3 6]]}

$$
\left[
\begin{array}{rrr}
1 & 4 \\
2 & 5 \\
3 & 6 \\
\end{array}
\right]
$$

行列の積

// Multiplication ...
func Multiplication(ma, mb Matrix) (Matrix, error) {
    ans := Matrix{}
    if ma.width != mb.height {
        return ans, xerrors.New("Mattrix size error")
    }
    ans.ZerosMatrix(ma.height, mb.width)
    for i, a := range ma.field {
        for j := 0; j < mb.width; j++ {
            mul, _ := sumOfProducts(a, T(mb).field[j])
            ans.field[i][j] = mul
        }
    }
    return ans, nil
}

func sumFloatArr(arr []float64) float64 {
    var ans float64
    for _, a := range arr {
        ans += a
    }
    return ans
}

func sumOfProducts(a, b []float64) (float64, error) {
    var ans []float64
    if len(a) != len(b) {
        return 0, xerrors.New("size error")
    }
    for i := 0; i < len(a); i++ {
        ans = append(ans, a[i]*b[i])
    }
    return sumFloatArr(ans), nil
}
var ma, mb Matrix
ma.CreateMatrix(2, 3, []float64{1, 2, 3, 4, 5, 6})
mb.CreateMatrix(3, 2, []float64{1, 2, 3, 4, 5, 6})
Multiplication(ma, mb) // {2 2 [[22 28] [49 64]]} <nil>

$$
\left[
\begin{array}{rrr}
1 & 2 & 3 \\
4 & 5 & 6
\end{array}
\right]\left[
\begin{array}{rrr}
1 & 2 \\
3 & 4 \\
5 & 6 \\
\end{array}
\right]=\left[
\begin{array}{rrr}
22 & 28 \\
49 & 64 \\
\end{array}
\right]
$$

終わりに

もっとこうした方がいいよ等あればご指摘いただけると嬉しいです😍

以上明日も頑張ります!!
tomowarkar ひとりAdvent Calendar Advent Calendar 2019

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0