我正在研究一种数学代码,它很大程度上依赖于通过实际数据的inplace-FFT进行卷积。
由于我的数据是真实的,直到它进入卷积并且在卷积完成时才是真实的,我在任何地方都使用std::vector<double>
。
所以在我的卷积中,我必须将我的真实数据复制到我的复杂数据中。我没有找到任何方法使用std::fill()
或任何其他比循环所有条目更复杂的方法。
此外:在测量使用原始指针与unique_ptr
与std::vector
相比所花费的时间时,第一个获胜的时间大约是所花费时间的一半,通过许多get()
操作包装。
我的编译器是否缺少某些优化,还是我必须使用原始指针和内存的麻烦?
工作示例:我现在无法对此进行测试,但我过去曾经大力支持我的主张。这些时间是通过使用Build-Dropdown中的(Build Solution)使用Visual Studio Community 2015构建解决方案而完成的。 性能分析显示,从包装器到数据花费了大量时间。
#include <chrono>
#include <complex>
#include <vector>
void FFT();
void IFFT();
int main() {
unsigned int N=1024;
std::vector<double> real;
real.resize(N);
std::vector<double> imag;
imag.resize(N);
for (unsigned int i = 0; i < N; ++i) {
real[i] = i;
imag[i] = i;
}
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::complex<double> I = std::complex<double> (0, 1);
std::vector<std::complex<double>> data;
data.resize(2048);
for (unsigned int i = 0; i < N; ++i) {
data[i] = real[i] + I*imag[i];
}
FFT();
data[0] = 0.25*I*(conj(data[0] * data[0]) - data[0]*data[0]);
for (unsigned int r = 1; r < 2 * N - r; ++r) {
std::complex<double> z1 = data[2 * N - r];
std::complex<double> z2 = data[r];
std::complex<double> res = 0.25*I*(conj(z1 * z1) - z2*z2);
data[r]=res;
data[2*N - r]= conj(res);
}
IFFT();
std::vector<double> result;
result.resize(2 * N);
for (unsigned int i = 0; i < 2 * N; ++i) {
result[i] = data[i].real();
}
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
}
答案 0 :(得分:2)
我没有找到任何方法使用std :: fill或任何其他比循环遍历所有条目更复杂的方法。
只需将std::transform
与lambda:
std::vector<double> a{ 1.0, 2.0, 3.0 };
std::vector<double> b{ 4.0, 5.0, 6.0 };
std::vector<std::complex<double>> cvec( a.size() );
std::transform( a.begin(), a.end(), b.begin(), cvec.begin(), []( double da, double db ) {
return std::complex<double>( da, db );
} );
您必须确保b
和cvec
至少与a
一样大,但对于cvec
,您可以使用std::back_inserter
,但这可能会稍微如果你没有为它预留保留,那就慢一些。