【问题标题】:Complex number array multiplication复数数组乘法
【发布时间】:2013-07-05 21:06:00
【问题描述】:

对于复数数组,a *= b 运算是否有乘法版本? 换句话说,将复数数组(大量元素或未知长度)的所有元素相乘并将结果存储在复数双精度变量中的最有效方法是什么?

在下面的代码中,Ans1 提供了正确答案,但是,对于我的应用程序来说,处理数组的每个元素是没有意义的,因为会有数百个元素。理想情况下,我想要一个循环(类似于Ans2)将数组的所有元素相乘并存储答案。如果我不将Ans2 初始化为1.0,1.0,则答案将是0,0,因为元素将乘以0。但是,使用1.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();
}

也许这可以很容易地完成,但我错过了一些东西。提前致谢。

【问题讨论】:

  • 乘以“数百”个复杂值对今天的计算机来说实际上并不是一个挑战……
  • “对于我的应用程序来说,处理数组的每个元素是没有意义的,因为会有数百个”你是在打孔卡上写这个程序吗?
  • 是的,但是必须像我为 Ans1 所做的那样手动键入每个元素可能不是使用当今计算机的最有效方式。我刚刚创建了数组 A 来填充值,但我的应用程序的值将来自其他地方。

标签: c++ complex-numbers


【解决方案1】:

复数的乘法恒等式是 1 + 0i,因此您应该在循环之前将 Ans2 初始化为 (1, 0)。

如果您不熟悉该术语,标识是不会改变操作结果的值。例如,实数的加法恒等式为 0,因为 a + 0 = a 表示任何实数值 a。对于复数的乘法,(a + bi) * (1 + 0i) = (a + bi)。在您的循环中,您希望将 Ans2 初始化为一个不会影响计算结果的值,因此您使用乘法恒等式。

【讨论】:

  • 谢谢,正是我想要的!
  • 不,有问题,很高兴为您提供帮助。
【解决方案2】:

首先,complex&lt;double&gt; a[n]; 行不是有效的 C++,因为 n 不是编译时常量——它必须是(至少在 C++14 之前)。您的编译器可能正在实现 VLA,但这些还不是标准的一部分。

换句话说,将复数数组(大量元素或未知长度)的所有元素相乘并将结果存储在复数双精度变量中的最有效方法是什么?

你可以选择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)

【讨论】:

  • 感谢您的全面回复。我以前不知道乘法恒等式,这解决了问题:)
【解决方案3】:

你可以试试这个:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-20
    • 2014-07-19
    • 2011-08-15
    相关资源
    最近更新 更多