『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

複素数(complex)

複素数型 (complex)

Python組み込みの複素数型数値型に分類されるオブジェクトの1つで、a + bj の形で定義します ( i ではなく j であることに注意してください)。a, b はそれぞれ複素数の実数部虚数部であり、浮動小数点数型 (float) として扱われます。虚数部が 1 のとき、a + j のように記述するとエラーになります。正しくは a + 1j です。
 
Python complex型 複素数平面

複素数の定義と四則演算

リテラルで a + bj と記述すると、複素数 (complexクラスのオブジェクト) が定義されます。あるいは、コンストラクタ complex(a, b) で明示的に定義します。

# PYTHON_COMPLEX

# In[1]

# 複素数 7+13i を定義
z1 = 7 + 13j

# コンストラクタで複素数5+iを定義
z2 = complex(5, 1)

算術演算子を使って複素数同士の加減乗除ができます。

# In[2]

print("z1 + z2 : {}".format(z1 + z2))
print("z1 - z2 : {}".format(z2 - z1))
print("z1 * z2 : {}".format(z1 * z2))
print("z2 / z1 : {}".format(z2 / z1))

# z1 + z2 : (12 + 14j)
# z2 - z1 : (2 + 12j)
# z1 * z2 : (22 + 72j)
# z2 / z1 : (0.2201834862385321 - 0.26605504587155965j)

complex 型と int 型、complex 型と float 型との間でも四則演算できます。
戻り値はすべて complex 型になります。

# In[3]

# 複素数zを定義
z = 2 + 3j

# 浮動小数点xを定義
x = 5.5

# x+z
print(x + z)

# (7.5 + 3j)

実部・虚部・共役複素数

複素数 7 + 13j を定義します。

# In[4]

# 複素数型z=7+13iを定義
z = 7 + 13j

real 属性で実部を参照できます。

# In[5]

# zの実数部 Re[z]
print(z.real)

# 7.0

imag 属性で虚部を参照できます。

# In[6]

# zの虚数部 Im[z]
print("虚部:", z.imag)

# 13.0

conjugate()メソッドは共役複素数を返します。

# In[7]

# zの共役複素数 z*
print(z.conjugate())

# (7-13j)

abs 関数は絶対値を返します。

# In[8]

# zの絶対値 |z|=zz*
print(abs(z))

# 14.7648230602334

【cmath】複素数演算

複素数の偏角の取得、極座標形式への変換などは cmath モジュール によってサポートされています。

複素数の偏角

cmathモジュールの phase 関数を使って、複素数 1 + i の偏角を求めてみます。ラジアンを度数法単位に変換するために、math モジュールの degrees関数もインポートしておきます。

# PYTHON_CMATH_COMPLEX

# In[1]

# mathモジュールをインポート
import math

# cmathモジュールをインポート
import cmath

# 複素数型 z = 1 + i を定義
z = 1 + 1j

# z の偏角(ラジアン)
arg_rad = cmath.phase(z)

# z の偏角(度)
arg_deg = math.degrees(arg_rad)

print("偏角 (ラジアン):", arg_rad)
print("偏角 (°):", arg_deg)

# 偏角(ラジアン): 0.7853981633974483
# 偏角(°): 45.0

よく知られているように、1 + i の偏角は 45°であることが確認できました。
ラジアンから度数法単位への変換には math モジュールの degrees 関数を用いています。

極座標形式

複素数 z = a + bi を極座標形式 z = e に変換するときは、cmath モジュールの polar 関数を用います。戻り値は (r, θ) のタプル型です。以下のサンプルコードで複素数 1 + i を極座標形式に変換してみます。

# PYTHON_COMPLEX_POLAR

# In[1]

import math
import cmath

# 複素数型 z = 1 + i を定義
z = 1 + 1j

# z の極座標形式 z = rexp(iθ) の r と θ を取得
zp = cmath.polar(z)

r = zp[0]
t = zp[1]

# zp を表示
print("極座標形式:", zp)

# r の平方を計算
print("r の平方:", r**2)

# θ を度数法で表示
print("θ[°]:", math.degrees(t))

# 極座標形式: (1.4142135623730951, 0.7853981633974483)
# r の平方: 2.0000000000000004
# θ[°]: 45.0

ちなみに i は (imaginary number) の頭文字です。数学や自然科学では虚数単位をそのまま i と表しますが、電気工学では電流 i との混同を避けるために j で表すことが多いようです。

【NumPy】複素数演算

NumPy には複素数の演算に関連するいくつかのユニバーサル関数が用意されています。

複素数の実部と虚部

numpy.real() は配列の各要素の実部を返します。
numpy.imag() は配列の各要素の虚部を取得します。

# NUMPY_COMPLEX

# In[1]

import numpy as np

# 複素数の配列
z = np.array([7 + 9j, 11 + 5j, 3 + 6j])

# 配列の各要素の実部を取得
z_real = np.real(z)

# 配列の各要素の実部を取得
z_imag = np.imag(z)

print("z_real = {}".format(z_real))
print("z_imag = {}".format(z_imag))

# z_real = [ 7. 11.  3.]
# z_imag = [9. 5. 6.]

共役複素数と偏角

numpy.conj() は配列の各要素の共役複素数を計算します。

# In[2]

import numpy as np

# 複素数の配列
z = np.array([3 + 7j, 1 + 2j, 5 + 12j])

# 配列の各要素の共役複素数を計算
z_conj = np.conj(z)

print("z_conj = {}".format(z_conj))
# z_conj = [3. -7.j 1. -2.j 5.-12.j]

numpy.angle() は配列の各要素の偏角を計算します。

# In[3]

# 複素数の配列
z = np.array([4 + 13j, 25 + 19j, 8 + 17j])

# 配列の各要素の共役複素数を計算
z_angle = np.angle(z)

# 数値を丸める
z_angle = np.round(z_angle, 3)

print("z_angle = {}".format(z_angle))
# z_angle = [1.272 0.65  1.131]

【SymPy】複素数演算

SymPy で複素数の演算を実行する場合、虚数単位として sympy.I を使います。

# SYMPY_COMPLEX

# In[1]

from sympy import *

# 記号を定義
a, b, c, d = symbols("a b c d")

# 複素数a+bi
z1 = a + b*I

# 複素数c+di
z2 = c + d*I

# 複素数同士の加算
# 式は虚数単位Iについて整理する
z3 = collect(z1 + z2, I)

z3
# a + c + I*(b + d)

sympy.re() は引数の実部を返します。

# In[2]

# 5+13iの実部
re(5 + 13*I)

# 5

sympy.im() は引数の虚部を返します。

# In[3]

# 7-9iの虚部
im(7 - 9*I)

# -9

sympy.arg() は引数の偏角を返します。

# In[4]

# 1+iの偏角
arg(1 + I)

# pi/4

sympy.conjugate() は引数の共役複素数を返します。

# In[5]

# 3+2iの共役複素数
conjugate(3 + 2*I)

# 3 - 2*I

コメント