简体   繁体   English

RcppArmadillo ifft2与R的原生mvfft

[英]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. 不幸的是, ifft2RcppArmadillo )和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 问题

  • Is the RcppArmadillo FFT still in development? RcppArmadillo FFT是否还在开发中?
  • Is this a common issue across FFT variants(numerical deviations outside of FP or DP noise)? 这是FFT变量中的常见问题吗(FP或DP噪声之外的数字偏差)?
  • Is there a 'low-level' function call from Rcpp or RcppArmadillo to call R's native FFT? Rcpp或RcppArmadillo是否有“低级”函数调用来调用R的本机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: 我不太喜欢你的例子:

  • as it is still way too complex 因为它仍然太复杂
  • you are transforming data in the functions you are comparing -- generally a bad idea 您正在比较的函数中转换数据-通常是一个坏主意
  • so I would suggest you fix your inputs 所以我建议您修正您的输入

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 这里的主要问题是

  • not reading the documentation carefully 没有仔细阅读文档
  • not working with a minimal examples 没有最小的例子

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM