[英]RcppArmadillo ifft2 Vs R's native mvfft
I have noticed that RcppArmadillo
supports FFT & 2-D FFT. 我注意到RcppArmadillo
支持FFT和2-D FFT。 Unfortunately there is a significant difference between ifft2
( RcppArmadillo
) and R's native mvfft(..., inverse = TRUE)
with my data. 不幸的是, ifft2
( RcppArmadillo
)和R的本机mvfft(..., inverse = TRUE)
与我的数据之间存在显着差异。 This is especially large in the zeroth bin (which is incredibly important in my application). 这在第零个bin中特别大(这在我的应用程序中非常重要)。 The difference is not a scalar multiple. 区别不是标量倍数。 I cannot find any documentation or account for these deviations especially in the zeroth bin. 我找不到任何文档或说明这些偏差,尤其是在第零档中。
I have debugged the issue specifically to the ifft(arma::cx_mat input)
function call. 我已经专门针对ifft(arma::cx_mat input)
函数调用调试了该问题。 Unless perhaps there is an unforeseen memory management issue, this is the culprit. 除非可能存在不可预见的内存管理问题,否则这是罪魁祸首。
Example: ifft2
result(1 column first 5 entries): 示例: 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
inverse result (1 column first 5 entries): mvfft
反结果(1列的前5个条目):
[1] 0.278131988-0.633838170i -0.195699114+0.445980950i
0.060070320-0.136894940i -0.011924932+0.027175865i 0.001754788-0.003999007i
Questions 问题
RcppArmadillo
FFT still in development? RcppArmadillo
FFT是否还在开发中? Reproducibility - Below I condensed the problem as much as I could and reproduced the issue. 可再现性-在下面,我尽我所能地简明扼要地阐述了问题,并重现了该问题。 Updated for minimal code Rcpp code: 更新为最少的代码 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 (sorry this is sloppy) 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
yields : 产量:
> 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
I don't particularly like your example: 我不太喜欢你的例子:
Here is a simpler example. 这是一个简单的例子。 help(fft)
in R leads of with this example 此示例的R引线中的help(fft)
fftR> x <- 1:4
fftR> fft(x)
[1] 10+0i -2+2i -2+0i -2-2i
fftR> fft(fft(x), inverse = TRUE)/length(x)
[1] 1+0i 2+0i 3+0i 4+0i
which we can easily reproduce using RcppArmadillo: 我们可以使用RcppArmadillo轻松地复制它们:
R> cppFunction("arma::cx_mat armafft(arma::vec x) { return fft(x); }",
+ depends="RcppArmadillo")
R> armafft(1:4)
[,1]
[1,] 10+0i
[2,] -2+2i
[3,] -2+0i
[4,] -2-2i
R>
and adding the inverse 并加上逆
R> cppFunction("arma::cx_mat armaifft(arma::cx_mat x) { return ifft(x); }",
+ depends="RcppArmadillo")
R> armaifft(armafft(1:4))
[,1]
[1,] 1+0i
[2,] 2+0i
[3,] 3+0i
[4,] 4+0i
R>
recovering our input as in the R example. 如R示例中那样恢复我们的输入。
No bug as far as I can tell, and I have no reason to believe this is any different for the 2d case... 据我所知,没有错误,而且我没有理由相信这与2d情况有所不同...
Edit/Followup: The error is with the OP, and not with Armadillo. 编辑/跟进:该错误是由OP引起的,与Armadillo无关。 The primary issues here are 这里的主要问题是
The main issue here is that Armadillo's fft()
can work on vectors or matrices and does hence (in the matrix case) correspond to R's mvfft()
. 这里的主要问题是Armadillo的fft()
可以在向量或矩阵上工作,因此(在矩阵情况下)确实对应于R的mvfft()
。 Armadillo's fft2()
is simply something else and not relevant here. Armadillo的fft2()
只是别的东西,与此处无关。
Let us continue / extend our previous example. 让我们继续/扩展前面的示例。 We redefine our accessor to use complex matrix values: 我们重新定义访问器以使用复杂的矩阵值:
R> cppFunction("arma::cx_mat armafft(arma::cx_mat x) { return fft(x); }",
+ depends="RcppArmadillo")
R>
and then define a complex array of dimension 5 x 2 which we feed to it: 然后定义一个尺寸为5 x 2的复杂数组,我们将其馈给它:
R> z <- array(1:10 + 1i, dim=c(5,2))
R> z
[,1] [,2]
[1,] 1+1i 6+1i
[2,] 2+1i 7+1i
[3,] 3+1i 8+1i
[4,] 4+1i 9+1i
[5,] 5+1i 10+1i
R>
R> armafft(z)
[,1] [,2]
[1,] 15.0+5.00000i 40.0+5.00000i
[2,] -2.5+3.44095i -2.5+3.44095i
[3,] -2.5+0.81230i -2.5+0.81230i
[4,] -2.5-0.81230i -2.5-0.81230i
[5,] -2.5-3.44095i -2.5-3.44095i
R>
This is the same output we would get from running the function separately on each column. 这是我们在每一列上分别运行该函数所获得的输出。 And that is also what R does for mvfft()
(cf help(fft)
) 这也是R对mvfft()
所做的工作(cf help(fft)
)
R> mvfft(z)
[,1] [,2]
[1,] 15.0+5.00000i 40.0+5.00000i
[2,] -2.5+3.44095i -2.5+3.44095i
[3,] -2.5+0.81230i -2.5+0.81230i
[4,] -2.5-0.81230i -2.5-0.81230i
[5,] -2.5-3.44095i -2.5-3.44095i
R>
Same result, different libraries / packages, no bug as far as I can see. 结果相同,不同的库/包,据我所知没有错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.