swtws 数学のやつ

1
さのたけと @taketo1024

「Swift で √2 を作ろう」で発表します、よろしくお願いします。 9/16 に iOSDC で発表した「Swift で数学のススメ」のコードレベルの解説をします。数学に自信がない方でも「コードで数学を作る」楽しさを感じて頂ければ幸いです。 #swtws

2017-10-21 21:37:34
さのたけと @taketo1024

話の大まかな流れは以下の通りです: 1. 群・環・体の定義と実装 2. 整数と多項式の類似 3. 代数拡大で √2 を作る #swtws

2017-10-21 21:38:04
さのたけと @taketo1024

皆さんは数、ベクトル、行列、関数など数学で扱う様々な「モノ」を知っていると思います。これらには同じモノ同士で + や × などの「演算」が定められています。「同じモノたちの集まり」とそこに定められた「演算」を合わせて「代数構造」と言います。 #swtws

2017-10-21 21:38:34
さのたけと @taketo1024

群・環・体は、色々なモノたちの代数構造を抽象化した概念です。群は加法群に限定することとして、それぞれ以下の演算が定まっていることを要請します: ・加法群:(+,-) ・環:(+,-,×) ・体:(+,-,×,÷) 下に行くほど要請が強くなっています。 #swtws

2017-10-21 21:39:04
さのたけと @taketo1024

これらの要請を「公理」と言います。Swift で言えば protocol のことです。以下のような対応を考えると分かりやすいと思います。 公理 ⇄ protocol 公理を満たす集合 ⇄ struct 集合の要素 ⇄ instance #swtws

2017-10-21 21:39:35
さのたけと @taketo1024

まず「加法群」とは 1. 足し算ができる 2. ゼロがある 3. 全ての元に和の逆元がある の三つを要請します。protocol を書いてみましょう。 #swtws gist.github.com/c21d7af17d6a01… pic.twitter.com/uzYA9lxyK2

2017-10-21 21:40:04
拡大
さのたけと @taketo1024

「ゼロ」とは「和に関する単位元」のことで、足しても変わらない特別な要素のことです。数であれば普通のゼロ、ベクトルならゼロベクトル、行列ならゼロ行列です。 これは集合に対して一つ定まる要素なので、static で宣言しています。 #swtws

2017-10-21 21:40:34
さのたけと @taketo1024

a の逆元は、足してゼロになる要素で -a と書きます。こちらは各要素に対して定まるものなので、 instance var として宣言しています。 #swtws

2017-10-21 21:41:07
さのたけと @taketo1024

上の要請には「引き算」は入っていませんが a - b = a + (-b) なので protocol extension として実装することができます。 #swtws gist.github.com/ab9d025c6f82a4… pic.twitter.com/mVNg3BYBoI

2017-10-21 21:41:37
拡大
さのたけと @taketo1024

ここに早くも抽象化によるメリットがあります。 AdditiveGroup に適合する型は、三つの要請さえ満たしていれば「引き算」は自動でついてくるということになります(この先こういうことをどんどんやります)。 #swtws

2017-10-21 21:42:07
さのたけと @taketo1024

ちなみに「加法群」の定義としては上では不十分で + の結合性 (a + b) + c == a + (b + c) や可換性 a + b == b + a も必要です。これらを protocol に入れることはできないので適合する型の責任としておきます(以後同様)。 #swtws

2017-10-21 21:42:37
さのたけと @taketo1024

次は「環」です。環は加法群の要請に加えて、 4. 掛け算ができる 5. 積の単位元がある を要請します。 AdditiveGroup はすでにあるので、その subprotocol として定義すれば OK です。 #swtws gist.github.com/8567ccc6433575… pic.twitter.com/J04pB49TjO

2017-10-21 21:43:07
拡大
さのたけと @taketo1024

「積の単位元」とは掛けても変わらない特別な要素で 1 に対応する要素です。環では「積の逆元」は要請されていないことに注意して下さい。 #swtws

2017-10-21 21:43:37
さのたけと @taketo1024

整数や実数は環です。「n次正方行列全体」も環になります。演算は行列の和と積で、 zero はゼロ行列、identity は単位行列です。 #swtws

2017-10-21 21:44:10
さのたけと @taketo1024

最後に「体」は、環の要請に加えて、 6. 0 以外の元は「積の逆元」を持つ を要請します。これを Ring の subprotocol として定めます。また extension で割り算も実装できます。 #swtws gist.github.com/1a3b73eda1dacd… pic.twitter.com/UbpXoVXI5G

2017-10-21 21:44:43
拡大
さのたけと @taketo1024

こうして四則演算のできる代数構造 Field 型が定義できました! 実数はもちろん体ですが、整数は脱落します。なぜでしょう? #swtws

2017-10-21 21:45:15
さのたけと @taketo1024

整数が体でないのは、例えば 2 は整数の中では逆元を持たないからです( 1/2 は整数ではない!) 同様に一般の正方行列は逆行列を持たないことから、正方行列も体でないことがわかります。 #swtws

2017-10-21 21:45:45
Kosuke Ogawa⛅エンジニア🏝宮崎 @koogawa

#swtws Ownership の大きな3つの機能 1. 値アクセスの排他則 2. shared参照 3. コピー不可能な値型

2017-10-21 21:46:11
さのたけと @taketo1024

さて、 Int 型を整数、Double 型を実数として、 Ring / Field に適合させるのは簡単です。すでにあるものを extend して、足りないものだけ埋めればいいのです(Swift の面白いところ!) #swtws gist.github.com/9d76ea988b48c7… pic.twitter.com/LmUeI6Kx4B

2017-10-21 21:46:15
拡大
さのたけと @taketo1024

整数(Int) と 実数(≒Double)の間に、整数の比で表される「有理数」があります。有理数も四則演算について閉じていることから体であることが分かります。実装は分子・分母を表す二つの整数 p, q をとって… #swtws gist.github.com/338d0f7fe9b5bf… pic.twitter.com/ESoLq4XtY1

2017-10-21 21:46:45
拡大
さのたけと @taketo1024

有理数の足し算や掛け算は小学校で習った通りに実装します。和と積の逆元を入れておけば、引き算と割り算は protocol extension によって自動で入ります👍 #swtws gist.github.com/9db17e63c114de… pic.twitter.com/kUqb33bRQm

2017-10-21 21:47:15
拡大
さのたけと @taketo1024

(練習問題) 複素数も四則演算のできる体となります。有理数と同様に実装してみましょう。 #swtws

2017-10-21 21:47:45
さのたけと @taketo1024

群・環・体の定義から、対応する protocol を実装し struct として適合する型を実装しました。以下の対応が見えるようになりましたか? 公理 ⇄ protocol 公理を満たす集合 ⇄ struct 集合の要素 ⇄ instance #swtws

2017-10-21 21:48:15
さのたけと @taketo1024

次は「多項式環」(Polynomial Ring) を作ります。多項式とは 1次式 ax + b, 2次式 ax^2 + bx + c を一般化したもので、その全体は環を成します。 #swtws pic.twitter.com/IJTkevsq2P

2017-10-21 21:48:45
拡大
さのたけと @taketo1024

多項式は次数と x^n たちの係数の列で決まります。ここで係数は実数だけでなく一般の体にできるように generic にしておきましょう。 #swtws gist.github.com/f67d6bea5fa7b2… pic.twitter.com/2yP6tvN49g

2017-10-21 21:49:15
拡大