Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Matrix Arithmetic in Swift

Matrix Arithmetic in Swift

USAMI Kosuke

May 15, 2019
Tweet

More Decks by USAMI Kosuke

Other Decks in Programming

Transcript

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

    / C# • ֶੜ࣌୅͸਺ֶઐ߈ • ࠷ۙɺ·ͨগ͠ਅ໘໨ʹ΍Γͩͨ͠
  2. ԿΛ࣮૷͢Δ͔ • ࠓճ͸ɺߦྻͷԋࢉʹண໨ͨ͠ • ଍͠ࢉ / εΧϥʔഒ / ͔͚ࢉ •

    ߦྻʹ͸ɺϕΫτϧΛϕΫτϧʹҠ͢ઢܕࣸ૾Λදݱ͢Δͱ͍ ͏ॏཁͳҙຯ͕͋Δ͕ɺࠓճ͸ѻΘͳ͍ʢͦΕʹ͸ϕΫτϧ΋ ࣮૷͢Δඞཁ͕͋ΔͷͰɾɾɾʣ
  3. 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] }
  4. ॳظԽ (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 } }
  5. ॳظԽ (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) } }
  6. ੒෼ͷऔಘͱઃఆ struct Matrix : MatrixProtocol { subscript(row: Int, column: Int)

    -> Scalar { get { return grid[row * columns + column] } set { grid[row * columns + column] = newValue } } }
  7. ߦϕΫτϧ / ྻϕΫτϧ 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] } } }
  8. ԋࢉͷ࣮૷ • ߦྻͷԋࢉ • ଍͠ࢉ / εΧϥʔഒ / ͔͚ࢉ •

    ͜ΕΒΛఆٛ͢Δϓϩτίϧ͕طʹ͋ΔͳΒ४ڌ͍ͤͨ͞ • ඪ४ͷ API ʹͳΔ΂͋͘Θ͍ͤͨ • ͳ͍৔߹Ͱ΋ɺϓϩτίϧΛఆٛͯ͠४ڌͤ͞ΔΑ͏ʹ͢Δ
  9. ଍͠ࢉͷ࣮૷ 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(-)) } }
  10. ՝୊ : zero ͸Ͳ͏͢Δʁ protocol AdditiveArithmetic { static var zero:

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

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

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

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

    func * (lhs: Self, rhs: Self) -> Self static func *= (lhs: inout Self, rhs: Self) }
  15. ͔͚ࢉͷ࣮૷ 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, +) }}) } }
  16. ࠓޙͷ՝୊ • associatedtype ΑΓδΣωϦΫεͷ΄͏͕ྑ͍͔ʁ • ΍ͬͺΓ Numeric ʹ͍͕ͨ͠ʁ • magnitude

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