RcppArmadillo
がFFT & 2-D FFTをサポートしています。残念ながら、ifft2
(RcppArmadillo
)とRのネイティブmvfft(..., inverse = TRUE)
には大きな違いがあります。これは、特に私のアプリケーションでは非常に重要なゼロビンで大きくなります。違いはスカラー倍数ではありません。私はこれらの逸脱のためのドキュメンテーションやアカウントを特に第0ビンに見つけることはできません。RcppArmadillo ifft2対Rのネイティブmvfft
特に、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
質問
- はあり
RcppArmadillo
FFTはまだ開発中ですか? - これはFFTバリアント(FPまたはDPノイズ外の数値偏差)でよく見られる問題ですか?
- RのネイティブFFTを呼び出すためにRcppまたはRcppArmadilloからの「低レベル」関数呼び出しがありますか?
再現性 - 以下では問題を凝縮して問題を再現しました。
#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アルゴリズムをトラブルシューティングしたことはありませんでしたが、最善を尽くします。今すぐそれに取り組む。 – caseyk
'int main'で始まります。既存のコードをコピーするよりも、新鮮なサンプルを作成する方がはるかに簡単です。 –