【问题标题】:C++ - Complex Value Calculation Error in Cross Spectral DensityC++ - 交叉谱密度中的复数值计算错误
【发布时间】:2018-01-19 19:53:35
【问题描述】:

我是 C++ 的初学者,我想做一些光谱计算,在这种情况下计算两个信号 (vecFirst, vecSecond) 的“交叉光谱密度”,这两个信号已经使用 FastFourierTransformation 进行了处理。生成 freqvecfreqvec2,包含每个频率的复数值。

对于这种计算,必须将每个值都保留为复数。例如:在第 6 行中计算的 CoSpectrum,结果应该是一个复数。

RowVectorXcd freqvec;
RowVectorXcd freqvec2;
fft.fwd(freqvec, vecFirst);
fft.fwd(freqvec2, vecSecond);

// # Create conjugate complex
freqvec.conjugate();
freqvec2.conjugate();
RowVectorXcd Rxy(freqvec.cols());
for (int i = 0; i < freqvec.cols(); i++) {
        std::complex<double>CoSpectrum( freqvec(i).real() * freqvec2(i).real() + freqvec(i).imag() * freqvec2(i).imag()) ;
        std::complex<double>QuadSpectrum( freqvec(i).real() * freqvec2(i).imag() - freqvec(i).real() * freqvec2(i).imag() ) ;
        std::complex<double>CoSpectrum_sqr = CoSpectrum * CoSpectrum ;
        std::complex<double>QuadSpectrum_sqr = QuadSpectrum * QuadSpectrum ;
        Rxy(i) = sqrt(std::complex<double>(CoSpectrum_sqr + QuadSpectrum_sqr)) ;
    }
}

不幸的是,我只能得到虚部为零的复数值。

谁能告诉我为什么? 我猜测表达式freqvec(i).real() 只返回一个双精度值,但我怎样才能得到实部但保持它是一个复数。或者,相应地,只需将复数的虚部乘以另一个复数的实部,并将结果保持为复数双精度数。

提前感谢您的帮助。

【问题讨论】:

  • 您正在为 std::complex 构造函数传递单个值。实部和虚部或复数需要两个双精度值。调用 real() 或 imag() 仅返回实数 - real + j imag。
  • std::complex&lt;double&gt;(freqvec(i).real(), 0) - 复数只包含实部和std::complex&lt;double&gt;(0, freqvec(i).imag()) - 只包含虚部
  • 我认为您不需要将两个 ffts 共轭,您可以直接将 std::complex 值和std::complex::abs() 相乘以获得幅度。
  • 首先:非常感谢。我曾想过类似的事情,但不确定。感谢有像你这样关心初学者的好人。所以我改变了sn-p如下:
  • 我无法尝试,但 AFAIK CSD 是交叉相关的傅立叶或第一个的 fft 和第二个的 rhe conj 的乘积,因此 ˋauto csd = freqvec(i) * frecvec2(i)。 conj;ˋ 并且你可以调用ˋcsd.abs()ˋ 来获取幅度

标签: c++ complex-numbers frequency-analysis


【解决方案1】:

首先:非常感谢。我曾想过类似的事情,但不确定。感谢有像你这样关心初学者的好人。

所以我把sn-p改成如下:

    // ### Attempting to compute the Frequency Power for Frequency Bins..
    RowVectorXcd freqvec;
    RowVectorXcd freqvec2;
    fft.fwd(freqvec, vecFirst);
    fft.fwd(freqvec2, vecSecond);
    std::cout<<"freqvec:"<<freqvec.cols()<<std::endl;

    // ### Attempting to compute the PowerSpectralDensitiy(PSD) and CrossSpectralDensity(CSD). The cross-spectral density is the Fourier transform of the cross-correlation function.
    RowVectorXcd Rxy(n_Epochs, freqvec.cols());
    RowVectorXcd Rxx(n_Epochs, freqvec.cols());
    RowVectorXcd Ryy(n_Epochs, freqvec.cols());
    for (int i = 0; i < n_Epochs; i++) {
            std::complex<double>CoSpectrum( std::complex<double>(freqvec(i).real(),0) * std::complex<double>(freqvec2(i).real(),0) + std::complex<double>(0,freqvec(i).imag()) * std::complex<double>(0, freqvec2(i).imag()) ) ;
            std::complex<double>QuadSpectrum( std::complex<double>(freqvec(i).real(), 0) * std::complex<double>(0, freqvec2(i).imag()) - std::complex<double>(0,freqvec(i).imag()) * std::complex<double>(freqvec2(i).real(), 0) ) ;
            std::complex<double>CoSpectrum_sqr = CoSpectrum * CoSpectrum ;
            std::complex<double>QuadSpectrum_sqr = QuadSpectrum * QuadSpectrum ;
            Rxy(i) = sqrt(std::complex<double>(CoSpectrum_sqr + QuadSpectrum_sqr)) ;
            Rxx(i) = std::complex<double>(freqvec(i).real(), 0) * std::complex<double>(freqvec(i).real(), 0) + std::complex<double>(0, freqvec(i).imag()) * std::complex<double>(0, freqvec(i).imag()) ;
            Ryy(i) = std::complex<double>(freqvec2(i).real(), 0) * std::complex<double>(freqvec2(i).real(), 0) + std::complex<double>(0, freqvec2(i).imag()) * std::complex<double>(0, freqvec2(i).imag()) ;
        }
    }

这解决了我的问题。再次感谢您的精彩讨论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多