cxx11_tensor_convolution.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 Benoit Steiner <benoit.steiner.goog@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 
12 #include <Eigen/CXX11/Tensor>
13 
14 using Eigen::Tensor;
16 
17 template <int DataLayout>
18 static void test_evals()
19 {
20  Tensor<float, 2, DataLayout> input(3, 3);
22 
23  input.setRandom();
24  kernel.setRandom();
25 
27  result.setZero();
29  dims3[0] = 0;
30 
31  typedef TensorEvaluator<decltype(input.convolve(kernel, dims3)), DefaultDevice> Evaluator;
32  Evaluator eval(input.convolve(kernel, dims3), DefaultDevice());
33  eval.evalTo(result.data());
34  EIGEN_STATIC_ASSERT(Evaluator::NumDims==2ul, YOU_MADE_A_PROGRAMMING_MISTAKE);
35  VERIFY_IS_EQUAL(eval.dimensions()[0], 2);
36  VERIFY_IS_EQUAL(eval.dimensions()[1], 3);
37 
38  VERIFY_IS_APPROX(result(0,0), input(0,0)*kernel(0) + input(1,0)*kernel(1)); // index 0
39  VERIFY_IS_APPROX(result(0,1), input(0,1)*kernel(0) + input(1,1)*kernel(1)); // index 2
40  VERIFY_IS_APPROX(result(0,2), input(0,2)*kernel(0) + input(1,2)*kernel(1)); // index 4
41  VERIFY_IS_APPROX(result(1,0), input(1,0)*kernel(0) + input(2,0)*kernel(1)); // index 1
42  VERIFY_IS_APPROX(result(1,1), input(1,1)*kernel(0) + input(2,1)*kernel(1)); // index 3
43  VERIFY_IS_APPROX(result(1,2), input(1,2)*kernel(0) + input(2,2)*kernel(1)); // index 5
44 }
45 
46 template <int DataLayout>
47 static void test_expr()
48 {
49  Tensor<float, 2, DataLayout> input(3, 3);
50  Tensor<float, 2, DataLayout> kernel(2, 2);
51  input.setRandom();
52  kernel.setRandom();
53 
56  dims[0] = 0;
57  dims[1] = 1;
58  result = input.convolve(kernel, dims);
59 
60  VERIFY_IS_APPROX(result(0,0), input(0,0)*kernel(0,0) + input(0,1)*kernel(0,1) +
61  input(1,0)*kernel(1,0) + input(1,1)*kernel(1,1));
62  VERIFY_IS_APPROX(result(0,1), input(0,1)*kernel(0,0) + input(0,2)*kernel(0,1) +
63  input(1,1)*kernel(1,0) + input(1,2)*kernel(1,1));
64  VERIFY_IS_APPROX(result(1,0), input(1,0)*kernel(0,0) + input(1,1)*kernel(0,1) +
65  input(2,0)*kernel(1,0) + input(2,1)*kernel(1,1));
66  VERIFY_IS_APPROX(result(1,1), input(1,1)*kernel(0,0) + input(1,2)*kernel(0,1) +
67  input(2,1)*kernel(1,0) + input(2,2)*kernel(1,1));
68 }
69 
70 template <int DataLayout>
71 static void test_modes() {
74  input(0) = 1.0f;
75  input(1) = 2.0f;
76  input(2) = 3.0f;
77  kernel(0) = 0.5f;
78  kernel(1) = 1.0f;
79  kernel(2) = 0.0f;
80 
82  dims[0] = 0;
84 
85  // Emulate VALID mode (as defined in
86  // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
87  padding[0] = std::make_pair(0, 0);
89  valid = input.pad(padding).convolve(kernel, dims);
90  VERIFY_IS_EQUAL(valid.dimension(0), 1);
91  VERIFY_IS_APPROX(valid(0), 2.5f);
92 
93  // Emulate SAME mode (as defined in
94  // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
95  padding[0] = std::make_pair(1, 1);
97  same = input.pad(padding).convolve(kernel, dims);
98  VERIFY_IS_EQUAL(same.dimension(0), 3);
99  VERIFY_IS_APPROX(same(0), 1.0f);
100  VERIFY_IS_APPROX(same(1), 2.5f);
101  VERIFY_IS_APPROX(same(2), 4.0f);
102 
103  // Emulate FULL mode (as defined in
104  // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
105  padding[0] = std::make_pair(2, 2);
107  full = input.pad(padding).convolve(kernel, dims);
108  VERIFY_IS_EQUAL(full.dimension(0), 5);
109  VERIFY_IS_APPROX(full(0), 0.0f);
110  VERIFY_IS_APPROX(full(1), 1.0f);
111  VERIFY_IS_APPROX(full(2), 2.5f);
112  VERIFY_IS_APPROX(full(3), 4.0f);
113  VERIFY_IS_APPROX(full(4), 1.5f);
114 }
115 
116 template <int DataLayout>
117 static void test_strides() {
120  input.setRandom();
121  kernel.setRandom();
122 
124  dims[0] = 0;
125  Eigen::array<ptrdiff_t, 1> stride_of_3;
126  stride_of_3[0] = 3;
127  Eigen::array<ptrdiff_t, 1> stride_of_2;
128  stride_of_2[0] = 2;
129 
131  result = input.stride(stride_of_3).convolve(kernel, dims).stride(stride_of_2);
132 
133  VERIFY_IS_EQUAL(result.dimension(0), 2);
134  VERIFY_IS_APPROX(result(0), (input(0)*kernel(0) + input(3)*kernel(1) +
135  input(6)*kernel(2)));
136  VERIFY_IS_APPROX(result(1), (input(6)*kernel(0) + input(9)*kernel(1) +
137  input(12)*kernel(2)));
138 }
139 
140 EIGEN_DECLARE_TEST(cxx11_tensor_convolution)
141 {
142  CALL_SUBTEST(test_evals<ColMajor>());
143  CALL_SUBTEST(test_evals<RowMajor>());
144  CALL_SUBTEST(test_expr<ColMajor>());
145  CALL_SUBTEST(test_expr<RowMajor>());
146  CALL_SUBTEST(test_modes<ColMajor>());
147  CALL_SUBTEST(test_modes<RowMajor>());
148  CALL_SUBTEST(test_strides<ColMajor>());
149  CALL_SUBTEST(test_strides<RowMajor>());
150 }
Eigen::Tensor::dimension
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n) const
Definition: Tensor.h:101
Eigen::Tensor
The tensor class.
Definition: Tensor.h:63
Eigen::array
Definition: EmulateArray.h:21
VERIFY_IS_EQUAL
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:386
EIGEN_DECLARE_TEST
EIGEN_DECLARE_TEST(cxx11_tensor_convolution)
Definition: cxx11_tensor_convolution.cpp:140
result
Values result
Definition: OdometryOptimize.cpp:8
Eigen::DefaultDevice
Definition: TensorDeviceDefault.h:17
test_strides
static void test_strides()
Definition: cxx11_tensor_convolution.cpp:117
test_expr
static void test_expr()
Definition: cxx11_tensor_convolution.cpp:47
test_evals
static void test_evals()
Definition: cxx11_tensor_convolution.cpp:18
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
VERIFY_IS_APPROX
#define VERIFY_IS_APPROX(a, b)
Definition: integer_types.cpp:15
Eigen::TensorBase< Tensor< Scalar_, NumIndices_, Options_, IndexType_ > >::setRandom
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor< Scalar_, NumIndices_, Options_, IndexType_ > & setRandom()
Definition: TensorBase.h:996
test_modes
static void test_modes()
Definition: cxx11_tensor_convolution.cpp:71
EIGEN_STATIC_ASSERT
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
Definition: StaticAssert.h:127
main.h
Eigen::TensorEvaluator
A cost model used to limit the number of threads used for evaluating tensor expression.
Definition: TensorEvaluator.h:28
Eigen::TensorBase< Tensor< Scalar_, NumIndices_, Options_, IndexType_ > >::stride
EIGEN_DEVICE_FUNC const EIGEN_STRONG_INLINE TensorStridingOp< const Strides, const Tensor< Scalar_, NumIndices_, Options_, IndexType_ > > stride(const Strides &strides) const
Definition: TensorBase.h:1134
eval
internal::nested_eval< T, 1 >::type eval(const T &xpr)
Definition: sparse_permutations.cpp:38
CALL_SUBTEST
#define CALL_SUBTEST(FUNC)
Definition: main.h:399


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:02:08