Pythonで複素数を扱う方法:complex型の基本からcmathモジュールまで
複素数の基礎知識
正の数には必ず2つの実数平方根が存在します。たとえば x² = 25 のとき、x = ±5 です。しかし x² = -25 のような場合は実数解が存在しません。負の数の平方根は、絶対値の平方根に虚数単位 j = √−1 を掛けた形で定義されます。
したがって、√−25 = √25 × √−1 = 5j となります。
複素数は実部と虚部から構成され、「x + yj」という形式で表されます。x と y はどちらも実数であり、y に虚数単位 j を掛けた部分が虚部となります。
記述例:3+2j、10-5.5J、9.55+2.3j、5.11e-6+4j
Pythonにおける複素数型(complex)
Pythonには複素数を扱うための組み込みデータ型「complex」が用意されています。複素数オブジェクトはリテラル表記によって、次のように簡単に作成できます。
>>> x = 2+3j
>>> type(x)
<class 'complex'>
複素数オブジェクトには、real(実部を返す)とimag(虚数単位 j を除いた虚部を返す)という2つの属性が用意されています。
>>> x.real
2.0
>>> x.imag
3.0
さらに、conjugate() メソッドも利用できます。共役複素数とは、実部が同じで虚部の符号だけが反転した数のことです。つまり、2+3j の共役複素数は 2-3j になります。
>>> x.conjugate()
(2-3j)
complex() 関数による生成
Pythonには組み込み関数 complex() もあり、こちらでも複素数オブジェクトを生成できます。この関数は実部と虚部に対応する2つの引数を受け取り、引数には任意の数値型(int、float、complex)を指定できます。
>>> complex(9,5)
(9+5j)
>>> complex(-6, -2.5)
(-6-2.5j)
>>> complex(1.5j, 2.5j)
(-2.5+1.5j)
引数を1つだけ渡した場合はそれが実部とみなされ、虚部は0になります。
>>> complex(15)
(15+0j)
また、数値を表す文字列を引数に指定することも可能です。
>>> complex('51')
(51+0j)
>>> complex('1.5')
(1.5+0j)
複素数の四則演算
加算と減算
複素数の加算・減算は、整数や浮動小数点数の場合と同じ感覚で行えます。実部同士、虚部同士がそれぞれ独立して計算される仕組みです。
>>> a = 6+4j
>>> b = 3+6j
>>> a+b
(9+10j)
>>> a-b
(3-2j)
乗算
乗算では、複素数を二項式とみなして展開します。第1の数の各項に、第2の数の各項を順番に掛け合わせて計算します。
a = 6+4j
b = 3+2j
c = a*b
c = (6+4j)*(3+2j)
c = (18+12j+12j+8*-1)
c = 10+24j
Pythonの対話コンソールで確認すると、上記の計算結果と一致することがわかります。
>>> a = 6+4j
>>> b = 3+2j
>>> a*b
(10+24j)
除算
複素数の除算は、分母の共役複素数を利用して行います。次の2つの複素数を例に考えてみましょう。
a = 2+4j
b = 1-2j
a/b を求める場合、まず分母 1-2j の共役複素数である 1+2j を求めます。
分子と分母の両方に共役複素数を掛けることで、除算の結果を導き出せます。
c = a/b
c = (2+4j)*(1+2j)/(1-2j)(1+2j)
c = (2+4j+4j+8*-1)/(1+2j-2j-4*-1)
c = (-6+8j)/5
c = -1.2+1.6j
Pythonの対話コンソールで実際に実行しても、同じ結果が得られることを確認できます。
>>> a = 2+4j
>>> b = 1-2j
>>> a/b
(-1.2+1.6j)
cmathモジュールとは
Python標準ライブラリの math モジュールに含まれる数学関数は、浮動小数点数を対象として設計されています。複素数に対しては、代わりに cmath モジュールを使用します。
複素数 z = x+yj は直交座標(デカルト座標)形式の表現です。内部では極座標形式、すなわち絶対値 r(組み込み関数 abs() が返す値)と位相角 Φ(ファイと読みます。原点と x を結ぶ線が x 軸から反時計回りに成す角度で、単位はラジアン)で表現されます。下図は複素数の極座標表示を示したものです。

cmathモジュールの関数を使うと、直交座標表現と極座標表現を相互に変換できます。
polar()
polar() — 直交座標形式で表された複素数の極座標表現を返します。戻り値は絶対値(モジュラス)と位相角からなるタプルです。
>>> import cmath
>>> a = 2+4j
>>> cmath.polar(a)
(4.47213595499958, 1.1071487177940904)
なお、絶対値は abs() 関数でも取得できます。
>>> abs(a)
4.47213595499958
phase()
phase() — 原点と複素数 a を結ぶ線分が x 軸となす反時計回りの角度を返します。角度の単位はラジアンで、範囲は π 〜 −π です。
>>> cmath.phase(a)
1.1071487177940904
rect()
rect() — 極形式(絶対値と位相角)で表された複素数を、直交座標形式に変換して返します。
>>> cmath.rect(4.47213595499958, 1.1071487177940904)
(2.0000000000000004+4j)
cmathモジュールの主な数学関数
cmathモジュールには、mathモジュールで定義されている数学関数の複素数版がすべて用意されています。ここでは、三角関数や対数関数などの代表例を紹介します。
cmath.sin() — ラジアンで表された位相角に対する正弦(サイン)の値を返します。
>>> import cmath
>>> a = 2+4j
>>> p = cmath.phase(a)
>>> cmath.sin(p)
(0.8944271909999159+0j)
同様に、cos()、tan()、asin()、acos()、atan() といった他の三角関数もcmathモジュール内で定義されています。
cmath.exp() — math.exp() と同様に、ex(x は複素数、e は自然対数の底 2.71828…)を返します。
>>> cmath.exp(a)
(-1.1312043837568135+2.4717266720048188j)
cmath.log10() — 底を10とした複素数の対数値を計算します。
>>> a = 1+2j
>>> cmath.log10(a)
(0.3494850021680094+0.480828578784234j)
cmath.sqrt() — 複素数の平方根を返します。
>>> cmath.sqrt(a)
(1.272019649514069+0.7861513777574233j)
まとめ
本記事では、Pythonの複素数データ型(complex型)の重要な特徴と、複素数に対して行える四則演算の方法について学びました。さらに、cmathモジュールを使った極座標変換や、sin()・exp()・log10()・sqrt() などの数学関数の使い方も確認しました。科学技術計算や信号処理などで複素数を扱う際には、ぜひ本記事の内容を参考にしてください。
-
Pythonで選択ソートを実装する方法|仕組みとサンプルコードをわかりやすく解説
この記事では、選択ソート(Selection Sort)の基本的な仕組みと、Python 3.x(およびそれ以前のバージョン)での実装方法について解説します。 選択ソートとは 選択ソートは、ソートされていない部分から最小の要素を繰り返し見つけ出し、先頭側へ移動させることで配列全体を整列していくアルゴリズムです。処理の過程で、対象の配列は次の2つの部分配列に分けられます。 すでにソートが完了している部分配列 まだソートされていない部分配列 選択ソートの各イテレーションでは、未ソートの部分配列から最小要素を取り出し、ソート済みの部分配列の末尾に追加していきます。 アルゴリズムの動作イメー
-
Pythonで複数の数値や配列の最大公約数(GCD)を求める方法
本記事では、以下の問題に対する解決策について詳しく解説します。問題の概要与えられた数値の配列から、それらすべての最大公約数(GCD)を求める必要があります。アプローチ2つより多い数値の最大公約数を求める場合、GCDは引数として渡されたすべての数値に共通する素因数の積と等しくなります。これは数学的な定義に基づく方法ですが、実装がやや複雑になります。もう一つの方法として、2つの数値ずつペアでGCDを繰り返し計算するという手法があります。具体的には、最初の2つの数値のGCDを求め、その結果と次の数値のGCDを計算し、これを配列の最後まで繰り返します。本記事では、後者のアプローチを実装していきます。実