3

a *= b複素数配列の演算に乗算バージョンはありますか? つまり、複素数の配列 (多数の要素または長さ不明) のすべての要素を乗算し、その結果を複素 double 変数に格納する最も効率的な方法は何ですか?

次のコードでAns1は正しい答えを示していますが、私のアプリケーションでは配列の各要素をアドレス指定するのは何百もの要素があるため意味がありません。理想的にAns2は、配列のすべての要素を乗算して答えを格納するループ (に似たもの) が必要です。要素が0で乗算されるため、答えAns2として開始しない場合。ただし、複素数を扱っているため、初期化も機能しません。1.0,1.00,01.0,1.0

編集 - 各要素を手動で処理できない理由は、配列の要素が別のa場所から取得され、長さaが異なる大きなプログラムにリンクされるためです。

理想的にはANSWER = COMPLEX ELEMENT[0]*COMPLEX ELEMENT[1]*COMPLEX ELEMENT[2]*....COMPLEX ELEMENT[n]

/*
  Complex Array Multiplication
*/

#include <complex>
#include <iostream>
#include <cmath>

using namespace std;

int main()
{
    int n = 3;
    complex<double> Ans1, Ans2(1.0,1.0);

    complex<double> a[n];

    a[0] = complex<double>(1.0, 1.5);
    a[1] = complex<double>(-1.0, 1.5);
    a[2] = complex<double>(1.0, -1.5);

    Ans1 = (a[0]*a[1]*a[2]);
    cout << "\nAns1 = " << Ans1;

    for (int i =0; i < n; i++) {
        Ans2 = Ans2 * a[i];
    }

    cout << "\nAns2 = " << Ans2;

    getchar();
}

多分これは非常に簡単に行うことができますが、何かが欠けています。前もって感謝します。

4

3 に答える 3

5

まず第一に、complex<double> a[n];n はコンパイル時の定数ではないため、この行は有効な C++ ではありません (少なくとも C++14 より前では)。コンパイラが VLA を実装している可能性がありますが、それらは (まだ) 標準の一部ではありません。

つまり、複素数の配列 (多数の要素または長さ不明) のすべての要素を乗算し、その結果を複素 double 変数に格納する最も効率的な方法は何ですか?

あなたは行くことができますstd::accumulate

#include <complex>
#include <iostream>
#include <cmath>
#include <algorithm> //accumulate
#include <functional> //multiplies

using namespace std;

int main()
{
    cons static int n = 3; //compiletime constant

    complex<double> a[n];

    a[0] = complex<double>(1.0, 1.5);
    a[1] = complex<double>(-1.0, 1.5);
    a[2] = complex<double>(1.0, -1.5);

    //define variables when they are needed

    //alternative 1: using std::multiplies
    auto Ans1 = std::accumulate(begin(a), end(a), complex<double>{1}, multiplies<complex<double>>{});
    cout << "\nAns1 = " << Ans1;

    //alternative 2: using a C++11 lambda
    auto Ans2 = std::accumulate(begin(a), end(a), complex<double>{1.0,1.0}, [](complex<double> a, complex<double> b) {return a*b;})
    cout << "\nAns2 = " << Ans2;

    //alternative 3: using a C++14 templated lambda
    auto Ans3 = std::accumulate(begin(a), end(a), complex<double>{1.0,1.0}, [](auto a, auto b) {return a*b;})
    cout << "\nAns3 = " << Ans3;
}  

complex(1,1)注:が実際に使用したい初期値であるかどうかはわかりません- 乗法恒等式はcomplex(1,0)

于 2013-07-08T13:58:30.467 に答える
5

複素数の乗法恒等式はであるため 、ループの前に (1, 0) に1 + 0i初期化する必要があります。Ans2

この用語に慣れていない方のために説明すると、ID は操作の結果を変更しない値です。たとえば、実数の加法的恒等式は 0a + 0 = aですa。複素数の乗算の場合、(a + bi) * (1 + 0i) = (a + bi). Ans2ループでは、計算結果に影響を与えない値に初期化したいので、乗法恒等式を使用します。

于 2013-07-08T13:54:03.700 に答える
0

これを試すことができます:

if (n>=2)
{
    complex<double> ans3 = a[0]*a[1];
    for (unsigned int i = 2; i < n; ++i)
    {
        ans3 *= a[i];
    }
    cout << "ans3 = " << ans3<<std::endl;
}
于 2013-07-08T13:53:16.213 に答える