10#include <unsupported/Eigen/CXX11/Tensor>
11#include "../Math/FFT.h"
19 const Eigen::array<Eigen::Index, dim>
d;
21 explicit Diff(
const Eigen::array<Eigen::Index, dim> &d_,
22 const Eigen::Matrix<double, dim, dim> &A,
23 const Eigen::array<Eigen::Index, dim> &n_)
25 for (
const auto &order :
d)
29 template <
int dm = dim>
30 typename std::enable_if<dm == 1, void>::type
perform_op(
const double *x_in,
31 double *y_out)
const {
32 Eigen::TensorMap<const Eigen::Tensor<double, dm>> xReal(x_in,
n);
33 const Eigen::Tensor<dcomplex, dm> x = xReal.template cast<dcomplex>();
34 Eigen::TensorMap<Eigen::Tensor<double, dm>> y(y_out,
n);
38 for (
const auto &order :
d) {
39 totalOrder = totalOrder + order;
41 if (totalOrder == 0) {
47 Eigen::Tensor<dcomplex, dm> xhat(
n);
51 Eigen::Tensor<dcomplex, dm> d2fhat(
n);
55 for (
int i = 0; i <
n[0]; ++i) {
58 for (
int k = 0; k < dim; ++k) {
61 else if (
d[k] % 2 == 0)
62 r << (i <=
n[0] / 2 ? i : i -
n[0]);
64 r << (i ==
n[0] / 2 ? 0 : -
n[0] * (i / (
n[0] / 2)) + i);
65 factor = factor * std::pow(-2.0 * std::numbers::pi *
dcomplex(0, 1) *
69 d2fhat(i) = xhat(i) * factor;
73 Eigen::Tensor<dcomplex, dm> Lf(
n);
79 template <
int dm = dim>
80 typename std::enable_if<dm == 2, void>::type
perform_op(
const double *x_in,
81 double *y_out)
const {
82 Eigen::TensorMap<const Eigen::Tensor<double, 2>> xReal(x_in,
n);
83 const Eigen::Tensor<dcomplex, 2> x = xReal.cast<
dcomplex>();
84 Eigen::TensorMap<Eigen::Tensor<double, 2>> y(y_out,
n);
88 for (
const auto &order :
d) {
89 totalOrder = totalOrder + order;
91 if (totalOrder == 0) {
97 Eigen::Tensor<dcomplex, 2> xhat(
n);
101 Eigen::Tensor<dcomplex, 2> d2fhat(
n);
105 for (
int i = 0; i <
n[0]; ++i) {
106 for (
int j = 0; j <
n[1]; ++j) {
109 for (
int k = 0; k < dim; ++k) {
112 else if (
d[k] % 2 == 0)
113 r << (i <=
n[0] / 2 ? i : i -
n[0]), (j <=
n[1] / 2 ? j : j -
n[1]);
115 r << (i ==
n[0] / 2 ? 0 : -
n[0] * (i / (
n[0] / 2)) + i),
116 (j ==
n[1] / 2 ? 0 : -
n[1] * (j / (
n[1] / 2)) + j);
117 factor = factor * std::pow(-2.0 * std::numbers::pi *
dcomplex(0, 1) *
121 d2fhat(i, j) = xhat(i, j) * factor;
126 Eigen::Tensor<dcomplex, 2> Lf(
n);
132 template <
int dm = dim>
133 typename std::enable_if<dm == 3, void>::type
perform_op(
const double *x_in,
134 double *y_out)
const {
135 Eigen::TensorMap<const Eigen::Tensor<double, dm>> xReal(x_in,
n);
136 const Eigen::Tensor<dcomplex, dm> x = xReal.template cast<dcomplex>();
137 Eigen::TensorMap<Eigen::Tensor<double, dm>> y(y_out,
n);
141 for (
const auto &order :
d) {
142 totalOrder = totalOrder + order;
144 if (totalOrder == 0) {
150 Eigen::Tensor<dcomplex, dm> xhat(
n);
154 Eigen::Tensor<dcomplex, dm> d2fhat(
n);
158 for (
int i = 0; i <
n[0]; ++i) {
159 for (
int j = 0; j <
n[1]; ++j) {
160 for (
int k = 0; k <
n[2]; ++k) {
163 for (
int l = 0; l < dm; ++l) {
166 else if (
d[l] % 2 == 0)
167 r << (i <=
n[0] / 2 ? i : i -
n[0]),
168 (j <=
n[1] / 2 ? j : j -
n[1]),
169 (k <=
n[2] / 2 ? k : k -
n[2]);
171 r << (i ==
n[0] / 2 ? 0 : -
n[0] * (i / (
n[0] / 2)) + i),
172 (j ==
n[1] / 2 ? 0 : -
n[1] * (j / (
n[1] / 2)) + j),
173 (k ==
n[2] / 2 ? 0 : -
n[2] * (k / (
n[2] / 2)) + k);
174 factor = factor * std::pow(-2.0 * std::numbers::pi *
178 d2fhat(i, j, k) = xhat(i, j, k) * factor;
184 Eigen::Tensor<dcomplex, dm> Lf(
n);
static void ifft(const Eigen::Tensor< dcomplex, 3 > &in, Eigen::Tensor< dcomplex, 3 > &out)
static void fft(const Eigen::Tensor< dcomplex, 3 > &in, Eigen::Tensor< dcomplex, 3 > &out)
Diff(const Eigen::array< Eigen::Index, dim > &d_, const Eigen::Matrix< double, dim, dim > &A, const Eigen::array< Eigen::Index, dim > &n_)
std::enable_if< dm==1, void >::type perform_op(const double *x_in, double *y_out) const
std::enable_if< dm==3, void >::type perform_op(const double *x_in, double *y_out) const
const Eigen::array< Eigen::Index, dim > d
std::enable_if< dm==2, void >::type perform_op(const double *x_in, double *y_out) const
std::complex< double > dcomplex
const Eigen::array< Eigen::Index, dim > n
VectorDimD cartesian() const