复数运算出错

Complex numbers arithmetic goes wrong

现在我正在尝试实现 Poisson binomial distribution 的概率公式。

公式是该部分的最后一个,其中包含复指数:

我有一个非常简单的代码可以执行此操作,但它输出了错误的概率。

#include <iostream>
#include <complex>
#include <cmath>
using namespace std;

int main(int argc, char const *argv[]) {
    int N=5; //number of coins
    double probabilities[N]={0.1,0.1,0.1,0.1,0.1}; //probabilities of coin landing head
    double distr[N+1];
    for (int j=0; j<N+1;j++){
        complex<double> temp1=0.0 + 0.0i;
        for (int k=0; k<N+1;k++){
           for(int l=0;l<N+1;l++){
           complex<double> temp2=1.0 + 0.0i;
               for (int m=0;m<N;m++){
                   temp2=temp2*(1.0+0.0i+(exp(l*2*M_PI*1.0i/(double(N)+1.0))-1.0+0.0i)*probabilities[m]);
               }
               temp2=temp2*exp(l*k*2*M_PI*1.0i/(double(N)+1.0));
               temp1=temp1+temp2/(double(N)+1.0);
           }
        }
        distr[j]=real(temp1);
    }
    for (int i=0;i<N+1;i++){
    cout<< distr[i] << ' ';
  }

这段代码的输出是[1,1,1,1,1,1],肯定是不正确的。我在想,也许我没有正确处理复数,但我看不出我哪里做错了。令人沮丧的是,这样一个简单的程序不起作用:(.

从代码中可以清楚地看出 temp1 不依赖于 j,因此您得到相同的数字,即 k 的总和。删除 j 上的外循环并写入 distr[k] = real(temp1); 并修复 exp(l*k*...) 中的符号后,您将得到预期的结果:

0.59049 0.32805 0.0729 0.0081 0.00045 1e-05 

经过一些简化的完整代码:

int main() {
    using namespace std::literals::complex_literals;

    constexpr int N = 5;
    const double probabilities[N] = {.1, .1, .1, .1, .1};
    const auto c = std::exp(2i * M_PI / (N + 1.));

    double distr[N + 1];
    for (int k = 0; k <= N; ++k) {
        auto sum = std::complex<double>(0);
        for(int l = 0; l <= N; ++l) {
            auto prod = std::complex<double>(1);
            for (int m = 0; m < N; ++m)
                prod *= 1. + (std::pow(c, l) - 1.) * probabilities[m];
            sum += prod * std::pow(c, -l * k) / (N + 1.);
        }
        distr[k] = std::real(sum);
    }

    for (auto d : distr)
        std::cout << d << ' ';
}