はじめに:なぜfloat精度の複素数が必要なのか?
C++で複素数を扱う際、一般的には`std::complex`テンプレートクラスが利用されます。このクラスは、実数部と虚数部を組み合わせて複素数を表現します。特に、数値計算の分野では、信号処理、画像処理、物理シミュレーションなど、複素数が頻繁に登場します。
`std::complex`は、デフォルトでは`double`精度で複素数を扱いますが、パフォーマンスやメモリ使用量の観点から、より軽量な`float`精度で複素数を扱いたい場面も少なくありません。例えば、組み込みシステムや、大量の複素数データを高速に処理する必要がある場合、`float`精度を用いることで、計算速度の向上やメモリフットプリントの削減が期待できます。
本記事では、`float`精度で複素数を扱うための`std::complex
基礎知識:`std::complex`とは?
`std::complex
- 実数部 (Real Part): 複素数の実軸上の値。
- 虚数部 (Imaginary Part): 複素数の虚軸上の値、虚数単位`i`(または`j`)に掛け合わされる部分。
例えば、複素数 `a + bi` は、`std::complex
`std::complex
- メモリ効率: `std::complex
`に比べて、使用するメモリ量が半分になります。 - 計算速度: 多くのハードウェアは`float`演算を`double`演算よりも高速に実行できるため、計算速度が向上する可能性があります。
- 互換性: `float`型のデータとの親和性が高く、既存の`float`ベースのコードとの連携が容易です。
実装/解決策:`std::complex`の使い方
`std::complex
1. 初期化
`std::complex
- 実数部と虚数部を指定して初期化:
`std::complex
- 実数部のみを指定して初期化 (虚数部は0になる):
`std::complex
- デフォルトコンストラクタ (実数部・虚数部ともに0):
`std::complex
2. 基本的な演算
`std::complex
- 加算 (+):
`(a + bi) + (c + di) = (a + c) + (b + d)i`
- 減算 (-):
`(a + bi) – (c + di) = (a – c) + (b – d)i`
- 乗算 ():
`(a + bi) (c + di) = (ac – bd) + (ad + bc)i`
- 除算 (/):
`(a + bi) / (c + di) = [(ac + bd) / (c^2 + d^2)] + [(bc – ad) / (c^2 + d^2)]i`
これらの演算は、`float`型の値や`std::complex
3. その他の便利な関数
`std::complex`には、複素数特有の計算をサポートする便利な関数も用意されています。
- `std::real(c)`: 複素数 `c` の実数部を取得します。
- `std::imag(c)`: 複素数 `c` の虚数部を取得します。
- `std::conj(c)`: 複素数 `c` の共役複素数を取得します(虚数部の符号を反転)。
- `std::abs(c)`: 複素数 `c` の絶対値(大きさ)を計算します。`sqrt(real(c)^2 + imag(c)^2)` と等価です。
- `std::arg(c)`: 複素数 `c` の偏角(ラジアン)を計算します。`atan2(imag(c), real(c))` と等価です。
サンプルプログラム
以下に、`std::complex
include
include
include
int main() {
// float精度で複素数を初期化する例
// 実数部: 1.0f, 虚数部: 0.5f
std::complex
// 実数部のみを指定して初期化 (虚数部は 0.0f になる)
std::complex
// デフォルトコンストラクタ (実数部・虚数部ともに 0.0f)
std::complex
std::cout << "cf1: " << cf1 << std::endl; // 出力: (1,0.5)
std::cout << "cf2: " << cf2 << std::endl; // 出力: (2.5,0)
std::cout << "cf3: " << cf3 << std::endl; // 出力: (0,0)
// 基本的な算術演算
std::complex
std::complex
std::complex
std::complex
std::cout << "\n--- Arithmetic Operations ---" << std::endl;
std::cout << "cf1 + cf2 = " << sum << std::endl; // 出力: (3.5,0.5)
std::cout << "cf1 - cf2 = " << diff << std::endl; // 出力: (-1.5,0.5)
std::cout << "cf1 cf2 = " << prod << std::endl; // 出力: (2.5,-1.25)
std::cout << "cf1 / cf2 = " << quot << std::endl; // 出力: (0.317073,-0.158537) - 浮動小数点演算の誤差を含む
// その他の便利な関数
std::cout << "\n--- Useful Functions ---" << std::endl;
std::cout << "Real part of cf1: " << std::real(cf1) << std::endl; // 出力: 1
std::cout << "Imaginary part of cf1: " << std::imag(cf1) << std::endl; // 出力: 0.5
std::cout << "Conjugate of cf1: " << std::conj(cf1) << std::endl; // 出力: (1,-0.5)
std::cout << "Absolute value of cf1: " << std::abs(cf1) << std::endl; // 出力: 1.11803 (sqrt(1^2 + 0.5^2))
std::cout << "Argument of cf1 (radians): " << std::arg(cf1) << std::endl; // 出力: 0.463648
// float型との演算
float real_val = 3.0f;
std::complex `std::complex `std::complex
std::cout << "\ncf1 + 3.0f = " << cf_float_op << std::endl; // 出力: (4,0.5)
return 0; // プログラムの正常終了を示す
}
応用・注意点

コメント