複素数(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

コメント

  1. あとりえこばと より:

    【AI連載小説】科学とコードの交差点(9)
     
    大学のコンピュータラボで、六郷開誠と刑部明信は物理学のプロジェクトに取り組んでいた。プロジェクトでは、複素数が重要な役割を果たすため、開誠と明信はPythonで複素数を扱う方法について熱心に話し合っていた。

    開誠が笑みを浮かべながら言った。
    「複素数の計算、結構やりごたえがありそうだね」
    明信も微笑みながら応えた。
    「そうだね。特に数学的な安定性や計算の効率性に気をつけないといけないよ」
    開誠はノートパソコンの画面を指差しながら続けた。
    「Pythonでは複素数は a + bj の形で表現されるけど、計算の過程で実部と虚部を分けて考えることが必要だよね」
    明信はうなずく。
    「その通り。特に虚数単位 j の二乗がマイナス1になることを理解しておくと、計算の際に混乱を避けられるよ」
    開誠はさらに深く考え込みながら続けた。
    「そういえば、複素数の絶対値や偏角の取り扱いも重要だよね。これらをうまく利用すると、いくつかの問題を効率的に解くことができるかもしれない」
    明信は一瞬黙って考える。
    「そうだね。また、数学的な関数や演算において、複素数がどれだけ表現力豊かなものかも考えておくべきだよ」