TMB Documentation  v1.9.11
fft.hpp
1 #include <unsupported/Eigen/FFT>
2 
3 namespace atomic {
4 
5 template<bool adjoint=false>
6 void fft_work(const CppAD::vector<double> &x,
7  CppAD::vector<double> &y) {
8  int ncplx = x.size() / 2;
9  typedef std::complex<double> C;
10  C* X = (C*) x.data();
11  C* Y = (C*) y.data();
12  Eigen::FFT<double> f;
13  // How Eigen/FFT differs: invertible scaling is performed
14  f.SetFlag(f.Unscaled);
15  if (!adjoint)
16  f.fwd(Y, X, ncplx);
17  else
18  f.inv(Y, X, ncplx);
19 }
20 
21 TMB_ATOMIC_VECTOR_FUNCTION_DECLARE(fft) // So can be used by ifft
22 TMB_ATOMIC_VECTOR_FUNCTION_DECLARE(ifft) // So can be used by fft
23 TMB_ATOMIC_VECTOR_FUNCTION_DEFINE( fft, tx.size(), fft_work<0>(tx, ty), px = ifft(py))
24 TMB_ATOMIC_VECTOR_FUNCTION_DEFINE(ifft, tx.size(), fft_work<1>(tx, ty), px = fft(py))
25 
34 template<class Type>
35 vector<std::complex<Type> > fft(vector<std::complex<Type> > xc,
36  bool inverse = false) {
37  CppAD::vector<Type> x(2 * xc.size());
38  Type* px = x.data();
39  Type* pxc = (Type*) xc.data();
40  for (size_t i=0; i<x.size(); i++) {
41  px[i] = pxc[i];
42  }
43  CppAD::vector<Type> y;
44  if (!inverse)
45  y = atomic::fft(x);
46  else
47  y = atomic::ifft(x);
48  px = (Type*) y.data();
49  for (size_t i=0; i<x.size(); i++) {
50  pxc[i] = px[i];
51  }
52  return xc;
53 }
54 
55 }
Vector class used by TMB.
Definition: vector.hpp:17
Namespace with special functions and derivatives.
vector< std::complex< Type > > fft(vector< std::complex< Type > > xc, bool inverse=false)
FFT (unscaled)
Definition: fft.hpp:35
License: GPL v2