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 で話します」