11#ifndef NDARRAY_FFT_FourierOps_h_INCLUDED
12#define NDARRAY_FFT_FourierOps_h_INCLUDED
20#include <boost/noncopyable.hpp>
30static const double M_PI = 4. * atan(1.);
37template <
typename T,
int N>
43 std::complex<T>
const & factor,
44 ArrayRef<std::complex<T>,N,C>
const & array,
45 int const real_last_dim
47 typename ArrayRef<std::complex<T>,N,C>::Iterator iter = array.begin();
48 T u = -2.0 * M_PI * (*offset) / array.size();
49 int kMid = (array.size() + 1) / 2;
50 for (
int k = 0; k < kMid; ++k, ++iter) {
51 FourierOps<T,N-1>::shift(offset+1, factor * std::polar(
static_cast<T
>(1), u * k),
52 *iter, real_last_dim);
54 if (array.size() % 2 == 0) {
55 FourierOps<T,N-1>::shift(offset+1, factor * std::cos(u * kMid), *iter, real_last_dim);
59 for (
int k_n = kMid - array.size(); k_n < 0; ++k_n, ++iter) {
60 FourierOps<T,N-1>::shift(offset+1, factor * std::polar(
static_cast<T
>(1), u * k_n),
61 *iter, real_last_dim);
66 static void differentiate(
int m, ArrayRef<std::complex<T>,N,C>
const & array,
int const real_last_dim) {
67 typename ArrayRef<std::complex<T>,N,C>::Iterator iter = array.begin();
68 int kMid = (array.size() + 1) / 2;
69 T u = 2.0 * M_PI / array.size();
70 for (
int k = 0; k < kMid; ++k, ++iter) {
71 if (m == N) (*iter) *= std::complex<T>(
static_cast<T
>(0), u * T(k));
72 FourierOps<T,N-1>::differentiate(m, *iter, real_last_dim);
74 if (array.size() % 2 == 0) {
75 (*iter) =
static_cast<T
>(0);
79 for (
int k_n = kMid - array.size(); k_n < 0; ++k_n, ++iter) {
80 if (m == N) (*iter) *= std::complex<T>(
static_cast<T
>(0), u * T(k_n));
81 FourierOps<T,N-1>::differentiate(m, *iter, real_last_dim);
92struct FourierOps<T,1> {
97 std::complex<T>
const & factor,
98 ArrayRef<std::complex<T>,1,C>
const & array,
99 int const real_last_dim
101 typename ArrayRef<std::complex<T>,1,C>::Iterator iter = array.begin();
102 T u = -2.0 * M_PI * (*offset) / real_last_dim;
103 int kMid = (real_last_dim + 1) / 2;
104 for (
int k = 0; k < kMid; ++k, ++iter) {
105 (*iter) *= factor * std::polar(1.0, u * T(k));
107 if (real_last_dim % 2 == 0) {
108 (*iter) *= factor * std::cos(u * kMid);
114 static void differentiate(
int m, ArrayRef<std::complex<T>,1,C>
const & array,
int const real_last_dim) {
115 typename ArrayRef<std::complex<T>,1,C>::Iterator iter = array.begin();
116 int kMid = (real_last_dim + 1) / 2;
118 T u = 2.0 * M_PI / real_last_dim;
119 for (
int k = 0; k < kMid; ++k, ++iter) {
120 (*iter) *= std::complex<T>(
static_cast<T
>(0), u * T(k));
123 if (real_last_dim % 2 == 0) {
124 array[kMid] =
static_cast<T
>(0);
138template <
typename T,
int N,
int C>
141 Array<std::complex<T>,N,C>
const & array,
142 int const real_last_dim
144 detail::FourierOps<T,N>::shift(
146 static_cast< std::complex<T>
>(1),
157template <
typename T,
int N,
int C>
160 Array<std::complex<T>,N,C>
const & array,
161 int const real_last_dim
163 detail::FourierOps<T,N>::differentiate(N-n, array.deep(), real_last_dim);
A multidimensional strided array.
Definition Array.h:35
void shift(Vector< T, N > const &offset, Array< std::complex< T >, N, C > const &array, int const real_last_dim)
Perform a Fourier-space translation transform.
Definition FourierOps.h:139
void differentiate(int n, Array< std::complex< T >, N, C > const &array, int const real_last_dim)
Numerically differentiate the array in Fourier-space in the given dimension.
Definition FourierOps.h:158
Main public header file for ndarray.
A fixed-size 1D array class.
Definition Vector.h:82
iterator begin()
Return an iterator to the beginning of the Vector.
Definition Vector.h:111