cxx11_tensor_ifft.cpp
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2014 Jianwei Cui <thucjw@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #include "main.h"
11 #include <complex>
12 #include <cmath>
13 #include <Eigen/CXX11/Tensor>
14 
15 using Eigen::Tensor;
16 
17 template <int DataLayout>
18 static void test_1D_fft_ifft_invariant(int sequence_length) {
19  Tensor<double, 1, DataLayout> tensor(sequence_length);
20  tensor.setRandom();
21 
22  array<int, 1> fft;
23  fft[0] = 0;
24 
25  Tensor<std::complex<double>, 1, DataLayout> tensor_after_fft;
26  Tensor<std::complex<double>, 1, DataLayout> tensor_after_fft_ifft;
27 
28  tensor_after_fft = tensor.template fft<Eigen::BothParts, Eigen::FFT_FORWARD>(fft);
29  tensor_after_fft_ifft = tensor_after_fft.template fft<Eigen::BothParts, Eigen::FFT_REVERSE>(fft);
30 
31  VERIFY_IS_EQUAL(tensor_after_fft.dimension(0), sequence_length);
32  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(0), sequence_length);
33 
34  for (int i = 0; i < sequence_length; ++i) {
35  VERIFY_IS_APPROX(static_cast<float>(tensor(i)), static_cast<float>(std::real(tensor_after_fft_ifft(i))));
36  }
37 }
38 
39 template <int DataLayout>
40 static void test_2D_fft_ifft_invariant(int dim0, int dim1) {
41  Tensor<double, 2, DataLayout> tensor(dim0, dim1);
42  tensor.setRandom();
43 
44  array<int, 2> fft;
45  fft[0] = 0;
46  fft[1] = 1;
47 
48  Tensor<std::complex<double>, 2, DataLayout> tensor_after_fft;
49  Tensor<std::complex<double>, 2, DataLayout> tensor_after_fft_ifft;
50 
51  tensor_after_fft = tensor.template fft<Eigen::BothParts, Eigen::FFT_FORWARD>(fft);
52  tensor_after_fft_ifft = tensor_after_fft.template fft<Eigen::BothParts, Eigen::FFT_REVERSE>(fft);
53 
54  VERIFY_IS_EQUAL(tensor_after_fft.dimension(0), dim0);
55  VERIFY_IS_EQUAL(tensor_after_fft.dimension(1), dim1);
56  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(0), dim0);
57  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(1), dim1);
58 
59  for (int i = 0; i < dim0; ++i) {
60  for (int j = 0; j < dim1; ++j) {
61  //std::cout << "[" << i << "][" << j << "]" << " Original data: " << tensor(i,j) << " Transformed data:" << tensor_after_fft_ifft(i,j) << std::endl;
62  VERIFY_IS_APPROX(static_cast<float>(tensor(i,j)), static_cast<float>(std::real(tensor_after_fft_ifft(i,j))));
63  }
64  }
65 }
66 
67 template <int DataLayout>
68 static void test_3D_fft_ifft_invariant(int dim0, int dim1, int dim2) {
69  Tensor<double, 3, DataLayout> tensor(dim0, dim1, dim2);
70  tensor.setRandom();
71 
72  array<int, 3> fft;
73  fft[0] = 0;
74  fft[1] = 1;
75  fft[2] = 2;
76 
77  Tensor<std::complex<double>, 3, DataLayout> tensor_after_fft;
78  Tensor<std::complex<double>, 3, DataLayout> tensor_after_fft_ifft;
79 
80  tensor_after_fft = tensor.template fft<Eigen::BothParts, Eigen::FFT_FORWARD>(fft);
81  tensor_after_fft_ifft = tensor_after_fft.template fft<Eigen::BothParts, Eigen::FFT_REVERSE>(fft);
82 
83  VERIFY_IS_EQUAL(tensor_after_fft.dimension(0), dim0);
84  VERIFY_IS_EQUAL(tensor_after_fft.dimension(1), dim1);
85  VERIFY_IS_EQUAL(tensor_after_fft.dimension(2), dim2);
86  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(0), dim0);
87  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(1), dim1);
88  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(2), dim2);
89 
90  for (int i = 0; i < dim0; ++i) {
91  for (int j = 0; j < dim1; ++j) {
92  for (int k = 0; k < dim2; ++k) {
93  VERIFY_IS_APPROX(static_cast<float>(tensor(i,j,k)), static_cast<float>(std::real(tensor_after_fft_ifft(i,j,k))));
94  }
95  }
96  }
97 }
98 
99 template <int DataLayout>
100 static void test_sub_fft_ifft_invariant(int dim0, int dim1, int dim2, int dim3) {
101  Tensor<double, 4, DataLayout> tensor(dim0, dim1, dim2, dim3);
102  tensor.setRandom();
103 
104  array<int, 2> fft;
105  fft[0] = 2;
106  fft[1] = 0;
107 
108  Tensor<std::complex<double>, 4, DataLayout> tensor_after_fft;
109  Tensor<double, 4, DataLayout> tensor_after_fft_ifft;
110 
111  tensor_after_fft = tensor.template fft<Eigen::BothParts, Eigen::FFT_FORWARD>(fft);
112  tensor_after_fft_ifft = tensor_after_fft.template fft<Eigen::RealPart, Eigen::FFT_REVERSE>(fft);
113 
114  VERIFY_IS_EQUAL(tensor_after_fft.dimension(0), dim0);
115  VERIFY_IS_EQUAL(tensor_after_fft.dimension(1), dim1);
116  VERIFY_IS_EQUAL(tensor_after_fft.dimension(2), dim2);
117  VERIFY_IS_EQUAL(tensor_after_fft.dimension(3), dim3);
118  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(0), dim0);
119  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(1), dim1);
120  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(2), dim2);
121  VERIFY_IS_EQUAL(tensor_after_fft_ifft.dimension(3), dim3);
122 
123  for (int i = 0; i < dim0; ++i) {
124  for (int j = 0; j < dim1; ++j) {
125  for (int k = 0; k < dim2; ++k) {
126  for (int l = 0; l < dim3; ++l) {
127  VERIFY_IS_APPROX(static_cast<float>(tensor(i,j,k,l)), static_cast<float>(tensor_after_fft_ifft(i,j,k,l)));
128  }
129  }
130  }
131  }
132 }
133 
135  CALL_SUBTEST(test_1D_fft_ifft_invariant<ColMajor>(4));
136  CALL_SUBTEST(test_1D_fft_ifft_invariant<ColMajor>(16));
137  CALL_SUBTEST(test_1D_fft_ifft_invariant<ColMajor>(32));
138  CALL_SUBTEST(test_1D_fft_ifft_invariant<ColMajor>(1024*1024));
139 
140  CALL_SUBTEST(test_2D_fft_ifft_invariant<ColMajor>(4,4));
141  CALL_SUBTEST(test_2D_fft_ifft_invariant<ColMajor>(8,16));
142  CALL_SUBTEST(test_2D_fft_ifft_invariant<ColMajor>(16,32));
143  CALL_SUBTEST(test_2D_fft_ifft_invariant<ColMajor>(1024,1024));
144 
145  CALL_SUBTEST(test_3D_fft_ifft_invariant<ColMajor>(4,4,4));
146  CALL_SUBTEST(test_3D_fft_ifft_invariant<ColMajor>(8,16,32));
147  CALL_SUBTEST(test_3D_fft_ifft_invariant<ColMajor>(16,4,8));
148  CALL_SUBTEST(test_3D_fft_ifft_invariant<ColMajor>(256,256,256));
149 
150  CALL_SUBTEST(test_sub_fft_ifft_invariant<ColMajor>(4,4,4,4));
151  CALL_SUBTEST(test_sub_fft_ifft_invariant<ColMajor>(8,16,32,64));
152  CALL_SUBTEST(test_sub_fft_ifft_invariant<ColMajor>(16,4,8,12));
153  CALL_SUBTEST(test_sub_fft_ifft_invariant<ColMajor>(64,64,64,64));
154 }
EIGEN_DEVICE_FUNC RealReturnType real() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n) const
Definition: Tensor.h:101
static void test_sub_fft_ifft_invariant(int dim0, int dim1, int dim2, int dim3)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor< Scalar_, NumIndices_, Options_, IndexType_ > & setRandom()
Definition: TensorBase.h:848
static void test_3D_fft_ifft_invariant(int dim0, int dim1, int dim2)
static void test_2D_fft_ifft_invariant(int dim0, int dim1)
static void test_1D_fft_ifft_invariant(int sequence_length)
void test_cxx11_tensor_ifft()
The tensor class.
Definition: Tensor.h:63


hebiros
Author(s): Xavier Artache , Matthew Tesch
autogenerated on Thu Sep 3 2020 04:08:09