pythonistaがC++で複素数を扱ってみる.
目次
はじめに
どうも,かわつあんです. 今日はpython歴2年の私がC++で複素数をつかっていろいろしたいと思います.
複素数は今日の物理の計算や工学などでは必要不可欠なものとなっています. 私がC++で最終的にやりたい計算も複素数を扱いますので,実際に複素数を扱ってみて思ったことをまとめれたらと思います.
複素数とは
基本的にほとんどの人が知ってそうですが,簡単にまとめておきます.(厳密な説明ではないです.)
複素数とは,実数で扱えない計算を扱えるように拡張した数です. 普通は負の数の平方根は存在しませんが,複素数では虚数を導入することで,負の数の平方根を扱えるようにしました. 複素数は実部と虚部からなり,それぞれをとするとのように書きます.
書き出したらキリがないので,このくらいにしておきます. 詳しくはwikiなどをどうぞ.
C++で複素数を扱う
それでは,C++複素数について扱おうと思いますが,pythonとの比較も行なっていこうと思います. 以下では,pythonで先にコードを作成および実行し,その後それと等価のことをC++で行なっていきます.
a = 4 + 3j print(a)
実行結果
(1+1j)
このようにpythonでは,虚数単位をで表します.これは,工学系では電流(密度)をとして扱うことが多いため代わりに虚数単位をとして表現する思想からきているようです. (ちなみに理学系では逆に電流をと書くことが多いです)
#include <iostream> #include <complex> using namespace ::std; int main(){ complex<float> a; a = complex<float>(4,3); cout << a << endl; }
実行結果
(4,3)
C++では(実部, 虚部)のようにして複素数を扱うようです.またcomplex
クラスをインクルードしないと複素数を定義できません.
すこし面倒ですが,そもそもCやC++は複素数を扱う前提ではなかったみたいなのでしょうがないとは思います.
ここでは,complex<float>
としており,複素数の実部および虚部はそれぞれfloat
型にしていますが,int
やdouble
にもできます.(int
型で複素数をあつかうのはあまり現実的ではありませんが.)
四則演算
複素数の演算もいろいろ行なってみます. まずは四則演算です.
pythonだと
a = 4 + 3j b = 5 + 5j print("{} + {} = {}".format(a, b, a+b)) print("{} - {} = {}".format(a, b, a-b)) print("{} * {} = {}".format(a, b, a*b)) print("{} / {} = {}".format(a, b, a/b))
実行結果
(4+3j) + (5+5j) = (9+8j) (4+3j) - (5+5j) = (-1-2j) (4+3j) * (5+5j) = (5+35j) (4+3j) / (5+5j) = (0.7-0.1j)
バッチリです.手計算とも相違ないので,問題なさそうです.
続いてC++だと
#include <iostream> #include <complex> using namespace ::std; int main(){ complex<float> a,b; a = complex<float>(4,3); b = complex<float>(5,5); cout << a <<" + "<< b <<" = "<< a+b << endl; cout << a <<" - "<< b <<" = "<< a-b << endl; cout << a <<" * "<< b <<" = "<< a*b << endl; cout << a <<" / "<< b <<" = "<< a/b << endl; }
出力結果
(4,3) + (5,5) = (9,8) (4,3) - (5,5) = (-1,-2) (4,3) * (5,5) = (5,35) (4,3) / (5,5) = (0.7,-0.1)
問題なく計算できました!
複素数特有の計算
四則演算の次は,複素数特有の計算をしてみます. 具体的にはとしたときの 実部と虚部と,複素数の大きさ,偏角,複素共役です.ここら辺が計算できれば,大体の計算はできると思います.
それではいきましょう.まずはpythonから.
import cmath z = 4 + 3j print("Re(z) = {}".format(z.real)) print("Im(z) = {}".format(z.imag)) print("|z| = {}".format(abs(z))) print("arg(z) = {}".format(cmath.phase(z))) print("z* = {}".format(z.conjugate())
比較的に簡単に計算できました. 偏角だけはモジュールでの関数がないみたいですね. numpyを使うといろいろ使えるmethodも変わりますが,ここでは割愛します.
#include <iostream> #include <complex> using namespace ::std; int main(){ complex<float> z; z = complex<float>(4,3); cout << "Re(z) = " << z.real() << endl; cout << "Im(z) = " << z.imag() << endl; cout << "|z| = " << abs(z) << endl; cout << "arg(z) = " << arg(z) << endl; cout << "z* = " << conj(z) << endl; }
実行結果
Re(z) = 4 Im(z) = 3 |z| = 5 arg(z) = 0.643501 z* = (4,-3)
計算できました.complex
をインクルードしてしまったら,大体の計算ができるみたいでいいですね!
複素数特有の演算は慣れてしまえばC++でも簡単にできそうでよかったです.
さいごに
今回はC++で複素数を扱って,いろいろな計算をしました.pythonのコードと適宜比較しましたが,少しの差異はあれども,C++でもそんなに難しくなく計算ができそうなので,ほっとしています.
次回は,複素数と配列を組み合わせた複素数配列を少しだけ扱ってみようと思います.
次回が終われば,ひとまずC++の演算の確認は終了して,ctypes
にも触れて行こうと思います.
どうぞお付き合いください〜
ではまた(✿╹◡╹)