USAMI Kosuke
May 15, 2019
360

# Matrix Arithmetic in Swift

May 15, 2019

## Transcript

2. ### ࣗݾ঺հ • Ӊࠤݟެี • ϑΣϯϦϧגࣜձࣾ • iOS ΞϓϦ։ൃ : Swift

/ C# • ֶੜ࣌୅͸਺ֶઐ߈ • ࠷ۙɺ·ͨগ͠ਅ໘໨ʹ΍Γͩͨ͠

4. ### ߦྻΛ Swift Ͱ࣮૷ͯ͠ΈΔ • ਺ֶͷ֓೦ΛϓϩάϥϛϯάݴޠͰදݱ͢Δ໨తɿ • ਺ֶͷ֓೦Λཧղ͍ͨ͠ • ϓϩάϥϛϯάݴޠΛཧղ͍ͨ͠ •

ࠓճ͸࣮༻౓͸͋·Γॏࢹ͠ͳ͍ • طʹ Swift for TensorFlow ͳͲ͕͋Δ
5. ### ԿΛ࣮૷͢Δ͔ • ࠓճ͸ɺߦྻͷԋࢉʹண໨ͨ͠ • ଍͠ࢉ / εΧϥʔഒ / ͔͚ࢉ •

ߦྻʹ͸ɺϕΫτϧΛϕΫτϧʹҠ͢ઢܕࣸ૾Λදݱ͢Δͱ͍ ͏ॏཁͳҙຯ͕͋Δ͕ɺࠓճ͸ѻΘͳ͍ʢͦΕʹ͸ϕΫτϧ΋ ࣮૷͢Δඞཁ͕͋ΔͷͰɾɾɾʣ
6. ### ߦྻΛදݱ͢ΔͨΊͷσʔλ • ֤੒෼ͷܕ͸Կ͔ • Կߦ͋Δ͔ / Կྻ͋Δ͔ • XߦYྻͷ੒෼Λऔಘ͢Δ /

ઃఆ͢Δ • ߦϕΫτϧ / ྻϕΫτϧ
7. ### Matrix ϓϩτίϧ protocol MatrixProtocol { associatedtype Scalar: Numeric var rows:

Int { get } var columns: Int { get } subscript(row: Int, column: Int) -> Scalar { get set } func vector(row: Int) -> [Scalar] func vector(column: Int) -> [Scalar] }
8. ### ॳظԽ (1) struct Matrix : MatrixProtocol { typealias Scalar =

Float private var grid: [Scalar] init(rows: Int, columns: Int, grid: [Scalar]) { self.rows = rows self.columns = columns self.grid = grid } }
9. ### ॳظԽ (2) // ΍ͬͺΓɺ͜͏ॻ͖͍ͨΑͶ let a = Matrix(elements: [[1, 2],

[3, 4]]) struct Matrix { init(elements: [[Scalar]]) { let rows = elements.count let columns = elements.first?.count ?? 0 let grid = elements.flatMap { \$0 } self.init(rows: rows, columns: columns, grid: grid) } }
10. ### ੒෼ͷऔಘͱઃఆ struct Matrix : MatrixProtocol { subscript(row: Int, column: Int)

-> Scalar { get { return grid[row * columns + column] } set { grid[row * columns + column] = newValue } } }
11. ### ߦϕΫτϧ / ྻϕΫτϧ struct Matrix : MatrixProtocol { func vector(row:

Int) -> [Scalar] { return (0..<columns).map { self[row, \$0] } } func vector(column: Int) -> [Scalar] { return (0..<rows).map { self[\$0, column] } } }
12. ### ԋࢉͷ࣮૷ • ߦྻͷԋࢉ • ଍͠ࢉ / εΧϥʔഒ / ͔͚ࢉ •

͜ΕΒΛఆٛ͢Δϓϩτίϧ͕طʹ͋ΔͳΒ४ڌ͍ͤͨ͞ • ඪ४ͷ API ʹͳΔ΂͋͘Θ͍ͤͨ • ͳ͍৔߹Ͱ΋ɺϓϩτίϧΛఆٛͯ͠४ڌͤ͞ΔΑ͏ʹ͢Δ
13. ### ଍͠ࢉͷϓϩτίϧ • AdditiveArithmetic ϓϩτίϧΛ࢖͏ • Swift 5 ͷ AdditiveArithmetic protocol

ͱ͸Կ͔ ͱ͍͏هࣄΛҎલ Qiita ʹॻ͍ͨ
14. ### ଍͠ࢉͷ࣮૷ extension Matrix : AdditiveArithmetic { static func + (lhs:

Matrix, rhs: Matrix) -> Matrix { return Matrix( rows: lhs.rows, columns: lhs.columns, grid: zip(lhs.grid, rhs.grid).map(+)) } static func - (lhs: Matrix, rhs: Matrix) -> Matrix { return Matrix( rows: lhs.rows, columns: lhs.columns, grid: zip(lhs.grid, rhs.grid).map(-)) } }
15. ### ՝୊ : zero ͸Ͳ͏͢Δʁ protocol AdditiveArithmetic { static var zero:

Self } • ͢΂ͯͷ੒෼͕ 0 ͷߦྻ͕θϩߦྻͰ͸͋Δͷ͕ͩɾɾɾ • ߦྻͷαΠζʹΑͬͯมΘΔͷͰɺstatic Ͱఆٛͮ͠Β͍ • ݱࡏɺྑ͍ղܾ͕ͳ͍ɾɾɾ
16. ### εΧϥʔഒͷϓϩτίϧͷఆٛ • Swift for TensorFlow ʹ͋ΔͷͰͦͷ··ਅࣅ͢Δ protocol VectorNumeric { associatedtype

Scalar: Numeric static func * (lhs: Scalar, rhs: Self) -> Self static func *= (lhs: inout Self, rhs: Scalar) }
17. ### εΧϥʔഒͷ࣮૷ extension Matrix : VectorNumeric { static func * (lhs:

Scalar, rhs: Matrix) -> Matrix { return Matrix( rows: rhs.rows, columns: rhs.columns, grid: rhs.grid.map { lhs * \$0 }) } }
18. ### ͔͚ࢉͷϓϩτίϧ • Swift ඪ४ͷ Numeric ͰͲ͏͔ʁ ҎԼͷϓϩύςΟ͕໰୊ protocol Numeric {

associatedtype Magnitude : Comparable, Numeric var magnitude: Self.Magnitude { get } } • magnitude ͸ઈର஋Λฦ͢ɾɾɾߦྻʹ͸ͳ͍֓೦ • ͕ͨͬͯ͠ɺߦྻ͸ Numeric ͡Όͳ͍
19. ### ͔͚ࢉͷϓϩτίϧͷఆٛ • Numeric ͔Β magnitude Λ͸ͣ͢ protocol MultiplicativeArithmetic { static

func * (lhs: Self, rhs: Self) -> Self static func *= (lhs: inout Self, rhs: Self) }
20. ### ͔͚ࢉͷ࣮૷ extension Matrix : MultiplicativeArithmetic { static func * (lhs:

Matrix, rhs: Matrix) -> Matrix { return Matrix( rows: lhs.rows, columns: rhs.columns, grid: (0..<lhs.rows).flatMap { row in (0..<rhs.columns).map { column in zip(lhs.vector(row: row), rhs.vector(column: column)) .map(*).reduce(0, +) }}) } }
21. ### ࠓޙͷ՝୊ • associatedtype ΑΓδΣωϦΫεͷ΄͏͕ྑ͍͔ʁ • ΍ͬͺΓ Numeric ʹ͍͕ͨ͠ʁ • magnitude

͸ߦྻ͕ࣜߟ͑ΒΕΔ͕ਖ਼ํߦྻͷΈ • ߦྻΛϕΫτϧʹ࡞༻͍ͤͨ͞ • ͜ͷߦྻΛ਌࿨͢ΔΑ͏ʹϕΫτϧΛఆٛͯ͠΍Δ