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__) || defined(EIGEN_AVOID_STL_ARRAY)
17 template <
typename T, std::
size_t n>
21 EIGEN_STRONG_INLINE T& operator[] (
size_t index)
22 {
return values[index]; }
24 EIGEN_STRONG_INLINE
const T& operator[] (
size_t index)
const
25 {
return values[index]; }
28 EIGEN_STRONG_INLINE T& front() {
return values[0]; }
30 EIGEN_STRONG_INLINE
const T& front()
const {
return values[0]; }
33 EIGEN_STRONG_INLINE T& back() {
return values[n-1]; }
35 EIGEN_STRONG_INLINE
const T& back()
const {
return values[n-1]; }
37 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
38 static std::size_t size() {
return n; }
43 template<
class T, std::
size_t n>
46 for (std::size_t i = 0; i < n; ++i) {
47 if (lhs[i] != rhs[i]) {
54 template<
class T, std::
size_t n>
55 EIGEN_DEVICE_FUNC
bool operator!=(
const array<T,n> & lhs,
const array<T,n> & rhs)
63 template <
typename T, std::
size_t N>
using array = std::array<T, N>;
71 #ifndef PINOCCHIO_WITH_EIGEN_TENSOR_MODULE
74 template<
typename Scalar_,
int NumIndices_,
int Options_ = 0,
typename IndexType = Eigen::DenseIndex>
77 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
79 typedef Scalar_ Scalar;
83 NumIndices = NumIndices_
85 typedef IndexType Index;
88 inline Tensor& base() {
return *
this; }
89 inline const Tensor& base()
const {
return *
this; }
91 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
92 Dimensions& dimensions() {
return m_dimensions; }
93 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
94 const Dimensions& dimensions()
const {
return m_dimensions; }
96 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank()
const
101 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n)
const
103 assert(n <= NumIndices &&
"n is larger than the dimension of the tensor.");
104 return m_dimensions[n];
107 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size()
const
109 return m_storage.size();
112 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
114 return m_storage.data();
117 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar *data()
const
119 return m_storage.data();
123 EIGEN_STRONG_INLINE
Tensor& setZero()
125 return setConstant(Scalar(0));
129 EIGEN_STRONG_INLINE
Tensor& setConstant(
const Scalar & val)
131 m_storage.setConstant(val);
136 EIGEN_STRONG_INLINE
Tensor& setRandom()
138 m_storage.setRandom();
142 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor()
147 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(
const Tensor & other)
148 : m_storage(other.m_storage)
149 , m_dimensions(other.m_dimensions)
153 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit Tensor(Index dim1)
156 m_dimensions[0] = dim1;
157 EIGEN_STATIC_ASSERT(1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
160 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(Index dim1, Index dim2)
161 : m_storage(dim1*dim2)
163 m_dimensions[0] = dim1;
164 m_dimensions[1] = dim2;
165 EIGEN_STATIC_ASSERT(2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
168 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(Index dim1, Index dim2, Index dim3)
169 : m_storage(dim1*dim2*dim3)
171 m_dimensions[0] = dim1;
172 m_dimensions[1] = dim2;
173 m_dimensions[2] = dim3;
174 EIGEN_STATIC_ASSERT(3 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
177 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(Index dim1, Index dim2, Index dim3, Index dim4)
178 : m_storage(dim1*dim2*dim3*dim4)
180 m_dimensions[0] = dim1;
181 m_dimensions[1] = dim2;
182 m_dimensions[2] = dim3;
183 m_dimensions[3] = dim4;
184 EIGEN_STATIC_ASSERT(4 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
187 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Tensor(Index dim1, Index dim2, Index dim3, Index dim4, Index dim5)
188 : m_storage(dim1*dim2*dim3*dim4*dim5)
190 m_dimensions[0] = dim1;
191 m_dimensions[1] = dim2;
192 m_dimensions[2] = dim3;
193 m_dimensions[3] = dim4;
194 m_dimensions[4] = dim5;
195 EIGEN_STATIC_ASSERT(5 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
199 EIGEN_STRONG_INLINE
const Scalar& operator()(Index i0)
const
201 EIGEN_STATIC_ASSERT(1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
202 return m_storage.coeff(i0);
206 EIGEN_STRONG_INLINE
const Scalar& operator()(Index i0, Index i1)
const
208 EIGEN_STATIC_ASSERT(2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
209 return m_storage.coeff(i0 + i1 * m_dimensions[0]);
213 EIGEN_STRONG_INLINE
const Scalar& operator()(Index i0, Index i1, Index i2)
const
215 EIGEN_STATIC_ASSERT(3 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
216 return m_storage.coeff(i0 + i1 * m_dimensions[0] + i2 * m_dimensions[1] * m_dimensions[0]);
220 EIGEN_STRONG_INLINE
const Scalar& operator()(Index i0, Index i1, Index i2, Index i3)
const
222 EIGEN_STATIC_ASSERT(4 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
223 return coeff(i0 + i1 * m_dimensions[0] + i2 * m_dimensions[1] * m_dimensions[0] + i3 * m_dimensions[2] * m_dimensions[1] * m_dimensions[0]);
227 EIGEN_STRONG_INLINE
const Scalar& operator()(Index i0, Index i1, Index i2, Index i3, Index i4)
const
229 EIGEN_STATIC_ASSERT(5 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
230 return coeff(i0 + i1 * m_dimensions[0] + i2 * m_dimensions[1] * m_dimensions[0] + i3 * m_dimensions[2] * m_dimensions[1] * m_dimensions[0] + i4 * m_dimensions[3] * m_dimensions[2] * m_dimensions[1] * m_dimensions[0]);
237 Index size = Index(1);
238 for(i = 0; i < NumIndices; i++)
240 Eigen::internal::check_rows_cols_for_overflow<Eigen::Dynamic>::run(size, dimensions[i]);
241 size *= dimensions[i];
244 for(i = 0; i < NumIndices; i++)
245 m_dimensions[i] = dimensions[i];
247 bool size_changed = size != this->size();
248 if(size_changed) m_storage.resize(size);
250 #ifdef EIGEN_INITIALIZE_COEFFS
253 #if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
254 m_storage.fill(Scalar(0));
255 #elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
256 m_storage.fill(std::numeric_limits<Scalar>::quiet_NaN());
262 EIGEN_DEVICE_FUNC
bool operator==(
const Tensor & other)
const
264 return m_storage == other.m_storage;
267 EIGEN_DEVICE_FUNC
bool operator!=(
const Tensor & other)
const
269 return m_storage != other.m_storage;
274 typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1,Options> StorageType;
275 StorageType m_storage;
284 template<
typename Scalar_,
int NumIndices_,
int Options_ = 0,
typename IndexType = Eigen::DenseIndex>
285 using Tensor = Eigen::Tensor<Scalar_,NumIndices_,Options_,IndexType>;
287 #endif // ifndef PINOCCHIO_WITH_EIGEN_TENSOR_MODULE
291 #if !EIGEN_VERSION_AT_LEAST(3,2,90)
292 #undef EIGEN_DEVICE_FUNC
295 #endif // ifndef __pinocchio_math_tensor_hpp__