TensorBase.h
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 #ifndef EIGEN_CXX11_TENSOR_TENSOR_BASE_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_BASE_H
12 
13 // clang-format off
14 
15 namespace Eigen {
16 
26 template<typename Derived>
27 class TensorBase<Derived, ReadOnlyAccessors>
28 {
29  public:
30  typedef internal::traits<Derived> DerivedTraits;
31  typedef typename DerivedTraits::Scalar Scalar;
32  typedef typename DerivedTraits::Index Index;
33  typedef typename internal::remove_const<Scalar>::type CoeffReturnType;
34  typedef typename internal::packet_traits<CoeffReturnType>::type PacketReturnType;
35  static const int NumDimensions = DerivedTraits::NumDimensions;
36 
37  // Generic nullary operation support.
38  template <typename CustomNullaryOp> EIGEN_DEVICE_FUNC
39  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<CustomNullaryOp, const Derived>
40  nullaryExpr(const CustomNullaryOp& func) const {
41  return TensorCwiseNullaryOp<CustomNullaryOp, const Derived>(derived(), func);
42  }
43 
44  // Coefficient-wise nullary operators
45  EIGEN_DEVICE_FUNC
46  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived>
47  constant(const Scalar& value) const {
48  return nullaryExpr(internal::scalar_constant_op<Scalar>(value));
49  }
50 
51  EIGEN_DEVICE_FUNC
52  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::UniformRandomGenerator<Scalar>, const Derived>
53  random() const {
54  return nullaryExpr(internal::UniformRandomGenerator<Scalar>());
55  }
56  template <typename RandomGenerator> EIGEN_DEVICE_FUNC
57  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<RandomGenerator, const Derived>
58  random(const RandomGenerator& gen = RandomGenerator()) const {
59  return nullaryExpr(gen);
60  }
61 
62  // Tensor generation
63  template <typename Generator> EIGEN_DEVICE_FUNC
64  EIGEN_STRONG_INLINE const TensorGeneratorOp<Generator, const Derived>
65  generate(const Generator& generator) const {
66  return TensorGeneratorOp<Generator, const Derived>(derived(), generator);
67  }
68 
69  // Generic unary operation support.
70  template <typename CustomUnaryOp> EIGEN_DEVICE_FUNC
71  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<CustomUnaryOp, const Derived>
72  unaryExpr(const CustomUnaryOp& func) const {
73  return TensorCwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
74  }
75 
76  // Coefficient-wise unary operators
77  EIGEN_DEVICE_FUNC
78  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>
79  operator-() const {
80  return unaryExpr(internal::scalar_opposite_op<Scalar>());
81  }
82 
83  EIGEN_DEVICE_FUNC
84  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived>
85  sqrt() const {
86  return unaryExpr(internal::scalar_sqrt_op<Scalar>());
87  }
88 
89  EIGEN_DEVICE_FUNC
90  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rsqrt_op<Scalar>, const Derived>
91  rsqrt() const {
92  return unaryExpr(internal::scalar_rsqrt_op<Scalar>());
93  }
94 
95  EIGEN_DEVICE_FUNC
96  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived>
97  square() const {
98  return unaryExpr(internal::scalar_square_op<Scalar>());
99  }
100 
101  EIGEN_DEVICE_FUNC
102  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived>
103  cube() const {
104  return unaryExpr(internal::scalar_cube_op<Scalar>());
105  }
106 
107  EIGEN_DEVICE_FUNC
108  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived>
109  inverse() const {
110  return unaryExpr(internal::scalar_inverse_op<Scalar>());
111  }
112 
113  EIGEN_DEVICE_FUNC
114  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived>
115  tanh() const {
116  return unaryExpr(internal::scalar_tanh_op<Scalar>());
117  }
118 
119  EIGEN_DEVICE_FUNC
120  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sigmoid_op<Scalar>, const Derived>
121  sigmoid() const {
122  return unaryExpr(internal::scalar_sigmoid_op<Scalar>());
123  }
124 
125  EIGEN_DEVICE_FUNC
126  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived>
127  exp() const {
128  return unaryExpr(internal::scalar_exp_op<Scalar>());
129  }
130 
131  EIGEN_DEVICE_FUNC
132  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived>
133  log() const {
134  return unaryExpr(internal::scalar_log_op<Scalar>());
135  }
136 
137  EIGEN_DEVICE_FUNC
138  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived>
139  abs() const {
140  return unaryExpr(internal::scalar_abs_op<Scalar>());
141  }
142 
143  EIGEN_DEVICE_FUNC
144  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_pow_op<Scalar>, const Derived>
145  pow(Scalar exponent) const {
146  return unaryExpr(internal::scalar_pow_op<Scalar>(exponent));
147  }
148 
149  EIGEN_DEVICE_FUNC
150  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_add_op<Scalar>, const Derived>
151  operator+ (Scalar rhs) const {
152  return unaryExpr(internal::scalar_add_op<Scalar>(rhs));
153  }
154 
155  EIGEN_DEVICE_FUNC
156  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sub_op<Scalar>, const Derived>
157  operator- (Scalar rhs) const {
158  EIGEN_STATIC_ASSERT((std::numeric_limits<Scalar>::is_signed || internal::is_same<Scalar, const std::complex<float> >::value), YOU_MADE_A_PROGRAMMING_MISTAKE);
159  return unaryExpr(internal::scalar_sub_op<Scalar>(rhs));
160  }
161 
162  EIGEN_DEVICE_FUNC
163  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const Derived>
164  operator* (Scalar rhs) const {
165  return unaryExpr(internal::scalar_multiple_op<Scalar>(rhs));
166  }
167 
168  EIGEN_DEVICE_FUNC
169  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_quotient1_op<Scalar>, const Derived>
170  operator/ (Scalar rhs) const {
171  // EIGEN_STATIC_ASSERT(!std::numeric_limits<Scalar>::is_integer, YOU_MADE_A_PROGRAMMING_MISTAKE);
172  return unaryExpr(internal::scalar_quotient1_op<Scalar>(rhs));
173  }
174 
175  EIGEN_DEVICE_FUNC
176  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
177  cwiseMax(Scalar threshold) const {
178  return cwiseMax(constant(threshold));
179  }
180 
181  EIGEN_DEVICE_FUNC
182  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
183  cwiseMin(Scalar threshold) const {
184  return cwiseMin(constant(threshold));
185  }
186 
187  template <typename NewType> EIGEN_DEVICE_FUNC
188  EIGEN_STRONG_INLINE const TensorConversionOp<NewType, const Derived>
189  cast() const {
190  return TensorConversionOp<NewType, const Derived>(derived());
191  }
192 
193  // Generic binary operation support.
194  template <typename CustomBinaryOp, typename OtherDerived> EIGEN_DEVICE_FUNC
195  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
196  binaryExpr(const OtherDerived& other, const CustomBinaryOp& func) const {
197  return TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other, func);
198  }
199 
200  // Coefficient-wise binary operators.
201  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
202  const TensorCwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const OtherDerived>
203  operator+(const OtherDerived& other) const {
204  return binaryExpr(other.derived(), internal::scalar_sum_op<Scalar>());
205  }
206 
207  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
208  const TensorCwiseBinaryOp<internal::scalar_difference_op<Scalar>, const Derived, const OtherDerived>
209  operator-(const OtherDerived& other) const {
210  return binaryExpr(other.derived(), internal::scalar_difference_op<Scalar>());
211  }
212 
213  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
214  const TensorCwiseBinaryOp<internal::scalar_product_op<Scalar>, const Derived, const OtherDerived>
215  operator*(const OtherDerived& other) const {
216  return binaryExpr(other.derived(), internal::scalar_product_op<Scalar>());
217  }
218 
219  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
220  const TensorCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>
221  operator/(const OtherDerived& other) const {
222  return binaryExpr(other.derived(), internal::scalar_quotient_op<Scalar>());
223  }
224 
225  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
226  const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const OtherDerived>
227  cwiseMax(const OtherDerived& other) const {
228  return binaryExpr(other.derived(), internal::scalar_max_op<Scalar>());
229  }
230 
231  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
232  const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const OtherDerived>
233  cwiseMin(const OtherDerived& other) const {
234  return binaryExpr(other.derived(), internal::scalar_min_op<Scalar>());
235  }
236 
237  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
238  const TensorCwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived>
239  operator&&(const OtherDerived& other) const {
240  return binaryExpr(other.derived(), internal::scalar_boolean_and_op());
241  }
242 
243  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
244  const TensorCwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>
245  operator||(const OtherDerived& other) const {
246  return binaryExpr(other.derived(), internal::scalar_boolean_or_op());
247  }
248 
249  // Comparisons and tests.
250  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
251  const TensorCwiseBinaryOp<std::less<Scalar>, const Derived, const OtherDerived>
252  operator<(const OtherDerived& other) const {
253  return binaryExpr(other.derived(), std::less<Scalar>());
254  }
255  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
256  const TensorCwiseBinaryOp<std::less_equal<Scalar>, const Derived, const OtherDerived>
257  operator<=(const OtherDerived& other) const {
258  return binaryExpr(other.derived(), std::less_equal<Scalar>());
259  }
260  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
261  const TensorCwiseBinaryOp<std::greater<Scalar>, const Derived, const OtherDerived>
262  operator>(const OtherDerived& other) const {
263  return binaryExpr(other.derived(), std::greater<Scalar>());
264  }
265  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
266  const TensorCwiseBinaryOp<std::greater_equal<Scalar>, const Derived, const OtherDerived>
267  operator>=(const OtherDerived& other) const {
268  return binaryExpr(other.derived(), std::greater_equal<Scalar>());
269  }
270 
271  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
272  const TensorCwiseBinaryOp<std::equal_to<Scalar>, const Derived, const OtherDerived>
273  operator==(const OtherDerived& other) const {
274  return binaryExpr(other.derived(), std::equal_to<Scalar>());
275  }
276  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
277  const TensorCwiseBinaryOp<std::not_equal_to<Scalar>, const Derived, const OtherDerived>
278  operator!=(const OtherDerived& other) const {
279  return binaryExpr(other.derived(), std::not_equal_to<Scalar>());
280  }
281 
282  // Coefficient-wise ternary operators.
283  template<typename ThenDerived, typename ElseDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
284  const TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>
285  select(const ThenDerived& thenTensor, const ElseDerived& elseTensor) const {
286  return TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>(derived(), thenTensor.derived(), elseTensor.derived());
287  }
288 
289  // Contractions.
290  typedef Eigen::IndexPair<Index> DimensionPair;
291 
292  template<typename OtherDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
293  const TensorContractionOp<const Dimensions, const Derived, const OtherDerived>
294  contract(const OtherDerived& other, const Dimensions& dims) const {
295  return TensorContractionOp<const Dimensions, const Derived, const OtherDerived>(derived(), other.derived(), dims);
296  }
297 
298  // Convolutions.
299  template<typename KernelDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
300  const TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>
301  convolve(const KernelDerived& kernel, const Dimensions& dims) const {
302  return TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>(derived(), kernel.derived(), dims);
303  }
304 
305  // Reductions.
306  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
307  const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>
308  sum(const Dims& dims) const {
309  return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::SumReducer<CoeffReturnType>());
310  }
311 
312  const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
313  sum() const {
314  DimensionList<Index, NumDimensions> in_dims;
315  return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::SumReducer<CoeffReturnType>());
316  }
317 
318  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
319  const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>
320  mean(const Dims& dims) const {
321  return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MeanReducer<CoeffReturnType>());
322  }
323 
324  const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
325  mean() const {
326  DimensionList<Index, NumDimensions> in_dims;
327  return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MeanReducer<CoeffReturnType>());
328  }
329 
330  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
331  const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>
332  prod(const Dims& dims) const {
333  return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::ProdReducer<CoeffReturnType>());
334  }
335 
336  const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
337  prod() const {
338  DimensionList<Index, NumDimensions> in_dims;
339  return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::ProdReducer<CoeffReturnType>());
340  }
341 
342  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
343  const TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const Dims, const Derived>
344  maximum(const Dims& dims) const {
345  return TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MaxReducer<CoeffReturnType>());
346  }
347 
348  const TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
349  maximum() const {
350  DimensionList<Index, NumDimensions> in_dims;
351  return TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MaxReducer<CoeffReturnType>());
352  }
353 
354  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
355  const TensorReductionOp<internal::MinReducer<CoeffReturnType>, const Dims, const Derived>
356  minimum(const Dims& dims) const {
357  return TensorReductionOp<internal::MinReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MinReducer<CoeffReturnType>());
358  }
359 
360  const TensorReductionOp<internal::MinReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
361  minimum() const {
362  DimensionList<Index, NumDimensions> in_dims;
363  return TensorReductionOp<internal::MinReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MinReducer<CoeffReturnType>());
364  }
365 
366  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
367  const TensorTupleReducerOp<
368  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
369  const array<Index, NumDimensions>, const Derived>
370  argmax() const {
371  array<Index, NumDimensions> in_dims;
372  for (int d = 0; d < NumDimensions; ++d) in_dims[d] = d;
373  return TensorTupleReducerOp<
374  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
375  const array<Index, NumDimensions>,
376  const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
377  }
378 
379  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
380  const TensorTupleReducerOp<
381  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
382  const array<Index, NumDimensions>, const Derived>
383  argmin() const {
384  array<Index, NumDimensions> in_dims;
385  for (int d = 0; d < NumDimensions; ++d) in_dims[d] = d;
386  return TensorTupleReducerOp<
387  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
388  const array<Index, NumDimensions>,
389  const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
390  }
391 
392  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
393  const TensorTupleReducerOp<
394  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
395  const array<Index, 1>, const Derived>
396  argmax(const int return_dim) const {
397  array<Index, 1> in_dims;
398  in_dims[0] = return_dim;
399  return TensorTupleReducerOp<
400  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
401  const array<Index, 1>,
402  const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
403  }
404 
405  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
406  const TensorTupleReducerOp<
407  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
408  const array<Index, 1>, const Derived>
409  argmin(const int return_dim) const {
410  array<Index, 1> in_dims;
411  in_dims[0] = return_dim;
412  return TensorTupleReducerOp<
413  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
414  const array<Index, 1>,
415  const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
416  }
417 
418  template <typename Reducer, typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
419  const TensorReductionOp<Reducer, const Dims, const Derived>
420  reduce(const Dims& dims, const Reducer& reducer) const {
421  return TensorReductionOp<Reducer, const Dims, const Derived>(derived(), dims, reducer);
422  }
423 
424  template <typename Broadcast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
425  const TensorBroadcastingOp<const Broadcast, const Derived>
426  broadcast(const Broadcast& broadcast) const {
427  return TensorBroadcastingOp<const Broadcast, const Derived>(derived(), broadcast);
428  }
429 
430  template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
431  const TensorConcatenationOp<Axis, const Derived, const OtherDerived>
432  concatenate(const OtherDerived& other, Axis axis) const {
433  return TensorConcatenationOp<Axis, const Derived, const OtherDerived>(derived(), other.derived(), axis);
434  }
435 
436  template <typename PatchDims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
437  const TensorPatchOp<const PatchDims, const Derived>
438  extract_patches(const PatchDims& patch_dims) const {
439  return TensorPatchOp<const PatchDims, const Derived>(derived(), patch_dims);
440  }
441 
442  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
443  const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
444  extract_image_patches(const Index patch_rows = 1, const Index patch_cols = 1,
445  const Index row_stride = 1, const Index col_stride = 1,
446  const Index in_row_stride = 1, const Index in_col_stride = 1,
447  const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
448  return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
449  in_row_stride, in_col_stride, 1, 1, padding_type, padding_value);
450  }
451 
452  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
453  const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
454  extract_image_patches(const Index patch_rows, const Index patch_cols,
455  const Index row_stride, const Index col_stride,
456  const Index in_row_stride, const Index in_col_stride,
457  const Index row_inflate_stride, const Index col_inflate_stride,
458  const Index padding_top, const Index padding_bottom,
459  const Index padding_left,const Index padding_right,
460  const Scalar padding_value) const {
461  return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
462  in_row_stride, in_col_stride, row_inflate_stride, col_inflate_stride,
463  padding_top, padding_bottom, padding_left, padding_right, padding_value);
464  }
465 
466  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
467  const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
468  extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
469  const Index plane_stride = 1, const Index row_stride = 1, const Index col_stride = 1,
470  const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = 0) const {
471  return TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>(derived(), patch_planes, patch_rows, patch_cols, plane_stride, row_stride, col_stride, 1, 1, 1, 1, 1, 1, padding_type, padding_value);
472  }
473 
474 
475  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
476  const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
477  extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
478  const Index plane_stride, const Index row_stride, const Index col_stride,
479  const Index plane_inflate_stride, const Index row_inflate_stride, const Index col_inflate_stride,
480  const Index padding_top_z, const Index padding_bottom_z,
481  const Index padding_top, const Index padding_bottom,
482  const Index padding_left, const Index padding_right, const Scalar padding_value = 0) const {
483  return TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>(derived(), patch_planes, patch_rows, patch_cols, plane_stride, row_stride, col_stride, 1, 1, 1, plane_inflate_stride, row_inflate_stride, col_inflate_stride, padding_top_z, padding_bottom_z, padding_top, padding_bottom, padding_left, padding_right, padding_value);
484  }
485 
486  // Morphing operators.
487  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
488  const TensorLayoutSwapOp<const Derived>
489  swap_layout() const {
490  return TensorLayoutSwapOp<const Derived>(derived());
491  }
492  template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
493  const TensorReshapingOp<const NewDimensions, const Derived>
494  reshape(const NewDimensions& newDimensions) const {
495  return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
496  }
497  template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
498  const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
499  slice(const StartIndices& startIndices, const Sizes& sizes) const {
500  return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
501  }
502  template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
503  const TensorChippingOp<DimId, const Derived>
504  chip(const Index offset) const {
505  return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
506  }
507  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
508  const TensorChippingOp<Dynamic, const Derived>
509  chip(const Index offset, const Index dim) const {
510  return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
511  }
512  template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
513  const TensorReverseOp<const ReverseDimensions, const Derived>
514  reverse(const ReverseDimensions& rev) const {
515  return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
516  }
517  template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
518  const TensorPaddingOp<const PaddingDimensions, const Derived>
519  pad(const PaddingDimensions& padding) const {
520  return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding);
521  }
522  template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
523  const TensorShufflingOp<const Shuffle, const Derived>
524  shuffle(const Shuffle& shuffle) const {
525  return TensorShufflingOp<const Shuffle, const Derived>(derived(), shuffle);
526  }
527  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
528  const TensorStridingOp<const Strides, const Derived>
529  stride(const Strides& strides) const {
530  return TensorStridingOp<const Strides, const Derived>(derived(), strides);
531  }
532  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
533  const TensorInflationOp<const Strides, const Derived>
534  inflate(const Strides& strides) const {
535  return TensorInflationOp<const Strides, const Derived>(derived(), strides);
536  }
537 
538  // Returns a tensor containing index/value tuples
539  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
540  const TensorIndexTupleOp<const Derived>
541  index_tuples() const {
542  return TensorIndexTupleOp<const Derived>(derived());
543  }
544 
545  // Support for custom unary and binary operations
546  template <typename CustomUnaryFunc>
547  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
548  const TensorCustomUnaryOp<const CustomUnaryFunc, const Derived> customOp(const CustomUnaryFunc& op) const {
549  return TensorCustomUnaryOp<const CustomUnaryFunc, const Derived>(derived(), op);
550  }
551  template <typename OtherDerived, typename CustomBinaryFunc>
552  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
553  const TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived> customOp(const OtherDerived& other, const CustomBinaryFunc& op) const {
554  return TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived>(derived(), other, op);
555  }
556 
557  // Force the evaluation of the expression.
558  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
559  const TensorForcedEvalOp<const Derived> eval() const {
560  return TensorForcedEvalOp<const Derived>(derived());
561  }
562 
563  protected:
564  template <typename Scalar, std::size_t NumIndices, int Options, typename IndexType> friend class Tensor;
565  template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
566  template <typename OtherDerived, int AccessLevel> friend class TensorBase;
567  EIGEN_DEVICE_FUNC
568  EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
569 };
570 
571 template<typename Derived>
572 class TensorBase<Derived, WriteAccessors> : public TensorBase<Derived, ReadOnlyAccessors> {
573  public:
574  typedef internal::traits<Derived> DerivedTraits;
575  typedef typename DerivedTraits::Scalar Scalar;
576  typedef typename DerivedTraits::Index Index;
577  typedef Scalar CoeffReturnType;
578  typedef typename internal::packet_traits<Scalar>::type PacketReturnType;
579  static const int NumDimensions = DerivedTraits::NumDimensions;
580 
581  template <typename Scalar, std::size_t NumIndices, int Options, typename IndexType> friend class Tensor;
582  template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
583  template <typename OtherDerived, int AccessLevel> friend class TensorBase;
584 
585  EIGEN_DEVICE_FUNC
586  EIGEN_STRONG_INLINE Derived& setZero() {
587  return setConstant(Scalar(0));
588  }
589  EIGEN_DEVICE_FUNC
590  EIGEN_STRONG_INLINE Derived& setConstant(const Scalar& val) {
591  return derived() = this->constant(val);
592  }
593  EIGEN_DEVICE_FUNC
594  EIGEN_STRONG_INLINE Derived& setRandom() {
595  return derived() = this->random();
596  }
597  template <typename RandomGenerator> EIGEN_DEVICE_FUNC
598  EIGEN_STRONG_INLINE Derived& setRandom() {
599  return derived() = this->template random<RandomGenerator>();
600  }
601 
602 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
603  EIGEN_DEVICE_FUNC
604  EIGEN_STRONG_INLINE Derived& setValues(
605  const typename internal::Initializer<Derived, NumDimensions>::InitList& vals) {
606  TensorEvaluator<Derived, DefaultDevice> eval(derived(), DefaultDevice());
607  internal::initialize_tensor<Derived, NumDimensions>(eval, vals);
608  return derived();
609  }
610 #endif // EIGEN_HAS_VARIADIC_TEMPLATES
611 
612  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
613  Derived& operator+=(const OtherDerived& other) {
614  return derived() = derived() + other.derived();
615  }
616  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
617  Derived& operator-=(const OtherDerived& other) {
618  return derived() = derived() - other.derived();
619  }
620  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
621  Derived& operator*=(const OtherDerived& other) {
622  return derived() = derived() * other.derived();
623  }
624  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
625  Derived& operator/=(const OtherDerived& other) {
626  return derived() = derived() / other.derived();
627  }
628 
629  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
630  const TensorLayoutSwapOp<const Derived>
631  swap_layout() const {
632  return TensorLayoutSwapOp<const Derived>(derived());
633  }
634  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
635  TensorLayoutSwapOp<Derived>
636  swap_layout() {
637  return TensorLayoutSwapOp<Derived>(derived());
638  }
639 
640  template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
641  const TensorConcatenationOp<const Axis, const Derived, const OtherDerived>
642  concatenate(const OtherDerived& other, const Axis& axis) const {
643  return TensorConcatenationOp<const Axis, const Derived, const OtherDerived>(derived(), other, axis);
644  }
645  template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
646  TensorConcatenationOp<const Axis, Derived, OtherDerived>
647  concatenate(const OtherDerived& other, const Axis& axis) {
648  return TensorConcatenationOp<const Axis, Derived, OtherDerived>(derived(), other, axis);
649  }
650 
651  template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
652  const TensorReshapingOp<const NewDimensions, const Derived>
653  reshape(const NewDimensions& newDimensions) const {
654  return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
655  }
656  template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
657  TensorReshapingOp<const NewDimensions, Derived>
658  reshape(const NewDimensions& newDimensions) {
659  return TensorReshapingOp<const NewDimensions, Derived>(derived(), newDimensions);
660  }
661 
662  template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
663  const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
664  slice(const StartIndices& startIndices, const Sizes& sizes) const {
665  return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
666  }
667  template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
668  TensorSlicingOp<const StartIndices, const Sizes, Derived>
669  slice(const StartIndices& startIndices, const Sizes& sizes) {
670  return TensorSlicingOp<const StartIndices, const Sizes, Derived>(derived(), startIndices, sizes);
671  }
672 
673  template <DenseIndex DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
674  const TensorChippingOp<DimId, const Derived>
675  chip(const Index offset) const {
676  return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
677  }
678  template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
679  TensorChippingOp<DimId, Derived>
680  chip(const Index offset) {
681  return TensorChippingOp<DimId, Derived>(derived(), offset, DimId);
682  }
683 
684  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
685  const TensorChippingOp<Dynamic, const Derived>
686  chip(const Index offset, const Index dim) const {
687  return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
688  }
689  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
690  TensorChippingOp<Dynamic, Derived>
691  chip(const Index offset, const Index dim) {
692  return TensorChippingOp<Dynamic, Derived>(derived(), offset, dim);
693  }
694 
695  template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
696  const TensorReverseOp<const ReverseDimensions, const Derived>
697  reverse(const ReverseDimensions& rev) const {
698  return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
699  }
700  template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
701  TensorReverseOp<const ReverseDimensions, Derived>
702  reverse(const ReverseDimensions& rev) {
703  return TensorReverseOp<const ReverseDimensions, Derived>(derived(), rev);
704  }
705 
706  template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
707  const TensorShufflingOp<const Shuffle, const Derived>
708  shuffle(const Shuffle& shuffle) const {
709  return TensorShufflingOp<const Shuffle, const Derived>(derived(), shuffle);
710  }
711  template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
712  TensorShufflingOp<const Shuffle, Derived>
713  shuffle(const Shuffle& shuffle) {
714  return TensorShufflingOp<const Shuffle, Derived>(derived(), shuffle);
715  }
716 
717  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
718  const TensorStridingOp<const Strides, const Derived>
719  stride(const Strides& strides) const {
720  return TensorStridingOp<const Strides, const Derived>(derived(), strides);
721  }
722  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
723  TensorStridingOp<const Strides, Derived>
724  stride(const Strides& strides) {
725  return TensorStridingOp<const Strides, Derived>(derived(), strides);
726  }
727 
728  // Select the device on which to evaluate the expression.
729  template <typename DeviceType>
730  TensorDevice<Derived, DeviceType> device(const DeviceType& device) {
731  return TensorDevice<Derived, DeviceType>(device, derived());
732  }
733 
734  protected:
735  EIGEN_DEVICE_FUNC
736  EIGEN_STRONG_INLINE Derived& derived() { return *static_cast<Derived*>(this); }
737  EIGEN_DEVICE_FUNC
738  EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
739 };
740 
741 } // end namespace Eigen
742 
743 #endif // EIGEN_CXX11_TENSOR_TENSOR_BASE_H
Namespace containing all symbols from the Eigen library.
Definition: CXX11Meta.h:13