はじめに
プログラムでlog(-1)と書くと、NaN(非数)が返されます。自分のプログラムでは、0のように扱われていたので、このことに無頓着であまり気にしていませんでした。よくよく調べると、log(-1)は実数では存在せず、虚数なら存在するということを知ったので、いろいろ試した結果のまとめです。
オイラーの公式
e^iθ = cosθ + i sinθ
から
e^iπ = -1
となり両辺の対数をとって
log(-1)=log(e^iπ)
が得られます。
log(e^iπ)は当然iπなので
log(-1)=iπ
負の対数は、虚数となることが確認できます。
googleの検索ボックスに「log(-1)/log(e)」と入力すると「3.14159265 i」と答えが返ってくることからgoogleは複素数を扱えるようです。なおgoogleのlogは底が10なので、式変形して使ってます。
多価関数
さて、この複素数の振る舞いがよくわかりません。
log(-1) = πi
log(-2) = 0.693147181 + πi
log(-3) = 1.09861229 + πi
log(-4) = 1.38629436 + πi
いろいろな数値を入れても、法則性が見いだせませんでした。
そこで、逆に
log(X) = x + yi
のx,yに任意の値を入れて、振る舞いを確認しました。
すると
log(-1) = -3πi
log(-1) = -πi
log(-1) = πi
log(-1) = 3πi
に気がつき、多価関数と呼ばれることや、リーマン面について、知ることができました。
arcsinθが多値を持つことと、同じです。
log(z)複素数の対数
プログラムで、複素数を扱うのに、pythonが便利そうなので、環境を整えます。
pythonは初めてなので、googleのcolabから使い始めましたが、すぐに限界が来たので、やめました。オフライン実行環境を探しましたが、最終的に、processing.pyに行きつきました。
複素数ライブラリcmathには、複素数の関数も用意されており、logに複素数を渡せることに気がつきました。前の疑問に立ち戻り、どんな複素数を対数に渡せば、どんな複素数になるか、という疑問を解決させます。つまり、どんな写像になっているかという疑問です。
環境
Processing.py(3063)
math, cmathライブラリ
結果
グリッド間隔は1です。
(-1-1i)〜(1+1i)の範囲の複素数が、どこに写像されるかを示した図です。
色々な範囲で試した結果、πiよりも大きくなることはなく、-πiよりも小さくなることはありませんでした。arcsinのように(-π<θ<π)で返されるのだと思います。というわけで、写像の図としては、上下にも永遠に繋がっていると言えます。
また、元の複素数の範囲を変えると、実軸方向に全体的にスライドしました。
魚の鱗のような、イメージでしょうか。ちょっとずつズレながら、全体を埋めるような。
コード
import math
import cmath
size(512, 512)
background(255)
z = 0 + 1j
# z -= 1j
print(z)
print(cmath.log(z))
translate(width / 2, height / 2)
scale(50)
strokeWeight(1 / 50.0)
# grid
stroke(200)
for x in range(-5, 6):
line(x, -height, x, height)
for y in range(-5, 6):
line(-width, y, width, y)
#######
strokeWeight(1 / 25.0)
colorMode(HSB,360,100,100)
for y in range(256):
for x in range(256):
re = map(x, 0, 256, -1, 1)
im = map(y, 0, 256, -1, 1)
if re == 0 and im == 0:
break
z = complex(re, im)
th = math.degrees(cmath.phase(z)+PI)
_z = cmath.log(z)
stroke(th, 100, 100)
point(_z.real, _z.imag)
sqrt平方根の写像
同様に、平方根についても確認しました。
√-1 = i
√i = √2/2+√2/2i
√4i = √2+√2i
√(1+i) = 1.09868411347+0.455089860562i
グリッド間隔は1です。
(-1-1i)〜(1+1i)の範囲の複素数が、どこに写像されるかを示した図です。
曲座標っぽくなる
(-4-4i)〜(4+4i)の範囲の複素数が、どこに写像されるかを示した図です。
4倍にすると、2倍になりました。
コード
import math
import cmath
size(512, 512)
background(255)
z = 0 + 1j
# z -= 1j
print(z)
print(cmath.sqrt(z))
translate(width / 2, height / 2)
scale(100)
strokeWeight(1 / 100.0)
# grid
stroke(200)
for x in range(-5, 6):
line(x, -height, x, height)
for y in range(-5, 6):
line(-width, y, width, y)
#######
strokeWeight(1 / 100.0)
colorMode(HSB,360,100,100)
for y in range(1024):
for x in range(1024):
re = map(x, 0, 1024, -1, 1)
im = map(y, 0, 1024, -1, 1)
if re == 0 and im == 0:
break
z = complex(re, im)
th = math.degrees(cmath.phase(z)+PI)
_z = cmath.sqrt(z)
stroke(th, 100, 100)
point(_z.real, _z.imag)