Swiftで行列を扱うために自作
概要
書籍「ニューラルネットワーク自作入門」をSwiftでコーディング。
書籍はPythonです。
Numpyを使用しています。
Numpyの代わりを自作します。
コード
import Foundation
/// 行列
struct Matrix {
var matrix:[[Double]] = []
func description() {
for r in 0..<matrix.count {
print("\(r) : \(matrix[r])")
}
}
static func rand(rows:Int, colums:Int) -> Matrix {
var createMatrix = Matrix()
createMatrix.matrix = [[Double]](repeating: [Double](repeating: 0.0, count: rows), count: colums)
for r in 0..<rows {
for c in 0..<colums {
createMatrix.matrix[r][c] = Double.random(in: 0...1)
}
}
return createMatrix
}
/// 行列の内積
/// - parameter left: 左辺(行列)
/// - parameter right: 右辺(行列)
/// - returns: 結果(行列)
static func dot(left:Matrix, right:Matrix) -> Matrix {
var result = Matrix()
result.matrix = [[Double]](repeating: [Double](repeating: 0.0, count: right.matrix[0].count), count: right.matrix.count)
for rresult in 0..<result.matrix.count {
for cresult in 0..<result.matrix[rresult].count {
var sum = 0.0
for rright in 0..<right.matrix.count {
sum = sum + (right.matrix[rright][cresult] * left.matrix[rresult][rright])
}
result.matrix[rresult][cresult] = sum
}
}
return result
}
/// 行列の転置
/// - parameter input: 行列
/// - returns: 結果(行列)
static func transpose(input:Matrix) -> Matrix {
var result = Matrix()
result.matrix = [[Double]](repeating: [Double](repeating: 0.0, count: input.matrix.count), count: input.matrix[0].count)
for r in 0..<input.matrix.count {
for c in 0..<input.matrix[r].count {
result.matrix[c][r] = input.matrix[r][c]
}
}
return result
}
}
func - (left: Matrix, right: Double) -> Matrix {
var result = Matrix()
result.matrix = left.matrix
for r in 0..<result.matrix.count {
for c in 0..<result.matrix[r].count {
result.matrix[r][c] = result.matrix[r][c] - right
}
}
return result
}
func - (left: Double, right: Matrix) -> Matrix {
var result = Matrix()
result.matrix = right.matrix
for r in 0..<result.matrix.count {
for c in 0..<result.matrix[r].count {
result.matrix[r][c] = left - result.matrix[r][c]
}
}
return result
}
func - (left: Matrix, right: Matrix) -> Matrix {
var result = Matrix()
result.matrix = left.matrix
for r in 0..<result.matrix.count {
for c in 0..<result.matrix[r].count {
result.matrix[r][c] = result.matrix[r][c] - right.matrix[r][c]
}
}
return result
}
func + (left: Matrix, right: Matrix) -> Matrix {
var result = Matrix()
result.matrix = left.matrix
for r in 0..<result.matrix.count {
for c in 0..<result.matrix[r].count {
result.matrix[r][c] = result.matrix[r][c] + right.matrix[r][c]
}
}
return result
}
/// 行列の要素同士の掛け算
/// - parameter left: 左辺(行列)
/// - parameter right: 右辺(行列)
/// - returns: 結果(行列)
func * (left: Matrix, right: Matrix) -> Matrix {
var result = Matrix()
result.matrix = left.matrix
for r in 0..<result.matrix.count {
for c in 0..<result.matrix[r].count {
result.matrix[r][c] = result.matrix[r][c] * right.matrix[r][c]
}
}
return result
}
/// 行列の要素同士の掛け算
/// - parameter left: 左辺(数値)
/// - parameter right: 右辺(行列)
/// - returns: 結果(行列)
func * (left: Double, right: Matrix) -> Matrix {
var result = Matrix()
result.matrix = right.matrix
for r in 0..<result.matrix.count {
for c in 0..<result.matrix[r].count {
result.matrix[r][c] = left * result.matrix[r][c]
}
}
return result
}
example
var a = Matrix()
a.matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
var b = Matrix()
b.matrix = [[1, 2, 3]]
print("転置")
let c = Matrix.transpose(input: b)
print(c.description())
print("内積")
print(Matrix.dot(left: a, right: c).description())
print("行列の要素同士の掛け算")
print((a * a).description())
print("行列の足し算")
print((a + a).description())
print("行列の引き算")
print((a - a).description())
転置 0 : [1.0] 1 : [2.0] 2 : [3.0] () 内積 0 : [14.0] 1 : [32.0] 2 : [50.0] () 行列の要素同士の掛け算 0 : [1.0, 4.0, 9.0] 1 : [16.0, 25.0, 36.0] 2 : [49.0, 64.0, 81.0] () 行列の足し算 0 : [2.0, 4.0, 6.0] 1 : [8.0, 10.0, 12.0] 2 : [14.0, 16.0, 18.0] () 行列の引き算 0 : [0.0, 0.0, 0.0] 1 : [0.0, 0.0, 0.0] 2 : [0.0, 0.0, 0.0] ()
Action Item
- 整理
- 初期化処理
- class化検討・判断
- Numpy.random.normal検討
- パラメータチェック
- 異常系
memo
SwiftでPythonが使える(ようになる)らしい。
記事「今、僕が一番注目している Swift の新機能について、 iOSDC Japan 2018 で話します」






