我目前正在尝试弄清楚如何使用库的FFT算法。假设我有一个函数
std::complex<double> f(std::complex<double> const & t){
return std::sin(t);
}
我使用这个函数进行计算。
Eigen::VectorXcd time(1000);
Eigen::VectorXcd f_values(1000);
for(int u = 0; u < 1000; ++u){
time(u) = u* 2. * M_PI / 1000;
f_values(u) = f(time(u));
}
我现在想计算
f_values
的傅里叶变换,所以我执行以下操作:Eigen::FFT<double> fft;
Eigen::VectorXcd f_freq(1000);
fft.fwd(f_freq, f_values);
现在我想绘制图表,但是为此我需要评估
f_freq
的频率,但我不知道如何获得这些频率。所以我的问题归结为找到包含频率的Eigen :: VectorXcd
,以绘制类似于以下内容的图形:
(很抱歉我使用图片作为描述,但我认为这样比我试图用文字来描述更清晰...图中的amplitude
应对应于我的f_freq
,而我正在寻找的是freq
的值...)。
以下是上述代码片段放入单个文件中的方式:
#include <eigen3/Eigen/Dense>
#include <eigen3/unsupported/Eigen/FFT>
#include <complex>
#include <cmath>
std::complex<double> f(std::complex<double> const & t){
return std::sin(t);
}
int main(){
Eigen::VectorXcd time(1000);
Eigen::VectorXcd f_values(1000);
for(int u = 0; u < 1000; ++u){
time(u) = u* 2. * M_PI / 1000;
f_values(u) = f(time(u));
}
Eigen::FFT<double> fft;
Eigen::VectorXcd f_freq(1000);
fft.fwd(f_freq, f_values);
//freq = ....
}
我按照建议的答案之一实现如下:
#include <eigen3/Eigen/Dense>
#include <eigen3/unsupported/Eigen/FFT>
#include <complex>
#include <cmath>
#include <iostream>
#include <fstream>
std::complex<double> f(std::complex<double> const & t){
return std::sin(1.*t);
}
int main(){
std::ofstream freq_out("frequencies.txt");
std::ofstream f_freq_out("f_freq.txt");
unsigned const N = 1000.;
Eigen::VectorXcd time(N);
Eigen::VectorXcd f_values(N);
for(int u = 0; u < N; ++u){
time(u) = u* 2. * M_PI / double(N);
f_values(u) = f(time(u));
}
Eigen::FFT<double> fft;
Eigen::VectorXcd f_freq(N);
Eigen::VectorXd freq(N);
fft.fwd(f_freq, f_values);
double const Ts = 2. * M_PI/double(N);
double const Fs = 1./Ts;
for(int u = 0; u < N; ++u){
freq(u) = Fs * u / double(N);
}
freq_out << freq;
f_freq_out << f_freq.cwiseAbs();
}
这导致了以下绘图结果: 这看起来有点不对劲..缩放显然没有太多意义,而且存在两个值尖峰的事实让我有点怀疑..
k * SampleRate/N
的式子,其中N
是点数,-N/2 <=k < N/2
。需要检查N
是奇数还是偶数。此外,根据实现方式,频率可以存储在-fmax
到fmax
或0
到fmax
然后是-fmax
到0
,这意味着绘图前需要重新组织数据。我知道这是一个 C++ 的问题,但是你可以查看 python 的文档 numpy.fft 和 numpy.fft.fftfreq 的实现。 - mikuszefskiTs
相比,您的正弦波频率非常低。也许尝试另一个Ts
以使尖峰更靠近中心...Ts = 10 /(2 * pi)
对我来说似乎是合理的。按照您现在的设置,尖峰应该在第一个箱中:对我来说看起来还不错。 - FushoEigen
返回一个双频谱(如果信号是实数,则对称)。 - Fusho