package main type Matrix []Vector func MakeMatrix(n, m int) Matrix { M := make(Matrix, n) for i := 0; i < n; i++ { M[i] = MakeVector(m) } return M } func MakeRandomMatrix(n, m int) Matrix { M := make(Matrix, n) for i := 0; i < n; i++ { M[i] = MakeRandomVector(m) } return M } func (A Matrix) N() int { return len(A) } func (A Matrix) M() int { return A[0].N() } func (A Matrix) Transpose() Matrix { B := MakeMatrix(A.M(), A.N()) for i := 0; i < A.N(); i++ { for j := 0; j < A.M(); j++ { B[j][i] = A[i][j] } } return B } func (A Matrix) Add(B Matrix) Matrix { if A.N() != B.N() || A.M() != B.M() { panic("Incompatible Dimensions") } for i := 0; i < A.N(); i++ { for j := 0; j < A.M(); j++ { A[i][j] += B[i][j] } } return A } func (A Matrix) Sub(B Matrix) Matrix { if A.N() != B.N() || A.M() != B.M() { panic("Incompatible Dimensions") } for i := 0; i < A.N(); i++ { for j := 0; j < A.M(); j++ { A[i][j] -= B[i][j] } } return A } func (A Matrix) Multiply(B Matrix) Matrix { if A.M() != B.N() { panic("Incompatible Dimensions") } C := MakeMatrix(A.N(), B.M()) for i := 0; i < A.N(); i++ { for j := 0; j < A.M(); j++ { if A[i][j] != 0 { for k := 0; k < B.M(); k++ { if B[j][k] != 0 { C[i][k] += A[i][j] * B[j][k] } } } } } return C } func (A Matrix) Divide(b float64) Matrix { if b == 1 { return A } for i := 0; i < A.N(); i++ { for j := 0; j < A.M(); j++ { A[i][j] /= b } } return A } func (A Matrix) Dropout(B Vector) Matrix { if A.M() != B.N() { panic("Incompatible Dimensions") } for i := 0; i < A.N(); i++ { for j := 0; j < A.M(); j++ { A[i][j] *= B[j] } } return A }