More Related Content Similar to 虚数は作れる!Swift で学ぶ複素数 Similar to 虚数は作れる!Swift で学ぶ複素数 (20) More from Taketo Sano (20) 虚数は作れる!Swift で学ぶ複素数3. 学校で習うとき
i = p−1
z = a + bi
1. 虚数単位 i = √-1 がいきなり出てくる
2. 複素数 z = a + bi の四則演算が定義される
3. 「数」と思っていた z
z がベクトルになってる
4. 「i i
をかけるのは90度回転です」などと教わる
5. 以後当たり前のように電流や波の方程式に出てくる
10. ✓
x
y
2
z =
2
3
◆
3
let z = Complex(2, 3)
11. イコールを定義
struct Complex: Equatable {
…
}
!
func == (a: Complex, b: Complex) - Bool {
return (a.x == b.x) (a.y == b.y)
}
12. 足し算・引き算・実数倍を定義
func + (z: Complex, w: Complex) - Complex {
return Complex(z.x + w.x, z.y + w.y)
}
!
prefix func -(z: Complex) - Complex {
return Complex(-z.x, -z.y);
}
!
func - (z: Complex, z: Complex) - Complex {
return Complex(z.x - w.x, z.y - w.y)
}
!
func * (a: Double, z: Complex) - Complex {
return Complex(a * z.x, a * z.y)
}
13. 次に1 1 = =
(1, 0), i = (0, 1) として、
z = x + yi の形で書けるようにする。
✓
1
0
◆
i =
✓
0
1
◆
z = a + bi
14. まず Double から生成できるようにする
struct Complex: …, FloatLiteralConvertible {
…
static func convertFromFloatLiteral(value:
FloatLiteralType) - Complex {
!
return Complex(value, 0)
}
}
let z: Complex = 2.0 // Complex(2.0, 0)
15. Int についてもやっておく
struct Complex: …, IntegerLiteralConvertible {
…
static func convertFromIntegerLiteral(value:
IntegerLiteralType) - Complex {
!
return Complex(Double(value), 0)
}
}
let z: Complex = -1 // Complex(-1, 0)
17. あとは 定数 i を定義すれば…
i
x
y
i =
✓
0
1
◆
let i = Complex(0, 1)
18. 求めていた表現を得る!
x
y
2 =
✓
2
0
◆
let z = 2 + 3 * i
3i =
✓
0
3
◆ z =
✓
2
3
◆
= 2+3i
21. z z = = a a + + bi, bi,w w = = c c + + di di
として、積 zw が定義
できるとすれば、
zw = (a + bi)(c + di)
= a(c + di) + bi(c + di)
分配法則
= ac + adi + bci + bdi2
= ac + adi + bci bd
分配法則
= ac bd + adi + bci
交換法則
= (ac bd) + (ad + bc)i
分配法則
とするしかない。
zw
i2 = 1
23. ちゃんと「掛け算の要件」を満たしている!
let α = 3 + 5 * i
let β = -1 + 4 * i
let γ = 4 - 7 * i
!
α * 1 == α // 1は単位元
α * β == β * α // 交換法則
(α * β) * γ == α * (β * γ) // 結合法則
α * (β + γ) == α * β + α * γ // 分配法則
当たり前に見えるが、テキトーに定義したのではこうならない。
これで安心して「数」として扱えるようになる。
24. i * i == -1 // true
YES!
25. 割り算も逆数との積で定義
struct Complex { … }
!
func / (z: Complex, w: Complex) - Complex {
let w_inv = Complex(w.x / (w.x * w.x + w.y * w.y),
-w.y / (w.x * w.x + w.y * w.y))
return z * w_inv
}
26. 複素数、できました!
struct Complex: Equatable, IntegerLiteralConvertible, FloatLiteralConvertible {
let x: Double
let y: Double
init(_ x: Double, _ y: Double) {
self.x = x
self.y = y
}
static func convertFromIntegerLiteral(value: IntegerLiteralType) - Complex {
return Complex(Double(value), 0)
}
static func convertFromFloatLiteral(value: FloatLiteralType) - Complex {
return Complex(value, 0)
}
} !
func == (z: Complex, w: Complex) - Bool {
return z.x == w.x z.y == w.y
} !
func + (z: Complex, w: Complex) - Complex {
return Complex(z.x + w.x, z.y + w.y)
} !
prefix func -(z: Complex) - Complex {
return Complex(-z.x, -z.y);
} !
func - (z: Complex, w: Complex) - Complex {
return Complex(z.x - w.x, z.y - w.y)
} !
func * (z: Complex, w: Complex) - Complex {
return Complex(z.x * w.x - z.y * w.y, z.x * w.y + z.y * w.x)
} !
func / (z: Complex, w: Complex) - Complex {
let w_inv = Complex(w.x / (w.x * w.x + w.y * w.y), -w.y / (w.x * w.x + w.y * w.y))
return z * w_inv
} !
let i = Complex(0, -1)
30. 複素数 z
z に対して、
絶対値 r = |z|, 偏角 θ= arg(z) が定義できる
Re
r = |z| ✓ = arg(z)
Im
r
✓
z
31. 実装しときましょう
func abs(z: Complex) - Double {
return sqrt(z.x * z.x + z.y * z.y)
}
!
func arg(z: Complex) - Double {
let r = abs(z)
if(r == 0) {
return 0
}
let t = acos(z.x / r)
return (z.y = 0) ? t : 2 * M_PI - t
}
33. 実装しときましょう
struct Complex: … {
let x: Double
let y: Double
init(_ x: Double, _ y: Double) {
self.x = x
self.y = y
}
init(r: Double, θ: Double) {
self.x = r * cos(θ)
self.y = r * sin(θ)
}
!
…
}
35. z = r(cos✓ + isin✓), w = s(cos + isin)
zw = rs{(cos✓cos sin✓sin) + i(sin✓cos + cos✓sin)}
= cos(✓ + ) = sin(✓ + )
= rs(cos(✓ + ) + isin(✓ + ))
に対して、
つまり…、
38. class ComplexPlane : UIView {
!
var unit: CGFloat = 50.0
var scale: CGFloat = 1.0
var points: [String: Complex] = [:]
var colors: [String: UIColor] = [:]
subscript(name: String) - (Complex!, UIColor!) {
get {
return (points[name], colors[name])
}
set(value) {
points[name] = value.0
colors[name] = value.1
}
}
override func drawRect(rect: CGRect) {
…
}
}
39. let cplane = ComplexPlane(frame: …)
cplane.scale = 2.0
!
cplane[1] = (1, nil)
cplane[i] = (i, nil)
!
let z = Complex(r: 2, θ: M_PI / 3)
cplane[z] = (z, UIColor.redColor())
!
let w = z * z
cplane[w] = (w, UIColor.blueColor())
!
cplane.setNeedsDisplay()
cplane
43. (例) 方程式: x^x2 2 + + x x + + 1 1 = = 0
0
5
2.5
-10 -7.5 -5 -2.5 0 2.5 5 7.5 10
-2.5
この方程式は実数の範囲では解を持たない。
-5
y = x2 + x + 1
44. 形式的に2方程式の解の公式を使うと、
x = −1 ± p12 − 4 · 1 · 1
p−3 p3i
ここで √-3 を √3 i と置き換えて:
は、x^x2 2 + + x x + + 1 1 = = 0
0 の解になっている。
2
= −1 ± p−3
2
↵ = −1 + p3i
2
, = −1 − p3i
2
45. yy == xx^22 ++ xx ++ 11 は xx == α↵, ,β で x 軸と交わっている…?
5
2.5
-10 -7.5 -5 -2.5 0 2.5 5 7.5 10
-2.5
-5
y = x2 + x + 1
↵? ?
x, y を複素数と見てグラフを描くには、
残念ながら我々の世界では次元が1つ足りない。
46. 代わりに、
Re
Im
Re
Im
z
w
f
w w = = f(z) f(z) = = z^z2 2 + + z z + + 1
1 を平面から平面への写像と見て、
zz の動きにあわせて ww がどう動くか見てみる。
48. Re
Im
Re
Im
z w
zz を半径を大きくしながら円上で動かす。
49. Re
Im
Re
Im
z w
半径 1 のときに ww == 00 となる点が2つある。
50. Re
Im
Re
Im
↵
z w
↵ = −1 + p3i
2
, = −1 − p3i
2
この2点が α↵,, β で、ff によって 0 に写されていた。
53. f(z) = anzn + ... + a1z + a0
は平面全体をちょうどn重に覆う写像になる。
w = z3 + z2 2z + 1
一般に
特に 0 に移る z も n 個あることになるので…
57. 次回予告(?)
• e, e, π, ⇡, i
i の饗宴 ~ Swift で学ぶオイラーの公式
• 無限遠を一点に ~ SceneKit で作るリーマン球面