【发布时间】:2016-08-15 03:30:12
【问题描述】:
我注意到RcppArmadillo 支持 FFT 和 2-D FFT。不幸的是,ifft2 (RcppArmadillo) 和 R 的原生 mvfft(..., inverse = TRUE) 与我的数据之间存在显着差异。这在第零个 bin 中尤其大(这在我的应用程序中非常重要)。差异不是标量倍数。我找不到任何文档或解释这些偏差,尤其是在第零个 bin 中。
我已针对ifft(arma::cx_mat input) 函数调用专门调试了该问题。除非可能存在无法预料的内存管理问题,否则这就是罪魁祸首。
示例:ifft2 结果(1 列前 5 个条目):
[1] 0.513297156-0.423498014i -0.129250939+0.300225299i
0.039722228-0.093052563i -0.007956237+0.018643534i 0.001181177-0.002768473i
mvfft 逆结果(1 列前 5 个条目):
[1] 0.278131988-0.633838170i -0.195699114+0.445980950i
0.060070320-0.136894940i -0.011924932+0.027175865i 0.001754788-0.003999007i
问题
-
RcppArmadilloFFT 是否仍在开发中? - 这是跨 FFT 变体的常见问题(FP 或 DP 噪声之外的数值偏差)吗?
- 是否存在来自 Rcpp 或 RcppArmadillo 的“低级”函数调用来调用 R 的本机 FFT?
重现性 - 下面我尽可能地浓缩了问题并重现了问题。 更新为最少的代码 rcpp代码:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
//profile is the dependent variable of a given variable x,
//q is a vector containing complex valued information for a single column after a tcrossprod
//Size is a scalar value which the FFT depends upon.
arma::cx_mat DebugLmnCPP( arma::cx_vec Profile, arma::cx_vec q) {
std::complex<double> oneeye (0,1);//Cmplx number (0 + 1i)
arma::cx_mat qFFT = ifft2( exp( oneeye * (Profile * q.st() ) ) );
return(qFFT );
}
// [[Rcpp::export]]
//For pedagogical purposes
arma::cx_mat DebugIFFTRCPP( arma::cx_mat input) {
arma::cx_mat qFFT = ifft2( input );
return( qFFT );
}
RCode(对不起,这是马虎)
library(Rcpp)
library(RcppArmadillo)
sourceCpp("/home/FILE.cpp")
#Use C++ function
qt <- c(6.0+0i, 5.95+0i, 0.10+0i)
prof <- 0.25* sin( (1:512)*(2*3.1415)/512 ) + 0.25#Offset Sine wave
Debug1 <- DebugLmnCPP( Profile = prof, q = qt )
#Use R function
FFTSize <- 2^9
DebugLmnR <- function(Profile, q) {
g <- (0+1i)*(as.matrix(Profile ) %*% t(q))
qFFT <- mvfft( exp(g) , inverse = TRUE) / FFTSize
return( qFFT )
}
#Call function
Debug2 <- DebugLmnR( Profile = prof, q = qt )
#Use R and C++
DebugLmnRC <- function(Profile, q) {
g <- (0+1i)*(as.matrix(Profile ) %*% t(q))
qFFT <- DebugIFFTRCPP(exp(g))
return( qFFT )
}
#Call function
Debug3 <- DebugLmnRC( Profile = prof, q = qt )
#Compare Results
Debug1[1:5,1] #CPP
Debug2[1:5,1] #R
Debug3[1:5,1] #R and CPP
产量:
> Debug1[1:5,1]
[1] 0.359632774+0.35083419i -0.037254305-0.36995074i 0.015576046+0.15288379i -0.004552119-0.03992962i
[5] 0.000967252+0.00765564i
> Debug2[1:5,1]
[1] 0.03620451+0.51053116i -0.04624384-0.55604273i 0.02204910+0.23101589i -0.00653108-0.06061692i
[5] 0.00140213+0.01167389i
> Debug3[1:5,1]
[1] 0.359632774+0.35083419i -0.037254305-0.36995074i 0.015576046+0.15288379i -0.004552119-0.03992962i
[5] 0.000967252+0.00765564i
【问题讨论】:
-
缩小问题范围。制作运行两种算法并产生不同结果的最小程序。还可以使用消毒剂(ASAN、Valgrind、...)运行您的代码。
-
我以前从未对 FFT 算法进行过故障处理,但我会尽力而为。现在正在努力。
-
以
int main开头。构建一个新示例可能比复制现有代码容易得多。 -
用示例代码更新了主帖以显示问题。现在我看到它是孤立的,我想知道问题是否更微不足道......
-
不确定这里是否重要,但
trans()是 Matlab / Armadillo 中的厄米共轭,即 R 中的Conj(t())。