2020. 5. 1. 00:57ㆍGo
In this post, We are going to make a matrix and additional arithmetic operations plus, minus. mulitply and scalar mulitply the last.
The chapter of post:
1. Matrix Structure
2. Matrix Functions
3. Implement Four Arithmetic Operations
4. Let's Go
https://github.com/SnowyPainter/Matrix
SnowyPainter/Matrix
Contribute to SnowyPainter/Matrix development by creating an account on GitHub.
github.com
First, Let's struct a structure (haha)
Let's create a matrix moudle and make a constructor.
The directory sturcture follow as:
matrix module folder, Matrix execute file, go.mod is just a package versioning file that you can create that 'go mod init <projectname>' and last main.go which would help test our matrix program.
next, matrix/matrix.go
package matrix
//Matrix contains Matrix raw
type Matrix struct {
raw [][]float64
Row int
Column int
}
The Matrix structure has 3 properties, raw, Row, Column.
Row and Column are raw's data size. In go, if you want to make a property private then make its name's first charactor to lower case. Likewise the public property must be uppercase.
We made a Matrix struct, then next is make a constructor. add the code snippet under into matrix/matrix.go.
//NewMatrix creats new Matrix structure
func NewMatrix(row int, col int) *Matrix {
r := make([][]float64, col)
for i := range r {
r[i] = make([]float64, row)
}
return &Matrix{
raw: r,
Row: row,
Column: col,
}
}
NewMatrix function initialize all arrays and put it on matrix reference variable to return.
Second, Implement Matrix struct functions
There are many functions we have to implement let's implement every functions step by step. first, we need make every get, set columns and rows functions. Step by Step, Easy get functions fisrt.
//GetColumn returns column of index
func (m *Matrix) GetColumn(index int) (array []float64) {
array = make([]float64, m.Column)
for i, r := range m.raw {
array[i] = r[index]
}
return
}
//GetRow returns row of index
func (m *Matrix) GetRow(index int) []float64 {
return m.raw[index]
}
These functions are get data by index. It's easy. Next is Set functions
//SetColumn set raw
func (m *Matrix) SetColumn(index int, data []float64) {
for i, r := range m.raw {
if i < len(data) {
r[index] = data[i]
continue
}
r[index] = 0
}
}
//SetRow set raw
func (m *Matrix) SetRow(index int, data []float64) {
if len(data) == m.Row {
m.raw[index] = data
return
}
for i := 0; i < m.Row; i++ {
if i >= len(data) {
m.raw[index][i] = 0
continue
}
m.raw[index][i] = data[i]
}
}
Set functions are easy too. just a for expressions.
Third, Implement four arithmetic operations
Actually more than four and some additional functions(e.g. transpose) so that are too long and maybe boring.
package matrix
import (
"errors"
)
//ErrMatrixesNotCoincided error
var ErrMatrixesNotCoincided error = errors.New("Two Matrixes are Not Coincided")
//ErrMatrixesNotBeMultiplicable error
var ErrMatrixesNotBeMultiplicable error = errors.New("Two Matrixes Row and Col not same")
//ElementAddHandler handles custom + or -
type ElementAddHandler func(float64, float64) float64
func checkCoincide(m1 *Matrix, m2 *Matrix) bool {
if m1.Row != m2.Row || m1.Column != m2.Column {
return false
}
return true
}
func checkMultiplicable(m1 *Matrix, m2 *Matrix) bool {
if m1.Row != m2.Column {
return false
}
return true
}
//Add sum each matrix
func (m *Matrix) add(matrix *Matrix, handler ElementAddHandler) *Matrix {
result := NewMatrix(m.Row, m.Column)
for i := 0; i < m.Column; i++ {
rowSum := make([]float64, m.Row)
r1 := m.GetRow(i)
r2 := matrix.GetRow(i)
for j := 0; j < m.Row; j++ {
rowSum[j] = handler(r1[j], r2[j])
}
result.SetRow(i, rowSum)
}
return result
}
//Plus Add two matrixes '+'
func (m *Matrix) Plus(mat *Matrix) (*Matrix, error) {
if !checkCoincide(m, mat) {
return nil, ErrMatrixesNotCoincided
}
return m.add(mat, func(a float64, b float64) float64 {
return a + b
}), nil
}
//Minus Add two matrixes '-'
func (m *Matrix) Minus(mat *Matrix) (*Matrix, error) {
if !checkCoincide(m, mat) {
return nil, ErrMatrixesNotCoincided
}
return m.add(mat, func(a float64, b float64) float64 {
return a - b
}), nil
}
//ScalarMultiply multiply constant value
func (m *Matrix) ScalarMultiply(c float64) *Matrix {
result := NewMatrix(m.Row, m.Column)
for i := 0; i < m.Column; i++ {
rowSum := make([]float64, m.Row)
for j, v := range m.GetRow(i) {
rowSum[j] = v * c
}
result.SetRow(i, rowSum)
}
return result
}
//Multiply Multiply each matrixes
func (m *Matrix) Multiply(mat *Matrix) (*Matrix, error) {
if !checkMultiplicable(m, mat) {
return nil, ErrMatrixesNotBeMultiplicable
}
result := NewMatrix(mat.Row, m.Column)
for i := 0; i < m.Column; i++ {
tmp := make([]float64, m.Row)
row := m.GetRow(i)
for j := 0; j < mat.Row; j++ {
for k, n := range mat.GetColumn(j) {
tmp[j] += row[k] * n
}
}
result.SetRow(i, tmp)
}
return result, nil
}
//Transpose return transpose matrix
func (m *Matrix) Transpose() (matrix *Matrix) {
matrix = NewMatrix(m.Column, m.Row)
for i := 0; i < m.Row; i++ { //transposed matrix's col == original.row
matrix.SetRow(i, m.GetColumn(i))
}
return matrix
}
The code above is whole code of matrix/calculate.go. copy & paste it.
Actually all the functions need not explain. everyone know how to add each matrix, multiply...
Fourth, Test go!
package main
import (
"fmt"
"github.com/snowypainter/Matrix/matrix"
)
func main() {
m := matrix.NewMatrix(2, 3)
m.SetRow(0, []float64{1, 2})
m.SetRow(1, []float64{3, 4})
m.SetRow(2, []float64{5, 6})
m2 := matrix.NewMatrix(2, 2)
m2.SetRow(0, []float64{1, 3})
m2.SetRow(1, []float64{2, 4})
fmt.Println(m)
fmt.Println(m.Transpose())
return
}
Thank you
'Go' 카테고리의 다른 글
How to sign in and sign up with Firebase on Javascript (0) | 2020.04.25 |
---|---|
How to use 'Html/Template' For your Echo Server in Go! (0) | 2020.04.18 |
Setting up Go develop environment for Beginners (0) | 2020.04.18 |
C# WebSocket-Sharp, Make it more smart (0) | 2020.04.13 |
C# The way to make Real-time audio communication RTC in WPF with WebSocket-Sharp (0) | 2020.04.12 |