5 #ifndef __pinocchio_math_tensor_hpp__
6 #define __pinocchio_math_tensor_hpp__
8 #include "pinocchio/fwd.hpp"
10 #if !EIGEN_VERSION_AT_LEAST(3, 2, 90)
11 #define EIGEN_DEVICE_FUNC
14 #ifndef PINOCCHIO_WITH_EIGEN_TENSOR_MODULE
15 #if (__cplusplus <= 199711L && EIGEN_COMP_MSVC < 1900) || defined(__CUDACC__) \
16 || defined(EIGEN_AVOID_STL_ARRAY)
19 template<
typename T, std::
size_t n>
23 EIGEN_STRONG_INLINE T & operator[](
size_t index)
28 EIGEN_STRONG_INLINE
const T & operator[](
size_t index)
const
34 EIGEN_STRONG_INLINE T & front()
39 EIGEN_STRONG_INLINE
const T & front()
const
45 EIGEN_STRONG_INLINE T & back()
50 EIGEN_STRONG_INLINE
const T & back()
const
55 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
static std::size_t size()
63 template<
class T, std::
size_t n>
66 for (std::size_t i = 0; i < n; ++i)
76 template<
class T, std::
size_t n>
77 EIGEN_DEVICE_FUNC
bool operator!=(
const array<T, n> & lhs,
const array<T, n> & rhs)
86 template<
typename T, std::
size_t N>
87 using array = std::array<T, N>;
95 #ifndef PINOCCHIO_WITH_EIGEN_TENSOR_MODULE
102 typename IndexType = Eigen::DenseIndex>
105 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
107 typedef Scalar_ Scalar;
111 NumIndices = NumIndices_
113 typedef IndexType Index;
120 inline const Tensor & base()
const
125 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Dimensions & dimensions()
129 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions & dimensions()
const
134 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank()
const
139 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n)
const
141 assert(n <= NumIndices &&
"n is larger than the dimension of the tensor.");
142 return m_dimensions[n];
145 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size()
const
147 return m_storage.size();
150 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar * data()
152 return m_storage.data();
155 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar * data()
const
157 return m_storage.data();
161 EIGEN_STRONG_INLINE
Tensor & setZero()
163 return setConstant(Scalar(0));
167 EIGEN_STRONG_INLINE
Tensor & setConstant(
const Scalar & val)
169 m_storage.setConstant(val);
174 EIGEN_STRONG_INLINE
Tensor & setRandom()
176 m_storage.setRandom();
180 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor()
185 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(
const Tensor & other)
186 : m_storage(other.m_storage)
187 , m_dimensions(other.m_dimensions)
191 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit Tensor(Index dim1)
194 m_dimensions[0] = dim1;
195 EIGEN_STATIC_ASSERT(1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
198 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(Index dim1, Index dim2)
199 : m_storage(dim1 * dim2)
201 m_dimensions[0] = dim1;
202 m_dimensions[1] = dim2;
203 EIGEN_STATIC_ASSERT(2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
206 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(Index dim1, Index dim2, Index dim3)
207 : m_storage(dim1 * dim2 * dim3)
209 m_dimensions[0] = dim1;
210 m_dimensions[1] = dim2;
211 m_dimensions[2] = dim3;
212 EIGEN_STATIC_ASSERT(3 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
215 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(Index dim1, Index dim2, Index dim3, Index dim4)
216 : m_storage(dim1 * dim2 * dim3 * dim4)
218 m_dimensions[0] = dim1;
219 m_dimensions[1] = dim2;
220 m_dimensions[2] = dim3;
221 m_dimensions[3] = dim4;
222 EIGEN_STATIC_ASSERT(4 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
225 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
226 Tensor(Index dim1, Index dim2, Index dim3, Index dim4, Index dim5)
227 : m_storage(dim1 * dim2 * dim3 * dim4 * dim5)
229 m_dimensions[0] = dim1;
230 m_dimensions[1] = dim2;
231 m_dimensions[2] = dim3;
232 m_dimensions[3] = dim4;
233 m_dimensions[4] = dim5;
234 EIGEN_STATIC_ASSERT(5 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
238 EIGEN_STRONG_INLINE
const Scalar & operator()(Index i0)
const
240 EIGEN_STATIC_ASSERT(1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
241 return m_storage.coeff(i0);
245 EIGEN_STRONG_INLINE
const Scalar & operator()(Index i0, Index i1)
const
247 EIGEN_STATIC_ASSERT(2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
248 return m_storage.coeff(i0 + i1 * m_dimensions[0]);
252 EIGEN_STRONG_INLINE
const Scalar & operator()(Index i0, Index i1, Index i2)
const
254 EIGEN_STATIC_ASSERT(3 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
255 return m_storage.coeff(i0 + i1 * m_dimensions[0] + i2 * m_dimensions[1] * m_dimensions[0]);
259 EIGEN_STRONG_INLINE
const Scalar & operator()(Index i0, Index i1, Index i2, Index i3)
const
261 EIGEN_STATIC_ASSERT(4 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
263 i0 + i1 * m_dimensions[0] + i2 * m_dimensions[1] * m_dimensions[0]
264 + i3 * m_dimensions[2] * m_dimensions[1] * m_dimensions[0]);
268 EIGEN_STRONG_INLINE
const Scalar &
269 operator()(Index i0, Index i1, Index i2, Index i3, Index i4)
const
271 EIGEN_STATIC_ASSERT(5 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
273 i0 + i1 * m_dimensions[0] + i2 * m_dimensions[1] * m_dimensions[0]
274 + i3 * m_dimensions[2] * m_dimensions[1] * m_dimensions[0]
275 + i4 * m_dimensions[3] * m_dimensions[2] * m_dimensions[1] * m_dimensions[0]);
282 Index size = Index(1);
283 for (i = 0; i < NumIndices; i++)
285 Eigen::internal::check_rows_cols_for_overflow<Eigen::Dynamic>::run(size, dimensions[i]);
286 size *= dimensions[i];
289 for (i = 0; i < NumIndices; i++)
290 m_dimensions[i] = dimensions[i];
292 bool size_changed = size != this->size();
294 m_storage.resize(size);
296 #ifdef EIGEN_INITIALIZE_COEFFS
299 #if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
300 m_storage.fill(Scalar(0));
301 #elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
302 m_storage.fill(std::numeric_limits<Scalar>::quiet_NaN());
308 EIGEN_DEVICE_FUNC
bool operator==(
const Tensor & other)
const
310 return m_storage == other.m_storage;
313 EIGEN_DEVICE_FUNC
bool operator!=(
const Tensor & other)
const
315 return m_storage != other.m_storage;
319 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> StorageType;
320 StorageType m_storage;
332 typename IndexType = Eigen::DenseIndex>
333 using Tensor = Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>;
339 #if !EIGEN_VERSION_AT_LEAST(3, 2, 90)
340 #undef EIGEN_DEVICE_FUNC
Main pinocchio namespace.