はじめに
数学を利用したいのであれば、公式を丸覚えしたところでなんの足しにもならない。それは理解の拒絶であり、文字列として記憶しているだけだ。だが、理解するのが難しい場合も多いだろう。そういった時、私はpythonコードとして動かしながら何が起こっているかを確認しつつ理解している。本稿は、オイラーの公式についてpythonコードで実装し、何が起こっているかを確認しながらこの美しい公式への理解を深めていきたい。
オイラーの公式
wikiより
数学の複素解析におけるオイラーの公式(オイラーのこうしき、英: Euler's formula)とは、複素指数函数と三角関数の間に成り立つ、以下の恒等式のことである:
$${\displaystyle e^{i x}=\cos x +i\sin x} $$
まずはこれをコードで記載し, y軸を実部, z軸を虚部として3次元上にプロットすることで確認していこう。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(-4*np.pi, 4*np.pi, 10000)
# 左辺
f = lambda x: np.e**(1j*x)
# 右辺
g = lambda x: np.cos(x) + 1j * np.sin(x)
fig = plt.figure(figsize=(10.0, 8.0))
ax = Axes3D(fig)
# 左辺をプロット
ax.plot(x, f(x).real, f(x).imag, "o", color='b', ms=5.0, label='e^ix')
# 右辺をプロット
ax.plot(x, g(x).real, g(x).imag, "o", color='r', ms=0.5, label='cos(x)+i*sin(x)')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.legend()
plt.show()
$e^{ix}$(青線)と$\cos x +i\sin x$(赤線)が一致することが確認できる。
これは何かと言うと、見る角度によっては先ほどのようなコイル状に見える。だが、以下の視点で見れば円運動であるし
※プロットする際少し歪んでしまうので綺麗にはならないですが…
fig = plt.figure(figsize=(10.0, 8.0))
ax = Axes3D(fig)
# 視点をzy面にするとzとyの関係性は円運動に見える
ax.view_init(elev=0, azim=0)
ax.plot(x, f(x).real, f(x).imag, "o", color='b', ms=1.0, label='e^ix')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.legend()
plt.show()
以下の視点で見れば$sin$波であるし
fig = plt.figure(figsize=(10.0, 8.0))
ax = Axes3D(fig)
# 視点をxz面にすると、xが変化した際のzの変化はsin波に見える
ax.view_init(elev=0, azim=-90)
ax.plot(x, f(x).real, f(x).imag, "o", color='b', ms=1.0, label='e^ix')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.legend()
plt.show()
以下の視点で見れば$cos$波であるし
fig = plt.figure(figsize=(10.0, 8.0))
ax = Axes3D(fig)
# 視点をxy面にすると、xが変化した際のyの変化はcos波
ax.view_init(elev=90, azim=-90)
ax.plot(x, f(x).real, f(x).imag, "o", color='b', ms=1.0, label='e^ix')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.legend()
plt.show()
z軸方向から見た仰角(elev)を変えることは位相を変化させることに等しい。
fig = plt.figure(figsize=(10.0, 8.0))
ax = Axes3D(fig)
# sin波とcos波はコイルを上から見るか手前から見るかで、これは斜めから見ている
ax.view_init(elev=45, azim=-90)
ax.plot(x, f(x).real, f(x).imag, "o", color='b', ms=1.0, label='e^ix')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.legend()
plt.show()
何が言いたいかというと、コイル(ばね)をある方向から見ると円だが、横から見ると波に見えて、ばねをくるくる回すと位相が変化していくということである。
余弦関数、正弦関数
実部と虚部の変化については3次元的に見るより色分けしてみたほうがわかりやすいので、以下のように色分けしながら見ていく。
※ラベルのrealは実部, imagは虚部を示している。
plt.figure(figsize=(10.0, 5.0))
plt.plot(x, f(x).real, linewidth=3.0, c='r', label='e^ix : real')
plt.plot(x, f(x).imag, linewidth=3.0, c='g', label='e^ix : imag')
plt.legend()
plt.show()
オイラーの公式により、三角関数を複素指数関数で表すことができる。余弦関数、正弦関数は
$${\displaystyle {\begin{aligned}\cos x&={\frac {e^{ix}+e^{-ix}}{2}},\
\sin x&={\frac {e^{ix}-e^{-ix}}{2i}}\end{aligned}}}$$
ということなので、まず $\cos x$ から確認する。
まず$x$に$-1$をかけると、かける前と比較し実部(赤と青)は一致するが、虚部(緑と黄)が反転しているので加算することで虚部が$0$になる。そして、実部は2倍になるので2で割ると$\cos x$になるわけだ。
plt.figure(figsize=(10.0, 5.0))
plt.plot(x, f(x).real, linestyle='dashed', linewidth = 3.0, c='r', label='e^ix : real')
plt.plot(x, f(x).imag, linestyle='dashed', linewidth = 3.0, c='g', label='e^ix : imag')
plt.plot(x, f(-x).real, linewidth=1.0, c='b', label='e^-ix : real')
plt.plot(x, f(-x).imag, linewidth=1.0, c='y', label='e^-ix : real')
plt.legend()
plt.show()
つぎに、さらに外から-1をかけると、今度は虚部(緑と黄)が一致するが、実部(赤と青)が反転しているので加算すると実部が0になる。そして虚部は2倍になるので2iで割るとsinになるわけだ。
plt.figure(figsize=(10.0, 5.0))
plt.plot(x, f(x).real, linestyle='dashed', linewidth = 3.0, c='r', label='e^ix : real')
plt.plot(x, f(x).imag, linestyle='dashed', linewidth = 3.0, c='g', label='e^ix : imag')
plt.plot(x, -1*f(-x).real, linewidth=1.0, c='b', label='e^-ix : real')
plt.plot(x, -1*f(-x).imag, linewidth=1.0, c='y', label='e^-ix : real')
plt.legend()
plt.show()
これはcos(赤線)が以下のようにy軸に関して対称であることから、xの符号によって値が変化しない性質を持ち、sin(緑)が原点に関して対称であることから、xに符号がかわるとyの符号も変わる性質を持つためである。
plt.figure(figsize=(10.0, 5.0))
plt.plot(x, np.cos(x), c='r', label='cos(x)')
plt.plot(x, np.sin(x), c='g', label='sin(x)')
plt.axvline(x=0, c='b')
plt.legend()
plt.show()
つまり、xにマイナスをかけて和をとれば、sinは打ち消しあって0となり、cosは一致するので2倍になる。
plt.figure(figsize=(10.0, 5.0))
plt.plot(x, np.cos(x)+np.cos(-x), c='r', label='cos(x)')
plt.plot(x, np.sin(x)+np.sin(-x), c='g', label='sin(x)')
plt.axvline(x=0, c='b')
plt.legend()
plt.show()
差を取ればcosは打ち消しあって0となり、sinは一致するので2倍になる。
plt.figure(figsize=(10.0, 5.0))
plt.plot(x, np.cos(x)-np.cos(-x), c='r', label='cos(x)')
plt.plot(x, np.sin(x)-np.sin(-x), c='g', label='sin(x)')
plt.axvline(x=0, c='b')
plt.legend()
plt.show()
オイラーの等式
オイラーの公式は、複素数の極形式を簡明な表示に導く。すなわち、複素数の極形式 $z = r(\cos θ + i \sin θ)$ は $z = re^{iθ}$ に等しい。また、特に、θ = π のとき、
$$e^{i\pi}+1=0$$
実際に計算してみると計算誤差があるため0にはならないが、ほぼ0となる。
np.e**(1j*np.pi) + 1
>>> 1.2246467991473532e-16j
これはつまり、 $x=\pi$ (青線)の時には実部(赤)が $-1$ となり虚部(青)が $0$ となるということ。
x = np.linspace(-2*np.pi, 2*np.pi, 10000)
plt.figure(figsize=(10.0, 5.0))
plt.plot(x, np.cos(x), c='r', label='cos(x)')
plt.plot(x, np.sin(x), c='g', label='sin(x)')
plt.axvline(x=0, linestyle='dashed', linewidth=1.0, c='c')
plt.axvline(x=np.pi/2, linestyle='dashed', linewidth=1.0, c='c')
plt.axvline(x=np.pi, c='b')
plt.axvline(x=-np.pi/2, linestyle='dashed', linewidth=1.0, c='c')
plt.axvline(x=-np.pi, linestyle='dashed', linewidth=1.0, c='c')
plt.legend()
plt.show()
水色の破線部分も踏まえて整理すると。オイラーの等式に加えて以下も全て成り立つ。
$$e^{i\pi}+1=0$$
$$e^{i\frac{\pi}{2}}-i=0$$
$$e^{0}-1=0$$
$$e^{-i\frac{\pi}{2}}+i=0$$
$$e^{-i\pi}+1=0$$
実際に計算しても0となる(誤差には目をつぶってください)
np.e**(1j*np.pi) + 1
>>> 1.2246467991473532e-16j
np.e**(1j*np.pi/2) - 1j
>>> (6.123233995736766e-17+0j)
print(np.e**0 - 1)
>>> 0.0
print(np.e**(-1j*np.pi/2) + 1j)
>>> (6.123233995736766e-17+0j)
print(np.e**(-1j*np.pi) + 1)
>>>-1.2246467991473532e-16j
最後に
いかがだったでしょうか?実際にpythonを使い動かしながら見ていくと、それが何を表しているのかわかりやすくワクワクしてこないでしょうか?ノートに公式を書いて暗記するのもいいですが、プログラムの勉強をしながら一緒に倒すのもまたいいものです。数学とプログラミングを一緒に学ぶモチベーションになったのであれば(・∀・)イイネ!!でも押していただければ幸いです。それではアデュー(´っ・ω・)っ