cxx11_tensor_morphing.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;
15 
16 template<typename>
17 static void test_simple_reshape()
18 {
19  Tensor<float, 5> tensor1(2,3,1,7,1);
20  tensor1.setRandom();
21 
22  Tensor<float, 3> tensor2(2,3,7);
23  Tensor<float, 2> tensor3(6,7);
24  Tensor<float, 2> tensor4(2,21);
25 
26  Tensor<float, 3>::Dimensions dim1(2,3,7);
27  tensor2 = tensor1.reshape(dim1);
29  tensor3 = tensor1.reshape(dim2);
31  tensor4 = tensor1.reshape(dim1).reshape(dim3);
32 
33  for (int i = 0; i < 2; ++i) {
34  for (int j = 0; j < 3; ++j) {
35  for (int k = 0; k < 7; ++k) {
36  VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor2(i,j,k));
37  VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor3(i+2*j,k));
38  VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor4(i,j+3*k));
39  }
40  }
41  }
42 }
43 
44 template<typename>
45 static void test_reshape_in_expr() {
46  MatrixXf m1(2,3*5*7*11);
47  MatrixXf m2(3*5*7*11,13);
48  m1.setRandom();
49  m2.setRandom();
50  MatrixXf m3 = m1 * m2;
51 
52  TensorMap<Tensor<float, 5>> tensor1(m1.data(), 2,3,5,7,11);
53  TensorMap<Tensor<float, 5>> tensor2(m2.data(), 3,5,7,11,13);
54  Tensor<float, 2>::Dimensions newDims1(2,3*5*7*11);
55  Tensor<float, 2>::Dimensions newDims2(3*5*7*11,13);
57  array<DimPair, 1> contract_along{{DimPair(1, 0)}};
58  Tensor<float, 2> tensor3(2,13);
59  tensor3 = tensor1.reshape(newDims1).contract(tensor2.reshape(newDims2), contract_along);
60 
61  Map<MatrixXf> res(tensor3.data(), 2, 13);
62  for (int i = 0; i < 2; ++i) {
63  for (int j = 0; j < 13; ++j) {
64  VERIFY_IS_APPROX(res(i,j), m3(i,j));
65  }
66  }
67 }
68 
69 template<typename>
71 {
72  Tensor<float, 3> tensor(2,3,7);
73  tensor.setRandom();
74 
75  Tensor<float, 2> tensor2d(6,7);
77  tensor2d.reshape(dim) = tensor;
78 
79  float scratch[2*3*1*7*1];
80  TensorMap<Tensor<float, 5>> tensor5d(scratch, 2,3,1,7,1);
81  tensor5d.reshape(dim).device(Eigen::DefaultDevice()) = tensor;
82 
83  for (int i = 0; i < 2; ++i) {
84  for (int j = 0; j < 3; ++j) {
85  for (int k = 0; k < 7; ++k) {
86  VERIFY_IS_EQUAL(tensor2d(i+2*j,k), tensor(i,j,k));
87  VERIFY_IS_EQUAL(tensor5d(i,j,0,k,0), tensor(i,j,k));
88  }
89  }
90  }
91 }
92 
93 template<int DataLayout>
94 static void test_simple_slice()
95 {
96  Tensor<float, 5, DataLayout> tensor(2,3,5,7,11);
97  tensor.setRandom();
98 
99  Tensor<float, 5, DataLayout> slice1(1,1,1,1,1);
100  Eigen::DSizes<ptrdiff_t, 5> indices(1,2,3,4,5);
101  Eigen::DSizes<ptrdiff_t, 5> sizes(1,1,1,1,1);
102  slice1 = tensor.slice(indices, sizes);
103  VERIFY_IS_EQUAL(slice1(0,0,0,0,0), tensor(1,2,3,4,5));
104 
105  Tensor<float, 5, DataLayout> slice2(1,1,2,2,3);
106  Eigen::DSizes<ptrdiff_t, 5> indices2(1,1,3,4,5);
107  Eigen::DSizes<ptrdiff_t, 5> sizes2(1,1,2,2,3);
108  slice2 = tensor.slice(indices2, sizes2);
109  for (int i = 0; i < 2; ++i) {
110  for (int j = 0; j < 2; ++j) {
111  for (int k = 0; k < 3; ++k) {
112  VERIFY_IS_EQUAL(slice2(0,0,i,j,k), tensor(1,1,3+i,4+j,5+k));
113  }
114  }
115  }
116 }
117 
118 template<typename=void>
119 static void test_const_slice()
120 {
121  const float b[1] = {42};
122  TensorMap<Tensor<const float, 1> > m(b, 1);
123  DSizes<DenseIndex, 1> offsets;
124  offsets[0] = 0;
125  TensorRef<Tensor<const float, 1> > slice_ref(m.slice(offsets, m.dimensions()));
126  VERIFY_IS_EQUAL(slice_ref(0), 42);
127 }
128 
129 template<int DataLayout>
130 static void test_slice_in_expr() {
131  typedef Matrix<float, Dynamic, Dynamic, DataLayout> Mtx;
132  Mtx m1(7,7);
133  Mtx m2(3,3);
134  m1.setRandom();
135  m2.setRandom();
136 
137  Mtx m3 = m1.block(1, 2, 3, 3) * m2.block(0, 2, 3, 1);
138 
139  TensorMap<Tensor<float, 2, DataLayout>> tensor1(m1.data(), 7, 7);
140  TensorMap<Tensor<float, 2, DataLayout>> tensor2(m2.data(), 3, 3);
141  Tensor<float, 2, DataLayout> tensor3(3,1);
143  array<DimPair, 1> contract_along{{DimPair(1, 0)}};
144 
145  Eigen::DSizes<ptrdiff_t, 2> indices1(1,2);
146  Eigen::DSizes<ptrdiff_t, 2> sizes1(3,3);
147  Eigen::DSizes<ptrdiff_t, 2> indices2(0,2);
148  Eigen::DSizes<ptrdiff_t, 2> sizes2(3,1);
149  tensor3 = tensor1.slice(indices1, sizes1).contract(tensor2.slice(indices2, sizes2), contract_along);
150 
151  Map<Mtx> res(tensor3.data(), 3, 1);
152  for (int i = 0; i < 3; ++i) {
153  for (int j = 0; j < 1; ++j) {
154  VERIFY_IS_APPROX(res(i,j), m3(i,j));
155  }
156  }
157 
158  // Take an arbitrary slice of an arbitrarily sized tensor.
159  TensorMap<Tensor<const float, 2, DataLayout>> tensor4(m1.data(), 7, 7);
160  Tensor<float, 1, DataLayout> tensor6 = tensor4.reshape(DSizes<ptrdiff_t, 1>(7*7)).exp().slice(DSizes<ptrdiff_t, 1>(0), DSizes<ptrdiff_t, 1>(35));
161  for (int i = 0; i < 35; ++i) {
162  VERIFY_IS_APPROX(tensor6(i), expf(tensor4.data()[i]));
163  }
164 }
165 
166 template<int DataLayout>
167 static void test_slice_as_lvalue()
168 {
169  Tensor<float, 3, DataLayout> tensor1(2,2,7);
170  tensor1.setRandom();
171  Tensor<float, 3, DataLayout> tensor2(2,2,7);
172  tensor2.setRandom();
173  Tensor<float, 3, DataLayout> tensor3(4,3,5);
174  tensor3.setRandom();
175  Tensor<float, 3, DataLayout> tensor4(4,3,2);
176  tensor4.setRandom();
177  Tensor<float, 3, DataLayout> tensor5(10,13,12);
178  tensor5.setRandom();
179 
180  Tensor<float, 3, DataLayout> result(4,5,7);
181  Eigen::DSizes<ptrdiff_t, 3> sizes12(2,2,7);
182  Eigen::DSizes<ptrdiff_t, 3> first_slice(0,0,0);
183  result.slice(first_slice, sizes12) = tensor1;
184  Eigen::DSizes<ptrdiff_t, 3> second_slice(2,0,0);
185  result.slice(second_slice, sizes12).device(Eigen::DefaultDevice()) = tensor2;
186 
187  Eigen::DSizes<ptrdiff_t, 3> sizes3(4,3,5);
188  Eigen::DSizes<ptrdiff_t, 3> third_slice(0,2,0);
189  result.slice(third_slice, sizes3) = tensor3;
190 
191  Eigen::DSizes<ptrdiff_t, 3> sizes4(4,3,2);
192  Eigen::DSizes<ptrdiff_t, 3> fourth_slice(0,2,5);
193  result.slice(fourth_slice, sizes4) = tensor4;
194 
195  for (int j = 0; j < 2; ++j) {
196  for (int k = 0; k < 7; ++k) {
197  for (int i = 0; i < 2; ++i) {
198  VERIFY_IS_EQUAL(result(i,j,k), tensor1(i,j,k));
199  VERIFY_IS_EQUAL(result(i+2,j,k), tensor2(i,j,k));
200  }
201  }
202  }
203  for (int i = 0; i < 4; ++i) {
204  for (int j = 2; j < 5; ++j) {
205  for (int k = 0; k < 5; ++k) {
206  VERIFY_IS_EQUAL(result(i,j,k), tensor3(i,j-2,k));
207  }
208  for (int k = 5; k < 7; ++k) {
209  VERIFY_IS_EQUAL(result(i,j,k), tensor4(i,j-2,k-5));
210  }
211  }
212  }
213 
214  Eigen::DSizes<ptrdiff_t, 3> sizes5(4,5,7);
215  Eigen::DSizes<ptrdiff_t, 3> fifth_slice(0,0,0);
216  result.slice(fifth_slice, sizes5) = tensor5.slice(fifth_slice, sizes5);
217  for (int i = 0; i < 4; ++i) {
218  for (int j = 2; j < 5; ++j) {
219  for (int k = 0; k < 7; ++k) {
220  VERIFY_IS_EQUAL(result(i,j,k), tensor5(i,j,k));
221  }
222  }
223  }
224 }
225 
226 template<int DataLayout>
227 static void test_slice_raw_data()
228 {
229  Tensor<float, 4, DataLayout> tensor(3,5,7,11);
230  tensor.setRandom();
231 
232  Eigen::DSizes<ptrdiff_t, 4> offsets(1,2,3,4);
233  Eigen::DSizes<ptrdiff_t, 4> extents(1,1,1,1);
234  typedef TensorEvaluator<decltype(tensor.slice(offsets, extents)), DefaultDevice> SliceEvaluator;
235  auto slice1 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
236  VERIFY_IS_EQUAL(slice1.dimensions().TotalSize(), 1);
237  VERIFY_IS_EQUAL(slice1.data()[0], tensor(1,2,3,4));
238 
239  if (DataLayout == ColMajor) {
240  extents = Eigen::DSizes<ptrdiff_t, 4>(2,1,1,1);
241  auto slice2 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
242  VERIFY_IS_EQUAL(slice2.dimensions().TotalSize(), 2);
243  VERIFY_IS_EQUAL(slice2.data()[0], tensor(1,2,3,4));
244  VERIFY_IS_EQUAL(slice2.data()[1], tensor(2,2,3,4));
245  } else {
246  extents = Eigen::DSizes<ptrdiff_t, 4>(1,1,1,2);
247  auto slice2 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
248  VERIFY_IS_EQUAL(slice2.dimensions().TotalSize(), 2);
249  VERIFY_IS_EQUAL(slice2.data()[0], tensor(1,2,3,4));
250  VERIFY_IS_EQUAL(slice2.data()[1], tensor(1,2,3,5));
251  }
252 
253  extents = Eigen::DSizes<ptrdiff_t, 4>(1,2,1,1);
254  auto slice3 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
255  VERIFY_IS_EQUAL(slice3.dimensions().TotalSize(), 2);
256  VERIFY_IS_EQUAL(slice3.data(), static_cast<float*>(0));
257 
258  if (DataLayout == ColMajor) {
259  offsets = Eigen::DSizes<ptrdiff_t, 4>(0,2,3,4);
260  extents = Eigen::DSizes<ptrdiff_t, 4>(3,2,1,1);
261  auto slice4 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
262  VERIFY_IS_EQUAL(slice4.dimensions().TotalSize(), 6);
263  for (int i = 0; i < 3; ++i) {
264  for (int j = 0; j < 2; ++j) {
265  VERIFY_IS_EQUAL(slice4.data()[i+3*j], tensor(i,2+j,3,4));
266  }
267  }
268  } else {
269  offsets = Eigen::DSizes<ptrdiff_t, 4>(1,2,3,0);
270  extents = Eigen::DSizes<ptrdiff_t, 4>(1,1,2,11);
271  auto slice4 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
272  VERIFY_IS_EQUAL(slice4.dimensions().TotalSize(), 22);
273  for (int l = 0; l < 11; ++l) {
274  for (int k = 0; k < 2; ++k) {
275  VERIFY_IS_EQUAL(slice4.data()[l+11*k], tensor(1,2,3+k,l));
276  }
277  }
278  }
279 
280  if (DataLayout == ColMajor) {
281  offsets = Eigen::DSizes<ptrdiff_t, 4>(0,0,0,4);
282  extents = Eigen::DSizes<ptrdiff_t, 4>(3,5,7,2);
283  auto slice5 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
284  VERIFY_IS_EQUAL(slice5.dimensions().TotalSize(), 210);
285  for (int i = 0; i < 3; ++i) {
286  for (int j = 0; j < 5; ++j) {
287  for (int k = 0; k < 7; ++k) {
288  for (int l = 0; l < 2; ++l) {
289  int slice_index = i + 3 * (j + 5 * (k + 7 * l));
290  VERIFY_IS_EQUAL(slice5.data()[slice_index], tensor(i,j,k,l+4));
291  }
292  }
293  }
294  }
295  } else {
296  offsets = Eigen::DSizes<ptrdiff_t, 4>(1,0,0,0);
297  extents = Eigen::DSizes<ptrdiff_t, 4>(2,5,7,11);
298  auto slice5 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
299  VERIFY_IS_EQUAL(slice5.dimensions().TotalSize(), 770);
300  for (int l = 0; l < 11; ++l) {
301  for (int k = 0; k < 7; ++k) {
302  for (int j = 0; j < 5; ++j) {
303  for (int i = 0; i < 2; ++i) {
304  int slice_index = l + 11 * (k + 7 * (j + 5 * i));
305  VERIFY_IS_EQUAL(slice5.data()[slice_index], tensor(i+1,j,k,l));
306  }
307  }
308  }
309  }
310 
311  }
312 
313  offsets = Eigen::DSizes<ptrdiff_t, 4>(0,0,0,0);
314  extents = Eigen::DSizes<ptrdiff_t, 4>(3,5,7,11);
315  auto slice6 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
316  VERIFY_IS_EQUAL(slice6.dimensions().TotalSize(), 3*5*7*11);
317  VERIFY_IS_EQUAL(slice6.data(), tensor.data());
318 }
319 
320 
321 template<int DataLayout>
322 static void test_strided_slice()
323 {
324  typedef Tensor<float, 5, DataLayout> Tensor5f;
326  typedef Tensor<float, 2, DataLayout> Tensor2f;
328  Tensor<float, 5, DataLayout> tensor(2,3,5,7,11);
329  Tensor<float, 2, DataLayout> tensor2(7,11);
330  tensor.setRandom();
331  tensor2.setRandom();
332 
333  if (true) {
334  Tensor2f slice(2,3);
335  Index2 strides(-2,-1);
336  Index2 indicesStart(5,7);
337  Index2 indicesStop(0,4);
338  slice = tensor2.stridedSlice(indicesStart, indicesStop, strides);
339  for (int j = 0; j < 2; ++j) {
340  for (int k = 0; k < 3; ++k) {
341  VERIFY_IS_EQUAL(slice(j,k), tensor2(5-2*j,7-k));
342  }
343  }
344  }
345 
346  if(true) {
347  Tensor2f slice(0,1);
348  Index2 strides(1,1);
349  Index2 indicesStart(5,4);
350  Index2 indicesStop(5,5);
351  slice = tensor2.stridedSlice(indicesStart, indicesStop, strides);
352  }
353 
354  if(true) { // test clamped degenerate interavls
355  Tensor2f slice(7,11);
356  Index2 strides(1,-1);
357  Index2 indicesStart(-3,20); // should become 0,10
358  Index2 indicesStop(20,-11); // should become 11, -1
359  slice = tensor2.stridedSlice(indicesStart, indicesStop, strides);
360  for (int j = 0; j < 7; ++j) {
361  for (int k = 0; k < 11; ++k) {
362  VERIFY_IS_EQUAL(slice(j,k), tensor2(j,10-k));
363  }
364  }
365  }
366 
367  if(true) {
368  Tensor5f slice1(1,1,1,1,1);
369  Eigen::DSizes<Eigen::DenseIndex, 5> indicesStart(1, 2, 3, 4, 5);
370  Eigen::DSizes<Eigen::DenseIndex, 5> indicesStop(2, 3, 4, 5, 6);
371  Eigen::DSizes<Eigen::DenseIndex, 5> strides(1, 1, 1, 1, 1);
372  slice1 = tensor.stridedSlice(indicesStart, indicesStop, strides);
373  VERIFY_IS_EQUAL(slice1(0,0,0,0,0), tensor(1,2,3,4,5));
374  }
375 
376  if(true) {
377  Tensor5f slice(1,1,2,2,3);
378  Index5 start(1, 1, 3, 4, 5);
379  Index5 stop(2, 2, 5, 6, 8);
380  Index5 strides(1, 1, 1, 1, 1);
381  slice = tensor.stridedSlice(start, stop, strides);
382  for (int i = 0; i < 2; ++i) {
383  for (int j = 0; j < 2; ++j) {
384  for (int k = 0; k < 3; ++k) {
385  VERIFY_IS_EQUAL(slice(0,0,i,j,k), tensor(1,1,3+i,4+j,5+k));
386  }
387  }
388  }
389  }
390 
391  if(true) {
392  Tensor5f slice(1,1,2,2,3);
393  Index5 strides3(1, 1, -2, 1, -1);
394  Index5 indices3Start(1, 1, 4, 4, 7);
395  Index5 indices3Stop(2, 2, 0, 6, 4);
396  slice = tensor.stridedSlice(indices3Start, indices3Stop, strides3);
397  for (int i = 0; i < 2; ++i) {
398  for (int j = 0; j < 2; ++j) {
399  for (int k = 0; k < 3; ++k) {
400  VERIFY_IS_EQUAL(slice(0,0,i,j,k), tensor(1,1,4-2*i,4+j,7-k));
401  }
402  }
403  }
404  }
405 
406  if(false) { // tests degenerate interval
407  Tensor5f slice(1,1,2,2,3);
408  Index5 strides3(1, 1, 2, 1, 1);
409  Index5 indices3Start(1, 1, 4, 4, 7);
410  Index5 indices3Stop(2, 2, 0, 6, 4);
411  slice = tensor.stridedSlice(indices3Start, indices3Stop, strides3);
412  }
413 }
414 
415 template<int DataLayout>
417 {
418  typedef Tensor<float, 2, DataLayout> Tensor2f;
420 
421  Tensor<float, 2, DataLayout> tensor(7,11),tensor2(7,11);
422  tensor.setRandom();
423  tensor2=tensor;
424  Tensor2f slice(2,3);
425 
426  slice.setRandom();
427 
428  Index2 strides(1,1);
429  Index2 indicesStart(3,4);
430  Index2 indicesStop(5,7);
431  Index2 lengths(2,3);
432 
433  tensor.slice(indicesStart,lengths)=slice;
434  tensor2.stridedSlice(indicesStart,indicesStop,strides)=slice;
435 
436  for(int i=0;i<7;i++) for(int j=0;j<11;j++){
437  VERIFY_IS_EQUAL(tensor(i,j), tensor2(i,j));
438  }
439 }
440 
441 
442 template<int DataLayout>
443 static void test_composition()
444 {
446  matrix.setRandom();
447 
448  const DSizes<ptrdiff_t, 3> newDims(1, 1, 11);
450  matrix.slice(DSizes<ptrdiff_t, 2>(2, 0), DSizes<ptrdiff_t, 2>(1, 11)).reshape(newDims);
451 
452  VERIFY_IS_EQUAL(tensor.dimensions().TotalSize(), 11);
453  VERIFY_IS_EQUAL(tensor.dimension(0), 1);
454  VERIFY_IS_EQUAL(tensor.dimension(1), 1);
455  VERIFY_IS_EQUAL(tensor.dimension(2), 11);
456  for (int i = 0; i < 11; ++i) {
457  VERIFY_IS_EQUAL(tensor(0,0,i), matrix(2,i));
458  }
459 }
460 
461 
463 {
464  CALL_SUBTEST_1(test_simple_reshape<void>());
465  CALL_SUBTEST_1(test_reshape_in_expr<void>());
466  CALL_SUBTEST_1(test_reshape_as_lvalue<void>());
467 
468  CALL_SUBTEST_1(test_simple_slice<ColMajor>());
469  CALL_SUBTEST_1(test_simple_slice<RowMajor>());
470  CALL_SUBTEST_1(test_const_slice());
471  CALL_SUBTEST_2(test_slice_in_expr<ColMajor>());
472  CALL_SUBTEST_3(test_slice_in_expr<RowMajor>());
473  CALL_SUBTEST_4(test_slice_as_lvalue<ColMajor>());
474  CALL_SUBTEST_4(test_slice_as_lvalue<RowMajor>());
475  CALL_SUBTEST_5(test_slice_raw_data<ColMajor>());
476  CALL_SUBTEST_5(test_slice_raw_data<RowMajor>());
477 
478  CALL_SUBTEST_6(test_strided_slice_write<ColMajor>());
479  CALL_SUBTEST_6(test_strided_slice<ColMajor>());
480  CALL_SUBTEST_6(test_strided_slice_write<RowMajor>());
481  CALL_SUBTEST_6(test_strided_slice<RowMajor>());
482 
483  CALL_SUBTEST_7(test_composition<ColMajor>());
484  CALL_SUBTEST_7(test_composition<RowMajor>());
485 }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorSlicingOp< const StartIndices, const Sizes, const Tensor< Scalar_, NumIndices_, Options_, IndexType_ > > slice(const StartIndices &startIndices, const Sizes &sizes) const
Definition: TensorBase.h:918
static void test_simple_reshape()
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n) const
Definition: Tensor.h:101
static void test_strided_slice_write()
static void test_slice_as_lvalue()
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorStridingSlicingOp< const StartIndices, const StopIndices, const Strides, const Tensor< Scalar_, NumIndices_, Options_, IndexType_ > > stridedSlice(const StartIndices &startIndices, const StopIndices &stopIndices, const Strides &strides) const
Definition: TensorBase.h:929
static void test_reshape_as_lvalue()
static void test_const_slice()
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor< Scalar_, NumIndices_, Options_, IndexType_ > & setRandom()
Definition: TensorBase.h:848
static void test_strided_slice()
static void test_slice_raw_data()
static void test_reshape_in_expr()
Tensor< float, 1 >::DimensionPair DimPair
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorReshapingOp< const NewDimensions, const Tensor< Scalar_, NumIndices_, Options_, IndexType_ > > reshape(const NewDimensions &newDimensions) const
Definition: TensorBase.h:907
void test_cxx11_tensor_morphing()
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex TotalSize() const
static void test_simple_slice()
static void test_composition()
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
Definition: mpreal.h:2201
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar * data()
Definition: Tensor.h:104
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
Definition: Tensor.h:102
static void test_slice_in_expr()
EIGEN_DEVICE_FUNC const Scalar & b
The tensor class.
Definition: Tensor.h:63


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