fftwtools/ 0000755 0001762 0000144 00000000000 14017172673 012311 5 ustar ligges users fftwtools/NAMESPACE 0000644 0001762 0000144 00000000356 14014563614 013530 0 ustar ligges users #exportPattern("^[^\\.]")
export( fftw, fftw2d, fftw3d, fftw_c2c, fftw_c2c_2d, fftw_c2c_3d, fftw_c2c_xd, fftw_c2r, fftw_r2c, fftw_r2c_2d, fftw_r2c_3d, mvfftw, mvfftw_c2c, mvfftw_c2r, mvfftw_r2c)
useDynLib(fftwtools, .registration = TRUE)
fftwtools/man/ 0000755 0001762 0000144 00000000000 14014563614 013060 5 ustar ligges users fftwtools/man/mvfftw.Rd 0000644 0001762 0000144 00000007110 12121155253 014650 0 ustar ligges users % The fftwtools R package
% fftw2d and general mvfftw tools in R
% Copyright (C) 2013 Karim Rahim
%
% Written by Karim Rahim.
%
% This file is part of the fftwtools package for R.
%
% The fftwtools package is free software: you can redistribute it and
% or modify it under the terms of the GNU General Public License as
% published by the Free Software Foundation, either version 2 of the
% License, or any later version.
%
% The fftwtools package is distributed in the hope that it will be
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with fftwtools. If not, see .
%
% If you wish to report bugs please contact the author.
% karim.rahim@gmail.com
% Jeffery Hall, Queen's University, Kingston Ontario
% Canada, K7L 3N6
\name{mvfftw}
\alias{mvfftw}
\alias{mvfftw_c2c}
\alias{mvfftw_r2c}
\alias{mvfftw_c2r}
\title{Compute the FFT on each column of a matrix using FFTW3}
\description{
This will compute the FFT of each column of a matrix using the FFTW3 libraries.
Use mvfftw_r2c(x, HermConj=0) for real to complex fft. This will
return the result without the redundant complex conjugate. This follows the R
convention for returning the unscaled inverse of the FFT. The function
mvfftw_c2r(res, HermConj=0, n=dim(x)[1]) will invert the FFT
from the result not containing the "Hermitian" redundant conjugate. You must
specify, n, the column dimension of the original data--the column
length of the original data--if the redundant complex conjugate is not included.
}
\usage{
mvfftw(data, inverse=0, HermConj=1, n=NULL, fftplanopt=0)
mvfftw(data, inverse=0, HermConj=1, n=NULL, fftplanopt=0)
mvfftw_r2c(data, HermConj=1, fftplanopt=0)
mvfftw_c2c(data, inverse=0, fftplanopt=0)
mvfftw_c2r(data, HermConj=1, n=NULL, fftplanopt=0)
}
\arguments{
\item{data}{(complex or real) matrix of columns to be processed}
\item{inverse}{(integer) 1 or 0 indicating if inverse fft is
preformed. The return follows the format of the R FFT commands. The
result is not scaled.}
\item{HermConj}{(integer) 1 or 0 indicating if either "Hermitian" redundant
conjugate should be returned, or that the complex to real data
includes the "Hermitian" redundant
conjugate.}
\item{n}{(integer) column length of the original data set, when using
the inverse coplex to real fft without providing the "Hermitian" redundant
conjugate.}
\item{fftplanopt}{(integer) 0 or 1 specifying the flag passed to
FFTW. 0 indicates the flag FFTW_ESTIMATE is used, and 1 indicates
FFTW_MEASURE is used. See FFTW documentation for use of these flags.
}
}
\author{Karim Rahim}
\examples{
x=c(1, 2, 3, 9, 8, 5, 1, 2, 9, 8, 7, 2)
x= t(matrix(x, nrow=4))
mvfft(x)
t(mvfft(t(mvfft(x))))
res <- mvfftw_r2c(x, HermConj=1)
res
mvfftw_c2c(res, inverse=1)/3
mvfftw_c2r(res)/3
res <- mvfftw_r2c(x, HermConj=0)
res
mvfftw_c2r(res, HermConj=0, n=3)/3
mvfftw_r2c(x, HermConj=1)
mvfft(x)
res <- mvfftw_r2c(x, HermConj=0)
res
mvfftw_c2r(res, HermConj=0, n=3)/3
res <- mvfftw_r2c(t(x), HermConj=1)
res
mvfftw_c2r(res, HermConj=1)/4
res <- mvfftw_r2c(t(x), HermConj=0)
res
mvfftw_c2r(res, HermConj=0, n=4)/4
mvfftw_r2c(t(x), HermConj=1)
mvfft(t(x))
mvfftw(mvfftw(x, HermConj=0), inverse=1, HermConj=0, n=3)/3
mvfftw(mvfftw(t(x), HermConj=0), inverse=1, HermConj=0, n=4)/4
mvfftw(mvfftw(t(x), inverse=1))/4
}
\keyword{fftw}
fftwtools/man/fftw3d.Rd 0000644 0001762 0000144 00000004322 14014563614 014545 0 ustar ligges users % The fftwtools R package
% fftw2d and general mvfftw tools in R
% Copyright (C) 2013 Karim Rahim
%
% Written by Karim Rahim.
%
% This file is part of the fftwtools package for R.
%
% The fftwtools package is free software: you can redistribute it and
% or modify it under the terms of the GNU General Public License as
% published by the Free Software Foundation, either version 2 of the
% License, or any later version.
%
% The fftwtools package is distributed in the hope that it will be
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with fftwtools. If not, see .
%
% If you wish to report bugs please contact the author.
% karim.rahim@gmail.com
% Jeffery Hall, Queen's University, Kingston Ontario
% Canada, K7L 3N6
\name{fftw3d}
\alias{fftw3d}
\alias{fftw_c2c_3d}
\alias{fftw_r2c_3d}
\title{Compute a two-dimensional FFT on a matrix using FFTW3}
\description{
Computes three-dimensional FFT on an array using the FFTW3 libraries.
Use fftw_r2c_3d(x, HermConj=0) for real to complex FFT. This will
return the result without the "Hermitian" redundancy. These functions follow the R
convention when returning the inverse of the FFT. For the two-dimension
fft, the inverse is currently requires the entire matrix, including the
redundant complex conjugate.
}
\usage{
fftw3d(data, inverse=0, HermConj=1)
fftw_r2c_3d(data, HermConj=1)
fftw_c2c_3d(data, inverse=0)
}
\arguments{
\item{data}{(complex or real) 3-dimensional array to be processed}
\item{inverse}{(integer) 1 or 0 indicating if inverse FFT is
preformed. The return follows the format of the R FFT commands--the
output is not scaled.}
\item{HermConj}{(integer) 1 or 0 indicating if either "Hermitian" redundant
conjugate should be returned.}
}
\author{Karim Rahim}
\examples{
x=c(1, 2, 3, 9, 8, 5, 1, 2, 9, 8, 7, 2)
x= array(x, dim=c(3,2,2))
fftw3d(x)
fftw3d(x, HermConj=0)
fftw3d(fftw3d(x), inverse=1)/12
fftw_r2c_3d(x)
fftw_r2c_3d(x, HermConj=0)
}
\keyword{fftw}
fftwtools/man/fftw2d.Rd 0000644 0001762 0000144 00000004771 13736207504 014557 0 ustar ligges users % The fftwtools R package
% fftw2d and general mvfftw tools in R
% Copyright (C) 2013 Karim Rahim
%
% Written by Karim Rahim.
%
% This file is part of the fftwtools package for R.
%
% The fftwtools package is free software: you can redistribute it and
% or modify it under the terms of the GNU General Public License as
% published by the Free Software Foundation, either version 2 of the
% License, or any later version.
%
% The fftwtools package is distributed in the hope that it will be
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with fftwtools. If not, see .
%
% If you wish to report bugs please contact the author.
% karim.rahim@gmail.com
% Jeffery Hall, Queen's University, Kingston Ontario
% Canada, K7L 3N6
\name{fftw2d}
\alias{fftw2d}
\alias{fftw_c2c_2d}
\alias{fftw_r2c_2d}
\alias{fftw_c2c_xd}
\title{Compute a two-dimensional FFT on a matrix using FFTW3}
\description{
Computes two-dimensional FFT on a matrix using the FFTW3 libraries.
Use fftw_r2c_2d(x, HermConj=0) for real to complex FFT. This will
return the result without the "Hermitian" redundancy. These functions follow the R
convention when returning the inverse of the FFT. For the two-dimension
fft, the inverse is currently requires the entire matrix, including the
redundant complex conjugate.
The function \code{fftw_c2c_xd} can calculate a higher dimensional FFT on a higher dimensional array.
}
\usage{
fftw2d(data, inverse=0, HermConj=1)
fftw_r2c_2d(data, HermConj=1)
fftw_c2c_2d(data, inverse=0)
fftw_c2c_xd(data, inverse=0)
}
\arguments{
\item{data}{(complex or real) matrix to be processed (or array for \code{fftw_c2c_xd})}
\item{inverse}{(integer) 1 or 0 indicating if inverse FFT is
preformed. The return follows the format of the R FFT commands--the
output is not scaled.}
\item{HermConj}{(integer) 1 or 0 indicating if either "Hermitian" redundant
conjugate should be returned.}
}
\author{Karim Rahim and Ege Rubak}
\examples{
x=c(1, 2, 3, 9, 8, 5, 1, 2, 9, 8, 7, 2)
x= t(matrix(x, nrow=4))
mvfft(x)
t(mvfft(t(mvfft(x))))
fftw2d(x)
fftw2d(x, HermConj=0)
fftw2d(fftw2d(x), inverse=1)/12
fftw2d(fftw2d(t(x)), inverse=1)/12
fftw_r2c_2d(x)
fftw_r2c_2d(x, HermConj=0)
fftw_c2c_xd(x)
}
\keyword{fftw}
fftwtools/man/fftw.Rd 0000644 0001762 0000144 00000006053 12121155144 014311 0 ustar ligges users % The fftwtools R package
% fftw2d and general mvfftw tools in R
% Copyright (C) 2013 Karim Rahim
%
% Written by Karim Rahim.
%
% This file is part of the fftwtools package for R.
%
% The fftwtools package is free software: you can redistribute it and
% or modify it under the terms of the GNU General Public License as
% published by the Free Software Foundation, either version 2 of the
% License, or any later version.
%
% The fftwtools package is distributed in the hope that it will be
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with fftwtools. If not, see .
%
% If you wish to report bugs please contact the author.
% karim.rahim@gmail.com
% Jeffery Hall, Queen's University, Kingston Ontario
% Canada, K7L 3N6
\name{fftw}
\alias{fftw}
\alias{fftw_c2c}
\alias{fftw_r2c}
\alias{fftw_c2r}
\title{Compute fft using fftw3}
\description{
These functions compute the FFT using the FFTW3 libraries.
Use fftw_r2c(x, HermConj=0) for real to complex fft. This will
return the result without the redundant complex conjugate. This follows the R
convention for returning the unscaled inverse of the FFT. The function
fftw_c2r(res, HermConj=0, n=length(x)) will invert the FFT
from the result not containing the redundant complex conjugate. You must
specify, n, the dimension of the original data--length--if the
redundant complex conjugate is not included.
}
\usage{
fftw(data, inverse=0, HermConj=1, n=NULL)
fftw(data, inverse=0, HermConj=1, n=NULL)
fftw_r2c(data, HermConj=1)
fftw_c2c(data, inverse=0)
fftw_c2r(data, HermConj=1, n=NULL)
}
\arguments{
\item{data}{(complex or real) vector to be processed}
\item{inverse}{(integer) 1 or 0 indicating if inverse FFT is
preformed. The return follows the format of the R FFT commands--the
output is not scaled.}
\item{HermConj}{(integer) 1 or 0 indicating if either "Hermitian" redundant
conjugate should be returned, or that the complex to real data
includes the "Hermitian" redundant
conjugate.}
\item{n}{(integer) column length of the original data set. This is required when using
the inverse complex to real FFT without providing the "Hermitian" redundant
conjugate.}
}
\author{Karim Rahim}
\examples{
res <- fftw_r2c(1:9)
res
fftw_c2r(res)/9
res
fftw_c2r(res)/9
res <- fftw_r2c(1:10)
res
fftw_c2r(res)/10
res
fftw_c2r(res)/10
res <- fftw_r2c(1:9, HermConj=0)
res
fftw_c2r(res, HermConj=0, n=9)/9
res <- fftw_r2c(1:10, HermConj=0)
res
fftw_c2r(res, HermConj=0, n=10)/10
fftw_r2c(1:3)
fftw_c2r(fftw_r2c(1:3))/3
fftw_c2r(fftw_r2c(1:2))/2
fftw_c2r(fftw_r2c(1:4))/4
fftw_r2c(1:3, HermConj=1)
fftw_c2r(fftw_r2c(1:3, HermConj=0), HermConj=0, n=3)/3
fftw_c2r(fftw_r2c(1:4, HermConj=0), HermConj=0, n=4)/4
fftw_c2r(fftw_r2c(1:20, HermConj=0), HermConj=0, n=20)/20
}
\keyword{fftw}
fftwtools/DESCRIPTION 0000644 0001762 0000144 00000002026 14017172673 014017 0 ustar ligges users Package: fftwtools
Version: 0.9-11
Title: Wrapper for 'FFTW3' Includes: One-Dimensional, Two-Dimensional,
Three-Dimensional, and Multivariate Transforms
Author: Karim Rahim
Maintainer: Karim Rahim
Depends: R (>= 3.0)
SystemRequirements: fftw3 (libfftw3-dev (deb), or fftw-devel (rpm))
Suggests: fftw
Description: Provides a wrapper for several 'FFTW' functions. This package provides access to the two-dimensional 'FFT', the multivariate 'FFT', and the one-dimensional real to complex 'FFT' using the 'FFTW3' library. The package includes the functions fftw() and mvfftw() which are designed to mimic the functionality of the R functions fft() and mvfft(). The 'FFT' functions have a parameter that allows them to not return the redundant complex conjugate when the input is real data.
License: GPL (>= 2)
ByteCompile: true
URL: https://github.com/krahim/fftwtools
NeedsCompilation: yes
Packaged: 2021-02-27 23:01:27 UTC; karim
Repository: CRAN
Date/Publication: 2021-03-01 14:10:02 UTC
fftwtools/build/ 0000755 0001762 0000144 00000000000 14016547507 013411 5 ustar ligges users fftwtools/build/vignette.rds 0000644 0001762 0000144 00000000344 14016547507 015751 0 ustar ligges users QM@+K!譛!/].ahyhޛ}=04=L6
CǮF ae'AkMS)">H Uk|ISF㲌/2jB 4_obc+b7as1aԗzj?TEo=05TըK$AZ! fftwtools/configure.ac 0000644 0001762 0000144 00000002463 14016474006 014576 0 ustar ligges users
## This file is part of fftwtools
## Note this file was copied from the file used in the R FFTW package
## As was the general build principle, and I am indebted to the authors of that
## package.
##
## Process this file with autoconf to produce a configure script.
## Rewritten 22 Feb 2021 by Dirk Eddelbuettel and released under GPL-2 or later
AC_PREREQ(2.61)
## Update this version number along with DESCRIPTION
AC_INIT([fftwtools], [0.9-11])
# Ensure C++ is set up as R expects
: ${R_HOME=`R RHOME`}
if test -z "${R_HOME}"; then
AC_MSG_ERROR([Could not determine R_HOME.])
fi
CC=`"${R_HOME}/bin/R" CMD config CC`
CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS`
AC_REQUIRE_CPP
AC_PROG_CC
## Check for pkg-config
AC_DEFUN([AC_PROG_PKGCONFIG], [AC_CHECK_PROG(PKGCONFIG,pkg-config,yes)])
AC_PROG_PKGCONFIG
## Report failure
if test x"${PKGCONFIG}" != x"yes"; then
AC_MSG_ERROR([pkg-config not found.])
fi
## Determine values
fftw3_cflags=`pkg-config --cflags fftw3`
fftw3_libs=`pkg-config --libs fftw3`
## Substitute in, respected existing values
AC_SUBST([PKG_CFLAGS],["${fftw3_cflags} ${PKG_CFLAGS}"])
AC_SUBST([PKG_LIBS],["${fftw3_libs} ${PKG_LIBS}"])
AC_CONFIG_FILES([src/Makevars])
AC_OUTPUT
echo "
${PACKAGE_NAME} ${PACKAGE_VERSION}
================
compiler flags: ${PKG_CFLAGS}
link argument: ${PKG_LIBS}
"
fftwtools/src/ 0000755 0001762 0000144 00000000000 14016547507 013101 5 ustar ligges users fftwtools/src/fftwtools.h 0000644 0001762 0000144 00000004540 14014563614 015277 0 ustar ligges users /* ## The fftwtools R package */
/* ## fftw2d and general mvfftw tools in R */
/* ## Copyright (C) 2013 Karim Rahim */
/* ## This file is part of the fftwtools package for R. */
/* ## The fftwtools package is free software: you can redistribute it and */
/* ## /or modify */
/* ## it under the terms of the GNU General Public License as published by */
/* ## the Free Software Foundation, either version 2 of the License, or */
/* ## any later version. */
/* ## The fftwtools package is distributed in the hope that it will be */
/* ## useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
/* ## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* ## GNU General Public License for more details. */
/* ## You should have received a copy of the GNU General Public License */
/* ## along with Foobar. If not, see . */
/* ## If you wish to report bugs please contact the author. */
/* ## karim.rahim@gmail.com */
/* ## Jeffery Hall, Queen's University, Kingston Ontario */
/* ## Canada, K7L 3N6 */
#ifndef __FFTWTOOLS_H__
#define __FFTWTOOLS_H__
/* real to complex forward */
void cfft_r2c(int* n, double* data,
double complex* res, int* retHermConj);
/* complex to real backward */
void cfft_c2r(int* n, double complex* data,
double* res);
/* complex to complex --eitherway */
void cfft_c2c(int* n, double complex* data,
double complex* res, int* inverse);
void cmvfft_r2c(int *n, int *m, double* data,
double complex* res,
int* fftwplanopt);
void cmvfft_c2r(int *n, int *m, double complex* data,
double* res, int* fftwplanopt);
void cmvfft_c2c(int *n, int *m, double complex* data,
double complex* res, int* inverse, int* fftwplanopt);
void cfft_r2c_2d(int* nx, int* ny, double* data, double complex* res);
void cfft_c2c_2d(int* nx, int* ny, double complex* data,
double complex* res, int* inverse);
void cfft_r2c_3d(int* nx, int* ny, int *nz, double* data, double complex* res);
void cfft_c2c_3d(int* nx, int* ny, int *nz, double complex* data,
double complex* res, int* inverse);
void cfft_c2c_xd(int* r, int* n, double complex* data,
double complex* res, int* inverse);
#endif
fftwtools/src/fftwtools.c 0000644 0001762 0000144 00000013050 14014563614 015266 0 ustar ligges users /* ## The fftwtools R package */
/* ## fftw2d and general mvfftw tools in R */
/* ## Copyright (C) 2013 Karim Rahim */
/* ## This file is part of the fftwtools package for R. */
/* ## The fftwtools package is free software: you can redistribute it and */
/* ## /or modify */
/* ## it under the terms of the GNU General Public License as published by */
/* ## the Free Software Foundation, either version 2 of the License, or */
/* ## any later version. */
/* ## The fftwtools package is distributed in the hope that it will be */
/* ## useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
/* ## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* ## GNU General Public License for more details. */
/* ## You should have received a copy of the GNU General Public License */
/* ## along with Foobar. If not, see . */
/* ## If you wish to report bugs please contact the author. */
/* ## karim.rahim@gmail.com */
/* ## Jeffery Hall, Queen's University, Kingston Ontario */
/* ## Canada, K7L 3N6 */
#include
#include
#include"fftwtools.h"
void cfft_r2c(int* n, double* data,
double complex* res, int* retHermConj) {
int i, nc = *n/2 +1;
fftw_plan p;
p = fftw_plan_dft_r2c_1d(*n, data, res, FFTW_ESTIMATE);
fftw_execute(p);
if(*retHermConj == 1) {
for(i=nc; i < *n; i++) {
res[i] = conj(res[*n - i]);
}
}
fftw_destroy_plan(p);
}
void cfft_c2r(int* n, double complex* data,
double* res) {
fftw_plan p;
p = fftw_plan_dft_c2r_1d(*n, data, res, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cfft_c2c(int* n, double complex* data,
double complex* res, int* inverse) {
int sign;
fftw_plan p;
if(*inverse == 1) {
sign = FFTW_BACKWARD;
} else {
sign = FFTW_FORWARD;
}
p = fftw_plan_dft_1d(*n, data, res, sign, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cmvfft_r2c(int *n, int *m, double* data,
double complex* res,
int* fftwplanopt) {
int nc = *n/2 +1;
fftw_plan p;
if(*fftwplanopt == 1 ) {
*fftwplanopt = FFTW_MEASURE;
} else {
*fftwplanopt = FFTW_ESTIMATE;
}
p = fftw_plan_many_dft_r2c(1, n,
*m, data,
NULL, 1,
*n, res,
NULL, 1,
nc, *fftwplanopt);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cmvfft_c2r(int *n, int *m, double complex* data,
double* res, int* fftwplanopt) {
int nc = *n/2 +1;
fftw_plan p;
if(*fftwplanopt == 1 ) {
*fftwplanopt = FFTW_MEASURE;
} else {
*fftwplanopt = FFTW_ESTIMATE;
}
p = fftw_plan_many_dft_c2r(1, n,
*m, data,
NULL, 1,
nc, res,
NULL, 1,
*n, *fftwplanopt);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cmvfft_c2c(int *n, int *m, double complex* data,
double complex* res, int* inverse, int* fftwplanopt) {
int sign;
fftw_plan p;
if(*fftwplanopt == 1 ) {
*fftwplanopt = FFTW_MEASURE;
} else {
*fftwplanopt = FFTW_ESTIMATE;
}
if(*inverse == 1) {
sign = FFTW_BACKWARD;
} else {
sign = FFTW_FORWARD;
}
p = fftw_plan_many_dft(1, n,
*m, data,
NULL, 1,
*n, res,
NULL, 1,
*n, sign, *fftwplanopt);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cfft_r2c_2d(int* nx, int* ny, double* data, double complex* res) {
fftw_plan p;
p = fftw_plan_dft_r2c_2d(*nx, *ny, data, res,
FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cfft_c2c_2d(int* nx, int* ny, double complex* data,
double complex* res, int* inverse) {
int sign;
fftw_plan p;
if(*inverse == 1) {
sign = FFTW_BACKWARD;
} else {
sign = FFTW_FORWARD;
}
p = fftw_plan_dft_2d(*nx, *ny, data, res,
sign, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cfft_r2c_3d(int* nx, int* ny, int *nz, double* data, double complex* res) {
fftw_plan p;
p = fftw_plan_dft_r2c_3d(*nx, *ny, *nz, data, res,
FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cfft_c2c_3d(int* nx, int* ny, int *nz, double complex* data,
double complex* res, int* inverse) {
int sign;
fftw_plan p;
if(*inverse == 1) {
sign = FFTW_BACKWARD;
} else {
sign = FFTW_FORWARD;
}
p = fftw_plan_dft_3d(*nx, *ny, *nz, data, res,
sign, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void cfft_c2c_xd(int* r, int* n, double complex* data,
double complex* res, int* inverse) {
int sign;
fftw_plan p;
if(*inverse == 1) {
sign = FFTW_BACKWARD;
} else {
sign = FFTW_FORWARD;
}
p = fftw_plan_dft(*r, n, data, res, sign, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
fftwtools/src/fftwtools_init.c 0000644 0001762 0000144 00000003032 14014563614 016310 0 ustar ligges users #include // for NULL
#include
/* FIXME:
Check these declarations against the C/Fortran source code.
*/
/* .C calls */
extern void cfft_c2c(void *, void *, void *, void *);
extern void cfft_c2c_2d(void *, void *, void *, void *, void *);
extern void cfft_c2c_3d(void *, void *, void *, void *, void *, void *);
extern void cfft_c2c_xd(void *, void *, void *, void *, void *);
extern void cfft_c2r(void *, void *, void *);
extern void cfft_r2c(void *, void *, void *, void *);
extern void cfft_r2c_2d(void *, void *, void *, void *);
extern void cfft_r2c_3d(void *, void *, void *, void *, void *);
extern void cmvfft_c2c(void *, void *, void *, void *, void *, void *);
extern void cmvfft_c2r(void *, void *, void *, void *, void *);
extern void cmvfft_r2c(void *, void *, void *, void *, void *);
static const R_CMethodDef CEntries[] = {
{"cfft_c2c", (DL_FUNC) &cfft_c2c, 4},
{"cfft_c2c_2d", (DL_FUNC) &cfft_c2c_2d, 5},
{"cfft_c2c_3d", (DL_FUNC) &cfft_c2c_3d, 6},
{"cfft_c2c_xd", (DL_FUNC) &cfft_c2c_xd, 5},
{"cfft_c2r", (DL_FUNC) &cfft_c2r, 3},
{"cfft_r2c", (DL_FUNC) &cfft_r2c, 4},
{"cfft_r2c_2d", (DL_FUNC) &cfft_r2c_2d, 4},
{"cfft_r2c_3d", (DL_FUNC) &cfft_r2c_3d, 5},
{"cmvfft_c2c", (DL_FUNC) &cmvfft_c2c, 6},
{"cmvfft_c2r", (DL_FUNC) &cmvfft_c2r, 5},
{"cmvfft_r2c", (DL_FUNC) &cmvfft_r2c, 5},
{NULL, NULL, 0}
};
void R_init_fftwtools(DllInfo *dll)
{
R_registerRoutines(dll, CEntries, NULL, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
}
fftwtools/src/Makevars.win 0000644 0001762 0000144 00000000726 12301424616 015364 0 ustar ligges users ## This file is copied from the FFTW package and the build script is based
## on the one created by the authors of that package.
##
## Note added May 4, 2013
## I found using win-builder.R-project.org, Uwe's setup, that this file was required for
## a build on windows.
## It is not required on my Linux machine.
## May 5th. I'm confused now as it appears this file is needed for building the package on Linux.
PKG_CPPFLAGS=
PKG_LIBS= -lfftw3 -lm
all: $(SHLIB)
fftwtools/src/Makevars.in 0000644 0001762 0000144 00000000716 14016473715 015205 0 ustar ligges users ## This file is copied from the FFTW package and the build script is based
## on the one created by the authors of that package.
##
## Note added May 4, 2013
## I found using win-builder.R-project.org, Uwe's setup, that this file was required for
## a build on windows.
## It is not required on my Linux machine.
## May 5th. I'm confused now as it appears this file is needed for building the package on Linux.
PKG_CPPFLAGS=@PKG_CFLAGS@
PKG_LIBS=@PKG_LIBS@
fftwtools/vignettes/ 0000755 0001762 0000144 00000000000 14016547506 014321 5 ustar ligges users fftwtools/vignettes/testTimeAndSimpleUse.bib 0000644 0001762 0000144 00000000514 12141054533 021035 0 ustar ligges users @Article{FFTW05,
author = {Frigo, Matteo and Johnson, Steven~G.},
title = {The Design and Implementation of {FFTW3}},
journal = {Proceedings of the IEEE},
year = 2005,
volume = 93,
number = 2,
pages = {216--231},
note = {Special issue on ``Program Generation, Optimization, and Platform Adaptation''}
}
fftwtools/vignettes/auto/ 0000755 0001762 0000144 00000000000 12141250557 015263 5 ustar ligges users fftwtools/vignettes/auto/testTimeAndSimpleUse.el 0000644 0001762 0000144 00000000332 12141250557 021653 0 ustar ligges users (TeX-add-style-hook "testTimeAndSimpleUse"
(lambda ()
(LaTeX-add-bibliographies)
(TeX-run-style-hooks
"inputenc"
"utf8"
"fullpage"
"hyperref"
"latex2e"
"art10"
"article")))
fftwtools/vignettes/testTimeAndSimpleUse.Rnw 0000644 0001762 0000144 00000012552 12301441772 021057 0 ustar ligges users \documentclass{article}
\usepackage{hyperref}
\usepackage{fullpage}
%\usepackage{natbib}
%\usepackage{graphics}
%\usepackage{amsmath}
%\usepackage{indentfirst}
\usepackage[utf8]{inputenc}
% \VignetteIndexEntry{ffttools example and simple use example}
\begin{document}
<>=
options(keep.source = TRUE, width = 60)
fftwtools1 <- packageDescription("fftwtools")
@
\title{FFTWTOOLS Timing and Simple Use (Version \Sexpr{fftwtools1$Version})}
\author{Karim J. Rahim}
\maketitle
\section{Overview}
The package \texttt{fftwtool} provides a wrapper for \texttt{FFTW} code discussed in \cite{FFTW05}.
This vignette provides example code for comparing execution times of \texttt{fftw} from the package \texttt{fftwtools} to the standard \texttt{R} \texttt{fft} function, and it demonstrates how
to replace the \texttt{R} function \texttt{fft} with \texttt{fftw}. The functions \texttt{fftw} and \texttt{mvfftw} mimic the behaviour of the \texttt{R} functions \texttt{fft} and \texttt{mvfft}. There is an \texttt{R} package called \texttt{FFTW} which offers different functionality than fftwtools, specifically it allows the user to set \emph{plans}, and improve the speed with multiple calls to \texttt{fftw} when using data sets of the same size, see \cite{FFTW05}.
\section{Timing Example}
We begin with a demonstration of the speed difference between a simple call to \texttt{fftw} and the default \texttt{fft} function. The performance improvement is visible with large data sets.
Using the example below with $2^{20},$ over one million, data points I observed the following execution times:
\begin{itemize}
\item \texttt{R}'s \texttt{fft}: 19.069 seconds
\item \texttt{fftw} default call: 8.804 seconds
\item \texttt{fftw} with \texttt{HermConj} set to \texttt{FALSE}: 7.594 seconds.
\end{itemize}
You can test timing at any size and decide which function to use.
As the speed advantage from the use of the package \texttt{fftw} is only seen in large examples, I currently use the \texttt{R} \texttt{fft} functions, and I change to \texttt{fftw} only when I encounter significantly large data sets and speed becomes a concern.
To reduce the check and install times of this package, I reduced \texttt{fftLength} from $2^{20}$ to $2^8$ in the code shown in this vignette. The standard \texttt{R} routine is faster using this number of samples, but it is \emph{not} faster with very large data sets.
To compare times, first we look at the time required for the default \texttt{R} \texttt{fft} routine.
<>=
library("fftwtools")
## We increment by powers of 2, but one can use other incrementes
## We choose fftlength = 2^20, but
## **this was reduced to 2^8 for the vignette distribution.**
fftLength <- 2^8
set.seed(10)
g <- rnorm(fftLength)
##Start the clock
ptm <- proc.time()
## Loop through
for (i in 1:100){
fft(g)
}
## Stop the clock
proc.time() - ptm
@
Next we look at replacing \texttt{fft} with \texttt{fftw} without any other changes.
<<>=
##timing # Start the clock!
ptm <- proc.time()
# Loop through
for (i in 1:100){
fftw(g)
}
# Stop the clock
proc.time() - ptm
@
Finally we look to see how much additional improvement can by had by not returning the complex conjugate which is not required for real data. It is likely this speed up is partially due to decreased memory allocation.
<<>=
## Start the clock!
ptm <- proc.time()
## Loop through
for (i in 1:100){
fftw(g, HermConj=FALSE)
}
## Stop the clock
proc.time() - ptm
@
\section{Replace R's \texttt{fft} call with \texttt{fftw}}
The following is a quick and dirty way to replace \texttt{fftw} with \texttt{fftw} in existing code. It is more appropriate to use a conditional statement in the replacement functions to call \texttt{fftw} and \texttt{mvfftw} when the length of $z$ is appropriately large.
<>=
## basic option ot overwrite calls
fft <- function(z, inverse = FALSE) {
fftwtools::fftw(z, inverse=inverse)
}
mvfft <- function(z, inverse=FALSE) {
fftwtools::mvfftw(z, invese=inverse)
}
@
The above is a simple method of replacing all \texttt{fft} calls with \texttt{fftw} calls in the \texttt{multitaper} package which I maintain. If you are interested in the additional improvement available from not returning the unnecessary complex conjugate when using real data, you can overwrite the call setting \texttt{HermConj} to \texttt{FALSE}.
<<>=
fft <- function(z, inverse = FALSE) {
fftwtools::fftw(z, inverse=inverse, HermConj=FALSE)
}
@
The last method is only valid when the input is not complex, and it may break certain calls depending on when the complex conjugate is discarded. If you discard the complex conjugate, you will need the length of the original data to perform an inverse Fourier transform. If you are using the latter method then it may be wise to look into further functionality provided in the \texttt{R} packages \texttt{FFTW} and \texttt{fftwtools}.
\subsection{Clean up}
If you replace the \texttt{R}'s call to \texttt{fft} with \texttt{fftw} then it is good practice to clean up the replacement and restore calls to \texttt{fft} and \texttt{mvfft} to the standard \texttt{R} routine when you are finished using \texttt{fftw}. The following code shows how this cleanup is performed.
<>=
rm(fft, mvfft)
@
\bibliographystyle{plain}
\bibliography{testTimeAndSimpleUse}
\end{document}
fftwtools/R/ 0000755 0001762 0000144 00000000000 14014563614 012506 5 ustar ligges users fftwtools/R/fftwtools.R 0000644 0001762 0000144 00000022456 14014563614 014671 0 ustar ligges users ## The fftwtools R package
## fftw2d and general mvfftw tools in R
## Copyright (C) 2013 Karim Rahim
## This file is part of the fftwtools package for R.
## The fftwtools package is free software: you can redistribute it and
## /or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 2 of the License, or
## any later version.
## The fftwtools package is distributed in the hope that it will be
## useful, but WITHOUT ANY WARRANTY; without even the implied warranty
## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with Foobar. If not, see .
## If you wish to report bugs please contact the author.
## karim.rahim@gmail.com
## Jeffery Hall, Queen's University, Kingston Ontario
## Canada, K7L 3N6
##generic function to call fftw3
## we recommend the FFTW library for setting the plan
fftw <- function(data, inverse=0, HermConj=1, n=NULL) {
res <- NULL
if(inverse==0) {
if(!is.complex(data)) {
res <- fftw_r2c(data, HermConj=HermConj)
} else {
res <- fftw_c2c(data, inverse=0)
}
} else {
if(HermConj==0 && is.complex(data) && is.numeric(n)) {
res <- fftw_c2r(data, HermConj=HermConj, n=n)
} else{
res <- fftw_c2c(data, inverse=1)
}
}
return(res)
}
##generic 2d fft
fftw2d <- function(data, inverse=0, HermConj=1) {
res <- NULL
if(inverse==0) {
if(!is.complex(data)) {
res <- fftw_r2c_2d(data, HermConj=HermConj)
} else {
res <- fftw_c2c_2d(data, inverse=0)
}
} else {
res <- fftw_c2c_2d(data, inverse=1)
}
return(res)
}
##generic 3d fft
fftw3d <- function(data, inverse=0, HermConj=1) {
res <- NULL
if(inverse==0) {
if(!is.complex(data)) {
res <- fftw_r2c_3d(data, HermConj=HermConj)
} else {
res <- fftw_c2c_3d(data, inverse=0)
}
} else {
res <- fftw_c2c_3d(data, inverse=1)
}
return(res)
}
##generic function to call multicol fftw3
mvfftw <- function(data, inverse=0, HermConj=1, n=NULL, fftplanopt=0) {
res <- NULL
if(inverse==0) {
if(!is.complex(data)) {
res <- mvfftw_r2c(data, HermConj=HermConj, fftplanopt=fftplanopt)
} else {
res <- mvfftw_c2c(data, inverse=0, fftplanopt=fftplanopt)
}
} else {
if(HermConj==0 && is.complex(data) && is.numeric(n)) {
res <- mvfftw_c2r(data, HermConj=HermConj, n=n,
fftplanopt=fftplanopt)
} else {
res <- mvfftw_c2c(data, inverse=1, fftplanopt=fftplanopt)
}
}
return(res)
}
fftw_r2c <- function(data, HermConj=1) {
n <- length(data)
nc <- NULL
if(HermConj ==1) {
nc <- n
} else {
nc <- as.integer(n/2) +1
}
out <- .C("cfft_r2c", as.integer(n), as.double(data),
res=complex(nc),
as.integer(HermConj),
PACKAGE="fftwtools")
return(out$res)
}
fftw_c2r <- function(data, HermConj=1, n=NULL) {
##when HermConj == 0, we need the length of the original
## data set.
len <- length(data)
nc <- NULL
if(HermConj==0) {
stopifnot(is.numeric(n))
nc <- as.integer(n/2) + 1
stopifnot(nc == len)
} else {
n <- len
nc <- as.integer(n/2) + 1
}
## only pass what is needed to the C function
out <- .C("cfft_c2r", as.integer(n), as.complex(data[1:nc]),
res=double(n),
PACKAGE = "fftwtools")
return(out$res)
}
fftw_c2c <- function(data, inverse=0) {
n <- length(data)
out <- .C("cfft_c2c", as.integer(n), as.complex(data),
res=complex(n), as.integer(inverse),
PACKAGE = "fftwtools")
return(out$res)
}
mvfftw_r2c <- function(data, HermConj=1, fftplanopt=0) {
data <- as.matrix(data)
n <- dim(data)[1]
m <- dim(data)[2] ## ncol
nc <- as.integer(n/2) +1
out <- .C("cmvfft_r2c", as.integer(n), as.integer(m),
as.double(data),
res=matrix(as.complex(0), nc, m),
as.integer(fftplanopt),
PACKAGE="fftwtools")
res <- as.matrix(out$res)
## moving this routine to C requires making space at the end each column,
## but the data is stored in a contiguous format when returned from
## fftw, and it is easier to manipulate this in R.
if(HermConj==1) {
## if( n %% 2 == 0) {
## res <- rbind(res, Conj(res[(nc-1):2,]))
## } else {
## res <- rbind(res, Conj(res[nc:2,]))
## }
idx <- n-nc+1
res <- rbind(res, Conj(res[idx:2,]))
}
return(res)
}
mvfftw_c2r <- function(data, HermConj=1, n=NULL, fftplanopt=0) {
##HermConj is used to determine the true length, n, of the
##input, fftw does not use the the Hermitian conjugate
## in this case the Hermatian conjugate must be stripped from the data.
data <- as.matrix(data)
##n <- length(data[,1])
len <- dim(data)[1]
m <- dim(data)[2]
nc <- NULL
if(HermConj==0) {
stopifnot(is.numeric(n))
nc <- as.integer(n/2) + 1
stopifnot(nc == len)
} else{
n <- len
nc <- as.integer(n/2) + 1
}
out <- .C("cmvfft_c2r", as.integer(n), as.integer(m),
as.complex(data[1:nc,]),
res=matrix(as.double(0), n, m), as.integer(fftplanopt),
PACKAGE="fftwtools")
return(out$res)
}
mvfftw_c2c <- function(data, inverse=0, fftplanopt=0) {
data <- as.matrix(data)
n <- dim(data)[1]
m <- dim(data)[2]
out <- .C("cmvfft_c2c", as.integer(n), as.integer(m),
as.complex(data),
res=matrix(as.complex(0), n, m),
as.integer(inverse), as.integer(fftplanopt),
PACKAGE="fftwtools")
return(out$res)
}
fftw_r2c_2d <- function(data, HermConj=1) {
## can be done with two mvfft's t(mvfft(t(mvfft(a))))
## == mvfft(t(mvfft(t(a))))
data <- as.matrix(data)
nR <- dim(data)[1]
nC <- dim(data)[2]
nRdiv2 <- nR/2
nRc <- floor(nRdiv2) +1
idxRowAppend <- ceiling(nRdiv2):2
##correct for the fact the c call is column-major
out <- .C("cfft_r2c_2d", as.integer(nC), as.integer(nR),
as.double(data), res=matrix(as.complex(0), nRc , nC),
PACKAGE="fftwtools")
res <- as.matrix(out$res)
if(HermConj==1 && nR > 2) {
if(length(idxRowAppend) == 1) {
##If the number of rows to append is one, R
##will create a column vector for cbind unless
##we transpose.
res <- rbind(res, Conj(cbind(res[2,1],
t(res[2,nC:2]))))
} else {
##With the exception of the first row, the
## resulting matrix is Hermatian --conjugate symmetric
res <- rbind(res, Conj(cbind(res[idxRowAppend,1],
res[idxRowAppend,nC:2])))
}
}
return(res)
}
fftw_c2c_2d <- function(data, inverse=0) {
## can be done with two mvfft's t(mvfft(t(mvfft(a))))
## == mvfft(t(mvfft(t(a))))
data <- as.matrix(data)
nR <- dim(data)[1]
nC <- dim(data)[2]
##we correct for the fact the c call is column-major
out <- .C("cfft_c2c_2d", as.integer(nC), as.integer(nR),
as.complex(data),
res=matrix(as.complex(0), nR , nC),
as.integer(inverse),
PACKAGE="fftwtools")
return(out$res)
}
fftw_r2c_3d <- function(data, HermConj=1) {
n1 <- dim(data)[1]
n2 <- dim(data)[2]
n3 <- dim(data)[3]
n1div2 <- n1/2
n1c <- floor(n1div2) +1
idx1Append <- ceiling(n1div2):2
##correct for the fact the c call is column-major
out <- .C("cfft_r2c_3d", as.integer(n3), as.integer(n2),
as.integer(n1), as.double(data),
res=array(as.complex(0), dim=c(n1c,n2,n3)),
PACKAGE="fftwtools")
if (HermConj==1 && n1 > 2) {
##With the exception of the first row, the
##resulting array is Hermatian --conjugate symmetric
i2 <- if (n2 > 1) c(1,n2:2) else 1
i3 <- if (n3 > 1) c(1,n3:2) else 1
res <- array(NA, c(n1,n2,n3))
res[1:n1c,,] <- out$res
res[(n1c+1):n1,,] <- Conj(out$res[idx1Append,i2,i3])
} else {
res <- out$res
}
return(res)
}
fftw_c2c_3d <- function(data, inverse=0) {
n1 <- dim(data)[1]
n2 <- dim(data)[2]
n3 <- dim(data)[3]
##we correct for the fact the c call is column-major
out <- .C("cfft_c2c_3d", as.integer(n3), as.integer(n2),
as.integer(n1), as.complex(data),
res=array(as.complex(0), dim=dim(data)),
as.integer(inverse),
PACKAGE="fftwtools")
return(out$res)
}
fftw_c2c_xd <- function(data, inverse=0) {
n <- dim(data)
r <- length(n)
##we correct for the fact the c call is column-major
n <- rev(n)
out <- .C("cfft_c2c_xd", as.integer(r), as.integer(n),
as.complex(data),
res=array(as.complex(0), rev(n)),
as.integer(inverse))
return(out$res)
}
fftwtools/MD5 0000644 0001762 0000144 00000002237 14017172673 012625 0 ustar ligges users 880e7c17a01d05accd08dfc8f9966c47 *DESCRIPTION
ed0c7521c81d8c7ac99c93f58609af4a *NAMESPACE
74f20ccee3bc60f65060a4d9de87067c *R/fftwtools.R
f6871ad95b2e7305354060498756f71d *build/vignette.rds
6e19154c3565f0fcb6bff424ce27bcc4 *cleanup
3d28827abf3132c57f3e92b740c58991 *configure
def24f31086da00197d4071f2d5d6d22 *configure.ac
8129170e1bd97b1932d2f25d9167a3cc *inst/doc/testTimeAndSimpleUse.R
25fc2522f2c2e411f178cfb997799d65 *inst/doc/testTimeAndSimpleUse.Rnw
c0499138582a6b229430db0301e77b22 *inst/doc/testTimeAndSimpleUse.pdf
bc3f7c554e70ad7cb85552bf81856e9f *man/fftw.Rd
9529a1969b1ad42bdd1944a3f9e8c935 *man/fftw2d.Rd
3e03fe7785e20fc6c7cb2d655df7443c *man/fftw3d.Rd
33fdd77263f8d69c628964ef8a7c3bda *man/mvfftw.Rd
fddcac97c20ad4f8a5d394372488e106 *src/Makevars.in
d27e1aad57007768487364be2f23ec36 *src/Makevars.win
3ce7ba6ecf4392dbff43fdfe3d103831 *src/fftwtools.c
a85f485d79bcdb5f03d2d51aafad68ff *src/fftwtools.h
3788861d0d869dfc145b7d4546b03714 *src/fftwtools_init.c
0de9eb21a9d5e2d07cf66ad81b4c9f66 *vignettes/auto/testTimeAndSimpleUse.el
25fc2522f2c2e411f178cfb997799d65 *vignettes/testTimeAndSimpleUse.Rnw
685d56ce46c314a52ce2c24be889201e *vignettes/testTimeAndSimpleUse.bib
fftwtools/inst/ 0000755 0001762 0000144 00000000000 14016547506 013266 5 ustar ligges users fftwtools/inst/doc/ 0000755 0001762 0000144 00000000000 14016547506 014033 5 ustar ligges users fftwtools/inst/doc/testTimeAndSimpleUse.R 0000644 0001762 0000144 00000004063 14016547506 020231 0 ustar ligges users ### R code from vignette source 'testTimeAndSimpleUse.Rnw'
###################################################
### code chunk number 1: foo
###################################################
options(keep.source = TRUE, width = 60)
fftwtools1 <- packageDescription("fftwtools")
###################################################
### code chunk number 2: timing1
###################################################
library("fftwtools")
## We increment by powers of 2, but one can use other incrementes
## We choose fftlength = 2^20, but
## **this was reduced to 2^8 for the vignette distribution.**
fftLength <- 2^8
set.seed(10)
g <- rnorm(fftLength)
##Start the clock
ptm <- proc.time()
## Loop through
for (i in 1:100){
fft(g)
}
## Stop the clock
proc.time() - ptm
###################################################
### code chunk number 3: