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

SwiftyMathで学ぶ数学(抽象代数学)

Taketo Sano
September 07, 2019

 SwiftyMathで学ぶ数学(抽象代数学)

Taketo Sano

September 07, 2019
Tweet

More Decks by Taketo Sano

Other Decks in Education

Transcript

  1. ࠓ೔ͷ໨త • ਺ֶʢந৅୅਺ֶʣͷجૅతͳ֓೦Λ protocol-oriented ͳ Swift ίʔυͰ࣮ݱ͠ͳ͕ΒֶͿ͜ͱɽ • ެཧΛ protocol

    ͱͯ͠ɼެཧΛຬͨ͢ର৅Λ struct ͱͯ͠ ࣮ݱ͢Δɽ·ͨಛఆͷ৚݅ԼͰର৅͕ຬͨ͢ެཧΛ “ڧԽ” Ͱ͖Δ͜ͱΛ conditional conformance ʹΑ࣮ͬͯݱ͢Δɽ • ந৅తͰ೉͍͠ݱ୅਺ֶʹڵຯΛ࣋ͭΩοΧέʹͳͬͨΒ خ͍͠ʂίϯϐϡʔλ্Ͱʮ਺ֶͷϛχνϡΞʯΛ࡞ͬͯ ༡Ϳ໘ന͞΋఻͍͑ͨɽ
  2. Contents ( ˒ ೉қ౓) 1. ܈ɾ؀ɾମͷఆٛ ˒ 2. ϢʔΫϦου؀ͱޓআ๏ ˒˒

    3. ੔਺ͷ৒༨ྨ؀ ˒˒˒ 4. ଟ߲ࣜͷ৒༨ྨ؀ ˒˒˒˒ 5. ୅਺֦େͰ਺Λ࡞Δ ˒˒˒˒˒ A. ݱࡏͷݚڀͱࠓޙͷల๬
  3. ܈ɾ؀ɾମ Ճ๏܈ ͕Ͱ͖Δ +, − ؀ ͕Ͱ͖Δ +, − ,

    × extends ମ ͕Ͱ͖Δ +, − , × , ÷ extends
  4. Ճ๏܈ (AdditiveGroup) ʴ ͱ − ͕Ͱ͖Δ protocol AdditiveGroup { static

    var zero: Self { get } // θϩͷଘࡏ static func + (a: Self, b: Self) -> Self // ଍͠ࢉ prefix static func - (x: Self) -> Self // ࿨ͷٯݩ static func - (a: Self, b: Self) -> Self // Ҿ͖ࢉ } extension AdditiveGroup { static func -(a: Self, b: Self) -> Self { return (a + (-b)) // Ҿ͖ࢉ͸࣮૷͠ͳͯ͘ྑ͍ʂ } }
  5. Ճ๏܈ (AdditiveGroup) ʴ ͱ − ͕Ͱ͖Δ protocol AdditiveGroup { static

    var zero: Self { get } // θϩͷଘࡏ static func + (a: Self, b: Self) -> Self // ଍͠ࢉ prefix static func - (x: Self) -> Self // ࿨ͷٯݩ static func - (a: Self, b: Self) -> Self // Ҿ͖ࢉ } extension AdditiveGroup { static func -(a: Self, b: Self) -> Self { return (a + (-b)) // Ҿ͖ࢉ͸࣮૷͠ͳͯ͘ྑ͍ʂ } } ஫)ʮՃ๏܈ʯͰ͋ΔͨΊʹ͸ɼ • ࿨ͷՄ׵ੑʢ x + y = y + x ʣ΍ɼ • θϩͷ୯Ґੑʢ x + 0 = 0 + x = x ʣͳͲ ॾʑͷੑ࣭Λຬͨ͞ͳ͚Ε͹ͳΒͳ͍ɽ ͜ΕΒ͸ protocol ϨϕϧͰ͸՝ͤͳ͍ͷͰɼ ࢓༷ͱͯ͠՝ͯ͠ద߹͢Δ struct ͷ੹೚ͱ͢Δɽ
  6. ؀ (Ring) 
 ʴ, −, × ͕Ͱ͖Δ protocol AdditiveGroup {

    // Ճ๏܈ … } protocol Ring: AdditiveGroup { // ؀ static var identity: Self { get } // ੵͷ୯Ґݩ static func * (a: Self, b: Self) -> Self // ֻ͚ࢉ var inverse: Self? { get } // ੵͷٯݩ } extends
  7. ؀ (Ring) 
 ʴ, −, × ͕Ͱ͖Δ protocol AdditiveGroup {

    // Ճ๏܈ … } protocol Ring: AdditiveGroup { // ؀ static var identity: Self { get } // ੵͷ୯Ґݩ static func * (a: Self, b: Self) -> Self // ֻ͚ࢉ var inverse: Self? { get } // ੵͷٯݩ } extends ٯݩ͸ optional
  8. ମ (Field) ʴ, −, ×, ÷ ͕Ͱ͖Δ protocol AdditiveGroup {

    … } protocol Ring: AdditiveGroup { … } protocol Field: Ring { static func / (a: Self, b: Self) -> Self // ׂΓࢉ } extension Field { static func / (a: Self, b: Self) -> Self { return a * b.inverse! } } extends extends
  9. ମ (Field) ʴ, −, ×, ÷ ͕Ͱ͖Δ protocol AdditiveGroup {

    … } protocol Ring: AdditiveGroup { … } protocol Field: Ring { static func / (a: Self, b: Self) -> Self // ׂΓࢉ } extension Field { static func / (a: Self, b: Self) -> Self { return a * b.inverse! } } extends extends ମ͸θϩͰͳ͍ݩ͸ ඞͣٯ਺Λ࣋ͭ
  10. 1) ੔਺ܕ (Integer) • ੔਺ܕ͸ +, -, × ͷͰ͖Δ؀ɽ •

    ÷ ʹ͍ͭͯ͸ดͯ͡ͳ͍ͷͰମͰ͸ͳ͍ɽ • ࣮૷͸ Int ܕΛ Ring ܕʹద߹ͤ͞ɼ଍Γͳ͍ϝιου͚ͩ ௥Ճ͢Δ͚ͩͰྑ͍ɽ extension Int: Ring { static var identity: Int { return 1 } static var inverse: Int? { return (abs(self) == 1) ? self : nil } }
  11. 2) ༗ཧ਺ܕ (Rational Number) • ༗ཧ਺ܕ͸࢛ଇԋࢉͷͰ͖Δମɽ • ࣮૷͸ straight forward.

    struct RationalNumber: Field { private let p, q: Int init(_ p: Int, _ q: Int) { (self.p, self.q) = (p, q) } static var zero: Int { return Rational(0, 1) } static var identity: Int { return Rational(1, 1) } var inverse: Rational? { return (p != 0) ? Rational(q, p) : nil } …
  12. ྫ3) ࣮਺…? (Real Number) • ࣮਺ܕ͸࢛ଇԋࢉͷͰ͖Δମɽ • Double Λ extend

    ࣮ͯ͠਺ͱ͍͏͜ͱʹ͍ͯ͠Δ͕ɼແཧ਺͸ුಈখ਺఺ ਺Ͱ͸ۙࣅతʹ͔͠ѻ͑ͳ͍ͷͰɼ͜ΕΛ࣮਺ͱݺͿͷ͸఍߅͕͋Δɽ typealias RealNumber = Double extension RealNumber: Field { public static var zero: { return 0 } static var identity: Int { return 1 } public var inverse: RealNumber? { return (self == 0) ? nil : 1/self } …
  13. ྫ4) ߦྻ (Matrix) • R Λ؀ͱ͢Δɽn × m ܕͷʢR-੒෼ʣߦྻͱ͸ɼR ͷཁૉΛ௕ํܗঢ়

    n × m ݸ ฒ΂ͨ΋ͷɽ • ߦྻͷ࿨ A + B ͸ɼA ͱ B ͷαΠζ͕Ұக͢Δ ৔߹ͷΈఆٛ͞ΕΔɽ • ߦྻͷੵ AB ͸… A = a11 a12 … a1m a21 a22 … a2m ⋮ ⋮ ⋱ ⋮ an1 an2 … anm n m
  14. ྫ4) ߦྻ (Matrix) • ߦྻͷੵ AB ͸ɼA ͷྻ਺ ͱ B

    ͷߦ਺ ͕Ұக͢Δ৔߹ʹͷΈ ఆٛ͞ΕΔɽ • ߦྻʹ͸ԋࢉ +, -, × ͕ఆٛ͞Ε͍ͯΔ͕ɼαΠζͷ੍໿ͳ͠ ʹ͸Ճ๏܈ͩͱ͔؀ͩͱ͔ݴ͑ͳ͍ʂ Ͳ͏࣮૷͢΂͖͔ʁ a11 … a1n a21 … a2n ⋮ ⋱ ⋮ am1 … amn a11 … a1n a21 … a2n ⋮ ⋱ ⋮ am1 … amn m n n p a11 … a1n a21 … a2n ⋮ ⋱ ⋮ am1 … amn = m p A B AB
  15. ྫ4) ߦྻ (Matrix) • ͜͏͸ͨ͘͠ͳ͍ɽ struct Matrix<R: Ring>: Ring {

    static func + (a: Matrix<R>, b: Matrix<R>) -> Matrix<R> { guard a.size == b.size else { fatalError() } return Matrix(size: a.size) { (i, j) in … } } static func * (a: Matrix<R>, b: Matrix<R>) -> Matrix<R> { guard a.size.1 == b.size.0 else { fatalError() } let size = (a.size.0, b.size.1) return Matrix(size: size) { (i, k) in … } } }
  16. ྫ4) ߦྻ (Matrix) • ͜͏͸ͨ͘͠ͳ͍ɽ struct Matrix<R: Ring>: Ring {

    static func + (a: Matrix<R>, b: Matrix<R>) -> Matrix<R> { guard a.size == b.size else { fatalError() } return Matrix(size: a.size) { (i, j) in … } } static func * (a: Matrix<R>, b: Matrix<R>) -> Matrix<R> { guard a.size.1 == b.size.0 else { fatalError() } let size = (a.size.0, b.size.1) return Matrix(size: size) { (i, k) in … } } }
  17. ྫ4) ߦྻ (Matrix) • ͜͏͍ͨ͠ʂ Ͱ΋ܕύϥϝʔλʹ Int ܕ͸༩͑ΒΕͳ͍… struct Matrix<n:

    Int, m: Int, R: Ring>: AdditiveGroup { static func + (a: Matrix<n, m, R>, b: Matrix<n, m, R>) -> Matrix<n, m, R> { return Matrix { (i, j) in … } } static func * <p>(a: Matrix<n, m, R>, b: Matrix<m, p, R>) -> _Matrix<n, p, R> { return Matrix { (i, k) in … } }
  18. ྫ4) ߦྻ (Matrix) • ͜͏͍ͨ͠ʂ Ͱ΋ܕύϥϝʔλʹ Int ܕ͸༩͑ΒΕͳ͍… struct Matrix<n:

    Int, m: Int, R: Ring>: AdditiveGroup { static func + (a: Matrix<n, m, R>, b: Matrix<n, m, R>) -> Matrix<n, m, R> { return Matrix { (i, j) in … } } static func * <p>(a: Matrix<n, m, R>, b: Matrix<m, p, R>) -> _Matrix<n, p, R> { return Matrix { (i, k) in … } }
  19. ྫ4) ߦྻ (Matrix) • ͳΒ͹੔਺஋ʹରԠ͢Δ ܕ Λ࡞Ε͹͍͍ • ʢΑΓετΠοΫʹϖΞϊͷެཧʹΑΔܕϨϕϧࣗવ਺Λ࡞ͬͯ΋͍͍ʣ protocol

    _Int { static var intValue: Int { get } } struct _0 : _Int { static let intValue = 0 } struct _1 : _Int { static let intValue = 1 } struct _2 : _Int { static let intValue = 2 } struct _3 : _Int { static let intValue = 3 } struct _4 : _Int { static let intValue = 4 } struct _5 : _Int { static let intValue = 5 } …
  20. ྫ4) ߦྻ (Matrix) • ͦͯ͜͠͏ɽ struct Matrix<n: _Int, m: _Int,

    R: Ring>: AdditiveGroup { static func + (a: Matrix<n, m, R>, b: Matrix<n, m, R>) -> Matrix<n, m, R> { return Matrix { (i, j) in … } } static func * <p>(a: Matrix<n, m, R>, b: Matrix<m, p, R>) -> _Matrix<n, p, R> { return Matrix { (i, k) in … } }
  21. ྫ4) ߦྻ (Matrix) • ಛʹ n = m ͷͱ͖͸ +

    ͱ × ʹ͍ͭͯด͍ͯ͡ΔͷͰʮ؀ʯʹͳΔɽ ͜ΕΛ conditional conformance ʹΑͬͯ ͱͰ͖Δʂ ਺ֶͱίʔυ͕៉ྷʹରԠͯ͠خ͍͠ • ʢݱ࣮໰୊Ͱ͸ߦྻͷαΠζΛಈతʹܾΊ͍ͨ৔߹΋ଟ͍ɽ SwiftyMath Ͱ͸αΠζʹ `Dynamic` ΛࢦఆͰ͖ΔΑ͏ʹ͍ͯ͠Δʣ extension Matrix: Ring where n == m { }
  22. ྫ5) ϕΫτϧ (Vector) • Vector ܕ͸ m = 1 ͷ

    Matrix ܕͳͷͰɼผ໊Λ͚ͭΕ͹࣮૷ऴΘΓɽ • ଍͠ࢉ΍ߦྻͱͷֻ͚ࢉ΋ɼߦྻͷԋࢉ͔ΒҾ͖ܧ͕ΕΔɽ • ͞Βʹ extension Ͱ಺ੵ΍֎ੵʢwhere n == 3ʣΛ௥Ճͯ͠΋ྑ͍ɽ typealias Vector<n: _Int, R: Ring> = Matrix<n, _1, R>
  23. (ൃల) Ճ܈ ͱ ϕΫτϧۭؒ • Vector ΋ Matrix ΋ɼR ͷཁૉΛֻ͚Δ

    εΧϥʔഒ ͱ͍͏ԋࢉ͕ఆٛ ͞ΕΔɽεΧϥʔഒͷͰ͖ΔՃ๏܈Λ R-Ճ܈ (R-Module) ͱ͍͏ɽ • ಛʹ R ͕ମͷͱ͖ɼ R-Ճ܈ ͸ R-ϕΫτϧۭؒ ͱݺ͹ΕΔɽ protocol Module: AdditiveGroup { associatedtype CoeffRing: Ring static func * (r: CoeffRing, m: Self) -> Self } protocol VectorSpace: Module where CoeffRing: Field { } extends
  24. ϢʔΫϦου؀ͱޓআ๏ • ੔਺؀ʹ͸ʮֻ͚ࢉͷٯԋࢉʯͱͯ͠ͷׂΓࢉ͸ఆٛͰ͖ ͳ͍͕ɼʮ༨Γ෇͖আࢉʯͳΒఆٛͰ͖Δɽ • Ұൠʹʮ༨Γ෇͖আࢉʯ͕Ͱ͖Δ؀Λ ϢʔΫϦου؀ ͱ͍ ͏ɽ •

    ϢʔΫϦου؀Ͱ͸ɼ೚ҙͷೋͭͷཁૉ a, b ʹରͯͦ͠Ε Βͷ࠷େެ໿਺ (greatest common divisor = gcd ) ΛٻΊΔ ΞϧΰϦζϜɿϢʔΫϦουͷޓআ๏ ͕࢖͑Δɽ
  25. ྫ) 1732 = 8 ⋅ 194 + 180 194 =

    1 ⋅ 180 + 14 180 = 12 ⋅ 14 + 12 14 = 1 ⋅ 12 + 2 12 = 6 ⋅ 2 + 0 gcd(1732, 194) = ?
  26. ྫ) 1732 = 8 ⋅ 194 + 180 194 =

    1 ⋅ 180 + 14 180 = 12 ⋅ 14 + 12 14 = 1 ⋅ 12 + 2 12 = 6 ⋅ 2 + 0 gcd(1732, 194) = ?
  27. ྫ) 1732 = 8 ⋅ 194 + 180 194 =

    1 ⋅ 180 + 14 180 = 12 ⋅ 14 + 12 14 = 1 ⋅ 12 + 2 12 = 6 ⋅ 2 + 0 gcd(1732, 194) = ?
  28. ྫ) 1732 = 8 ⋅ 194 + 180 194 =

    1 ⋅ 180 + 14 180 = 12 ⋅ 14 + 12 14 = 1 ⋅ 12 + 2 12 = 6 ⋅ 2 + 0 gcd(1732, 194) = ?
  29. ྫ) 1732 = 8 ⋅ 194 + 180 194 =

    1 ⋅ 180 + 14 180 = 12 ⋅ 14 + 12 14 = 1 ⋅ 12 + 2 12 = 6 ⋅ 2 + 0 gcd(1732, 194) = ?
  30. ྫ) gcd(1732,194) = gcd(194,180) = gcd(180,14) = gcd(14,12) = gcd(12,2)

    = 2 1732 = 8 ⋅ 194 + 180 194 = 1 ⋅ 180 + 14 180 = 12 ⋅ 14 + 12 14 = 1 ⋅ 12 + 2 12 = 6 ⋅ 2 + 0 gcd(1732, 194) = ?
  31. ϢʔΫϦου؀ͱޓআ๏ͷ࣮૷ func gcd<R: EuclideanRing>(_ a: R, _ b: R) ->

    R { switch b { case .zero: return a default: return gcd(b, a % b) } } protocol EuclideanRing: Ring { static func / (a: Self, b: Self) -> Self static func % (a: Self, b: Self) -> Self static func /% (a: Self, b: Self) -> (Self, Self) }
  32. Int ܕΛ EuclideanRing ܕʹ extension Int: EuclideanRing { static func

    /% (a: Int, b: Int) -> (Int, Int) { let q = a / b // ঎ let r = a - q * b // ༨Γ return (q, r) } }
  33. ଟ߲ࣜ (Polynomial) • ্ͷΑ͏ͳܗͷࣜΛ x ͷଟ߲ࣜͱ͍͏ɽ܎਺ ai ͸೚ҙͷ؀ R ͷݩɽ

    • ʢR-܎਺ʣଟ߲ࣜͷશମ͸ɼ+, -, × ͷͰ͖Δ ؀ Λͳ͢ʢεΧϥʔഒ ͷͰ͖Δ R-Ճ܈ Ͱ΋͋Δʣɽ • ಛʹ R ͕ ମ ͷͱ͖ɼR-܎਺ଟ߲ࣜ؀ ͸ ϢʔΫϦου؀ ͱͳΔɽ f(x) = an xn + an−1 xn−1 + ⋯ + a1 x + a0
  34. ྫ) f(x) = 2x3 + x2 − 3x + 2

    Λ g(x) = x2 + 1 ͰׂΔɽ ∴ f(x) = (2x + 1) ⋅ g(x) − 5x + 1
  35. ଟ߲ࣜܕͷ࣮૷ struct Polynomial<R: Ring>: Ring, Module { typealias CoeffRing =

    R static func + (f: Polynomial<R>, g: Polynomial<R>) -> Polynomial<R> { … extension Polynomial: EuclideanRing where R: Field { static func /%(f: Polynomial<R>, g: Polynomial<R>) -> (Polynomial<R>, Polynomial<R>) { …
  36. ֦ுϢʔΫϦουͷޓআ๏ • ޓআ๏Λ֦ுͯ͠ɼϢʔΫϦου؀ R ͷݩ a, b ʹରͯ͠ɼ ɹͳΔ R

    ͷݩ x, y ΛٻΊΔ͜ͱ͕Ͱ͖Δɽ • ϢʔΫϦουͷޓআ๏Λٯ͔Βղ͖௚͢͜ͱͰಘΒΕΔɽ ax + by = gcd(a, b)
  37. ྫ) gcd(1732, 194) = 2 1732 = 8 ⋅ 194

    + 180 194 = 1 ⋅ 180 + 14 180 = 12 ⋅ 14 + 12 14 = 1 ⋅ 12 + 2 12 = 6 ⋅ 2 + 0
  38. ྫ) gcd(1732, 194) = 2 2 = 14 − 1

    ⋅ 12 = 14 − 1 ⋅ (180 − 12 ⋅ 14) = −1 ⋅ 180 + 13 ⋅ 14 = −1 ⋅ 180 + 13 ⋅ (194 − 1 ⋅ 180) = 13 ⋅ 194 − 14 ⋅ 180 = 13 ⋅ 194 − 14 ⋅ (1732 − 8 ⋅ 194) = −14 ⋅ 1732 + 125 ⋅ 194 x y → ͜ͷΞϧΰϦζϜ΋ <R: EuclideanRing> ʹର͢Δ ɹ δΣωϦοΫͳؔ਺ extGcd ͱ࣮ͯ͠૷Ͱ͖Δɽ
  39. ࣌ܭͷੈքͷ੔਺ • ʮ࣌ܭͷੈքͷ੔਺ʯ͸ɼपظ n Λݻఆ͢Δ͝ͱʹ࡞ΕΔɽ • ੔਺ a, b ʹରͯ͠ɼͦΕΒΛ

    n Ͱׂͬͨ༨Γ͕౳͍࣌͠ʹ ʮn ࣌ؒ࣌ܭʯͷதͰ͸౳͍͠ͱݟͳ͢ɽ͜ͷੈքʹ͸શ෦ Ͱ n ݸ͔͠਺͕ͳ͍ɽ • ʮn ࣌ؒ࣌ܭʯͷதͰ΋଍͠ࢉͱֻ͚ࢉ͕Ͱ͖ͯ؀Λͳ͢ɽ ͜ͷ؀Λ Z/n ͱॻ͘ʢਖ਼ࣜʹ͸ ੔਺ͷ৒༨ྨ؀ ͱ͍͏ʣ
  40. Z/n ͷ࣮૷ struct Z<n: _Int>: Ring { let value: Int

    init(_ value: Int) { self.value = value } static func ==(a: Z<n>, b: Z<n>) -> Bool { return (a.value - b.value) % n.intValue == 0 } static func + (a: Z<n>, b: Z<n>) -> Z<n> { return Z<n>(a.value + b.value) } …
  41. Z/n ͷׂΓࢉ͸ʁ • Z/n ͰׂΓࢉ͸Ͱ͖ΔͩΖ͏͔ʁ → Z/n ͷ 0 Ͱͳ͍ݩ

    a ʹରͯ͠ɼͦͷٯ਺͸औΕΔͩΖ͏͔ʁ → n ͷഒ਺Ͱͳ͍ ੔਺ a ʹରͯ͠ɼax ≡ 1 (mod n) ͱͳΔ੔਺ x Λݟ͚͍ͭͨɽ
  42. n = 5 ͷ৔߹ * | 0 1 2 3

    4 -------------------------- 0 | 0 0 0 0 0 1 | 0 1 2 3 4 2 | 0 2 4 1 3 3 | 0 3 1 4 2 4 | 0 4 3 2 1 Z/5 ͷ৐ࢉද
  43. n = 5 ͷ৔߹ * | 0 1 2 3

    4 -------------------------- 0 | 0 0 0 0 0 1 | 0 1 2 3 4 2 | 0 2 4 1 3 3 | 0 3 1 4 2 4 | 0 4 3 2 1 Z/5 ͷ৐ࢉද 0 Ͱͳ͍਺͸ٯ਺Λ࣋ͭ
  44. n = 6 ͷ৔߹ * | 0 1 2 3

    4 5 ------------------------------ 0 | 0 0 0 0 0 0 1 | 0 1 2 3 4 5 2 | 0 2 4 0 2 4 3 | 0 3 0 3 0 3 4 | 0 4 2 0 4 2 5 | 0 5 4 3 2 1 Z/6 ͷ৐ࢉද
  45. n = 6 ͷ৔߹ * | 0 1 2 3

    4 5 ------------------------------ 0 | 0 0 0 0 0 0 1 | 0 1 2 3 4 5 2 | 0 2 4 0 2 4 3 | 0 3 0 3 0 3 4 | 0 4 2 0 4 2 5 | 0 5 4 3 2 1 Z/6 ͷ৐ࢉද
  46. n = 6 ͷ৔߹ * | 0 1 2 3

    4 5 ------------------------------ 0 | 0 0 0 0 0 0 1 | 0 1 2 3 4 5 2 | 0 2 4 0 2 4 3 | 0 3 0 3 0 3 4 | 0 4 2 0 4 2 5 | 0 5 4 3 2 1 Z/6 ͷ৐ࢉද ٯ਺Λ࣋ͨͳ͍ʂ
  47. n = 7 ͷ৔߹ * | 0 1 2 3

    4 5 6 ---------------------------------- 0 | 0 0 0 0 0 0 0 1 | 0 1 2 3 4 5 6 2 | 0 2 4 6 1 3 5 3 | 0 3 6 2 5 1 4 4 | 0 4 1 5 2 6 3 5 | 0 5 3 1 6 4 2 6 | 0 6 5 4 3 2 1 Z/7 ͷ৐ࢉද
  48. n = 7 ͷ৔߹ * | 0 1 2 3

    4 5 6 ---------------------------------- 0 | 0 0 0 0 0 0 0 1 | 0 1 2 3 4 5 6 2 | 0 2 4 6 1 3 5 3 | 0 3 6 2 5 1 4 4 | 0 4 1 5 2 6 3 5 | 0 5 3 1 6 4 2 6 | 0 6 5 4 3 2 1 Z/7 ͷ৐ࢉද
  49. n = 8 ͷ৔߹ * | 0 1 2 3

    4 5 6 7 -------------------------------------- 0 | 0 0 0 0 0 0 0 0 1 | 0 1 2 3 4 5 6 7 2 | 0 2 4 6 0 2 4 6 3 | 0 3 6 1 4 7 2 5 4 | 0 4 0 4 0 4 0 4 5 | 0 5 2 7 4 1 6 3 6 | 0 6 4 2 0 6 4 2 7 | 0 7 6 5 4 3 2 1 Z/8 ͷ৐ࢉද
  50. n = 8 ͷ৔߹ * | 0 1 2 3

    4 5 6 7 -------------------------------------- 0 | 0 0 0 0 0 0 0 0 1 | 0 1 2 3 4 5 6 7 2 | 0 2 4 6 0 2 4 6 3 | 0 3 6 1 4 7 2 5 4 | 0 4 0 4 0 4 0 4 5 | 0 5 2 7 4 1 6 3 6 | 0 6 4 2 0 6 4 2 7 | 0 7 6 5 4 3 2 1 Z/8 ͷ৐ࢉද
  51. n = 8 ͷ৔߹ * | 0 1 2 3

    4 5 6 7 -------------------------------------- 0 | 0 0 0 0 0 0 0 0 1 | 0 1 2 3 4 5 6 7 2 | 0 2 4 6 0 2 4 6 3 | 0 3 6 1 4 7 2 5 4 | 0 4 0 4 0 4 0 4 5 | 0 5 2 7 4 1 6 3 6 | 0 6 4 2 0 6 4 2 7 | 0 7 6 5 4 3 2 1 Z/8 ͷ৐ࢉද ٯ਺Λ࣋ͨͳ͍ʂ
  52. Z/n ͷݩ͕ٯ਺Λ࣋ͭ৚݅ • ࣮͸ a ͱ n ͕ ޓ͍ʹૉɼͭ·Γ ͷͱ͖ɼa

    ͸ Z/ n ͷதͰٯ਺Λ࣋ͭɽͳͥͳΒ֦ுϢʔΫϦουޓআ๏ʹΑΓ ͳΔ x, y Λݟ͚ͭΔ͜ͱ͕Ͱ͖ɼ Ͱ͸ ͱͳΔ͔Βɽ͜ͷ x ͕ Z/n ͷதͰ a ͷٯ਺Λ༩͑Δɽ gcd(a, n) = 1 ax + ny = 1 mod n ax ≡ 1
  53. struct Z<n: _Int>: Ring { let value: Int … var

    inverse: Z<n>? { let (gcd, x, y) = extGcd(value, n.intValue) return (gcd == 1) ? Z<n>(x) : nil } } Z/n ʹ͓͚Δٯ਺ͷ࣮૷
  54. ༗ݶମ #Fp • ಛʹ n ͱͯ͠ૉ਺ p ΛऔΕ͹ɼp ͷഒ਺Ͱͳ͍ શͯͷ੔਺

    a ͸ p ͱޓ͍ʹૉɽ͕ͨͬͯ͠ Z/p ͷ೚ҙͷ 0 Ͱͳ͍ݩ a ͸ɼZ/p ͷதͰٯ਺Λ࣋ͭɽͭ·Γ Z/p ͸ମʂ • Z/p ͕ମͰ͋Δ͜ͱΛڧௐͯ͠ ͱॻ͘ɽ ͸༗ཧ਺ମ ΍࣮਺ମ ͱҟͳΓɼ༗ݶݸͷݩ͔࣋ͨ͠ͳ͍ɽ ಛʹ ͸ 2ݩू߹Ͱɼཧ࿦্΋Ԡ༻্΋ॏཁɽ • ͯ͞ɼ্ͷ਺ֶతࣄ࣮ΛίʔυͰ࣮ݱ͢Δʹ͸ʁ Fp Fp Q R F2 = {0, 1}
  55. protocol _Int { … } protocol _Prime: _Int {} extension

    _2: _Prime {} extension _3: _Prime {} extension _5: _Prime {} extension _7: _Prime {} extension _11: _Prime {} … extension Z: Field where n: _Prime {} typealias F<p: _Prime> = Z<p> • ͜ΕͰΑ͠ • ʢSwiftyMath Ͱ͸ IntegerQuotientRing<n> ͱ࣮ͯ͠૷ʣ
  56. ଟ߲ࣜͷ৒༨ྨ؀ • ੔਺؀ʹରͯ͠΍ͬͨͷͱશ͘ಉ͡ํ๏Ͱɼଟ߲ࣜ؀ʹରͯ͠ ΋৒༨ྨ؀͕࡞ΕΔɽ • ମ F ্ͷଟ߲ࣜ p(x) ΛऔΓʮp(x)

    Ͱׂͬͨ༨Γʯ͚ͩΛݟΔ͜ ͱͰɼ p(x) Λ๏ͱͨ͠ଟ߲ࣜͷ଍͠ࢉͱׂΓࢉ͕ఆٛͰ͖Δɽ • ͜ΕΛଟ߲ࣜ؀ F[x] ͷ৒༨ྨ؀ͱݺͼɼF[x]/p(x) ͱॻ͘ɽ p(x) ≡ 0 f(x) ≡ f(x) + p(x) p(x) 0 F[x] F[x]/p(x)
  57. F[x]/p(x) ͕ମʹͳΔ৚݅͸ʁ • Z/p ͸ p ͕ૉ਺ ͷͱ͖ʹମͱͳΔͷͰ͋ͬͨɽଟ߲ࣜʹର ͯ͠΋ “ૉ਺”

    ͷΑ͏ͳ֓೦͸͋Δ͔ʁ → YESʂ • ଟ߲ࣜ p(x) ͕ɼ • ͱॻ͚Δͱ͖ɼp(x) ͸ Մ໿ Ͱ͋Δͱ͍͍ɼՄ໿Ͱͳ͍ͱ͖ ط໿ ͱ͍͏ʢ੔਺ͷ߹੒਺ɾૉ਺ͷఆٛͱಉ͡ܗʂʣ p(x) = f(x) ⋅ g(x) (deg f, deg g > 0)
  58. F[x]/p(x) ͕ମʹͳΔ৚݅͸ʁ • ଟ߲ࣜ p(x) ͕ط໿Ͱ͋Δͱ͢Δɽp(x) ͷഒ਺Ͱͳ͍೚ҙͷ f(x) ʹରͯ͠ɼ֦ுϢʔΫϦουͷޓআ๏͔Βɼ ͳΔଟ߲ࣜ

    g(x), k(x) ͕ଘࡏ͠ɼ Ͱ͸ ͱͳΔɽ͜ͷ g(x) ͕ F[x]/p(x) ͷதͰ f(x) ͷٯ਺Λ༩͑Δʂ f(x)g(x) + p(x)k(x) = 1 mod p(x) f(x)g(x) ≡ 1
  59. ྫ) • Λߟ͑Α͏ɽ • ͸࣮਺܎਺ଟ߲ࣜͱͯ͠͸ ͱՄ ໿Ͱ͋Δ͕ɼ༗ཧ਺܎਺ͱͯ͠͸Մ໿Ͱͳ͍ɽैͬͯ ͸ମͱͳΔɽ • ྫ͑͹

    ͸ ͷഒ਺Ͱ͸ͳ͍ͷͰɼ ͷத Ͱٯ਺Λ࣋ͪɼ Ͱ༩͑ΒΕΔɽ࣮ࡍɼ Ͱ͔֬ʹٯ਺ͱͳ͍ͬͯΔʂ F = Q, p(x) = x2 − 2 p(x) p(x) = (x − 2)(x + 2) Q[x]/p(x) f(x) = x + 1 p(x) Q[x]/p(x) g(x) = x − 1 f(x)g(x) = x2 − 1 ≡ x2 − 1 − (x2 − 2) = 1 mod p(x)
  60. F[x]/p(x) ͷ࣮૷ protocol _Polynomial { associatedtype F: Field static var

    value: Polynomial<F> { get } } protocol _IrrPolynomial: _Polynomial { } struct PolynomialQuotientRing<p: _Polynomial>: Ring { typealias F = p.F let value: Polynomial<p.F> … } extension PolynomialQuotientRing: Field where p: _IrrPolynomial { } • ੔਺ͷ৔߹ͱಉ༷ʹଟ߲ࣜΛܕͱͯ࣋ͯ͠ΔΑ͏ʹͯ͠ɼ৒༨ྨ؀ܕΛ࡞Δɽ • ಛʹଟ߲͕ࣜط໿Ͱ͋Δ৔߹ʹɼ৒༨ྨ؀͸ମͰ͋Δͱએݴ͢Δɽ
  61. ୅਺֦େ • ࣮͸ F[x]/p(x) Λ࡞Δखଓ͖ʹΑͬͯɼମ F ʹ “৽͍͠਺” Λ෇ ͚Ճ͑ͯʮΑΓେ͖ͳମʯΛߏ੒͢Δ͜ͱ͕Ͱ͖Δɽ

    • ઌ΄Ͳͷ ͷྫͰ͸ɼ࣮͸ Λ࡞ͬ ͍ͯͨɽ ͷଟ߲ࣜ ͸ɼ Λຬͨ͢ͷͰɼ ʹ͓͍ͯ͸ ͱ͍͏͜ͱɽ F = Q, p(x) = x2 − 2 2 F[x] x x2 ≡ x2 − (x2 − 2) = 2 mod p(x) F[x]/p(x) x = 2
  62. ୅਺֦େ • ࠓ౓͸ Λߟ͑ͯΈΑ͏ɽ ͷଟ߲ࣜ ͸ɼ Λຬͨ͢ͷͰɼ ʹ͓͍ͯ ͸ڏ਺୯Ґ ɽ

    • ମ ʹڏ਺୯Ґ ΛఴՃͯ͠ɼෳૉ਺ମ ͕࡞Εͨʂ F = R, p(x) = x2 + 1 F[x] x x2 ≡ x2 − (x2 + 1) = − 1 mod p(x) F[x]/p(x) x i R i C C = R[x]/(x2 + 1)
  63. (ൃల) ୅਺త਺ͱ௒ӽ਺ • ҰൠʹɼF[x]/p(x) ͸ ମ F ʹ p(x) ͷ

    ࠜ ΛఴՃͨ͠ମͱͳΔɽ • ͸ ͷࠜɼ ͸ ͷࠜͰ͋ͬͨɽ • F ্ͷଟ߲ࣜͷࠜͱͳΔ਺Λ F ͷ ୅਺త਺ ͱ͍͏ɽ୅਺త਺͸୅਺֦ େʹΑͬͯߏ੒Ͱ͖Δʢίϯϐϡʔλ্Ͱ΋࣮ݱͰ͖Δʣ • ୅਺త਺Ͱͳ͍਺Λ ௒ӽ਺ ͱ͍͏ɽ ΍ ͸ ্௒ӽతɽ௒ӽ਺͸ ୅਺֦େʹΑͬͯ͸࡞Εͳ͍ɽ • ίϯϐϡʔλ͔ΒݟΕ͹ “ڏ਺” ΑΓ΋ “࣮਺” Ͱ͋Δ ΍ ͷํ͕ Α΄Ͳ imaginary ʹݟ͑Δ… 2 x2 − 2 i x2 + 1 π e Q i π e
  64. ݱࡏͷݚڀ • ๻͸ʮ௿࣍ݩτϙϩδʔʯͷݚڀΛίϯϐϡʔλΛ࢖ͬ ͯߦ͏͜ͱʹऔΓ૊ΜͰ͍·͢ɽ • म࢜՝ఔͰ͸݁ͼ໨ͷ Khovanov homology ͷݚڀΛ͠· ͨ͠ɽݱࡏ͸ϙευΫݚڀһͱڞಉͰɼ݁ͼ໨ͷ

    Grid homology ʹؔ͢ΔݚڀΛߦ͍ͬͯ·͢ɽ • ༗ݶମ্ͷߦྻܭࢉϥΠϒϥϦΛ SwiftyMath ʹ૊ΈࠐΜ Ͱɼ਺ेສ × ਺ेສن໛ͷߦྻܭࢉΛ GCP Ͱճ͍ͯ͠· ͢✊
  65. ࠓޙͷల๬ • ʮ਺ֶ͸ϓϩάϥϛϯάͷ໾ʹཱͭʯͱΑ͘ݴΘΕΔ͕ɼ๻͸ϓ ϩάϥϛϯάΛ਺ֶͷ໾ʹཱ͍ͯͨʢͦ͜ʹ೩͑Δʣɽ • ਺ֶ͸ͱͯ΋೉͍͕͠ɼϓϩάϥϛϯά͕Ͱ͖Δ͜ͱ͸ɼ਺ֶΛ ֶͿ্Ͱ΋ݚڀ͢Δ্Ͱ΋ڧΈʹͳΔʂ • Swift ͸਺ֶʹ޲͍͍ͯΔʂ

    Python ΑΓ΋ݎ͘ɼHaskell ΑΓ΋ ॊೈɽ਺ֶతه๏ʹدΓఴͬͨॻ͖ํ͕Ͱ͖ΔɽͰ΋ݚڀऀք۾ Ͱ͸͔ͳΓϚΠφʔͳݴޠ… • ਎ۙͳ஥ؒΛ૿΍͍ͨ͠ʂ SwiftyMath ʹ contribute ͯ͘͠ΕΔਓ ͓଴ͪͯ͠·͢