Skip to content

Commit 3519a39

Browse files
committed
[Core] Overload Eigen::Ref to comply with Numpy row-major
1 parent d9cf8d9 commit 3519a39

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ SET(HEADERS
103103
registration.hpp
104104
angle-axis.hpp
105105
quaternion.hpp
106+
ref.hpp
106107
)
107108

108109
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy")

src/ref.hpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2018, Justin Carpentier <[email protected]>, LAAS-CNRS
3+
*
4+
* This file is part of eigenpy.
5+
* eigenpy is free software: you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public License
7+
* as published by the Free Software Foundation, either version 3 of
8+
* the License, or (at your option) any later version.
9+
* eigenpy is distributed in the hope that it will be
10+
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details. You should
13+
* have received a copy of the GNU Lesser General Public License along
14+
* with eigenpy. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
17+
#ifndef __eigenpy_ref_hpp__
18+
#define __eigenpy_ref_hpp__
19+
20+
#include "eigenpy/fwd.hpp"
21+
22+
namespace eigenpy
23+
{
24+
template<typename MatType, int IsVectorAtCompileTime = MatType::IsVectorAtCompileTime>
25+
struct StrideType
26+
{
27+
typedef Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic> type;
28+
};
29+
30+
template<typename MatType>
31+
struct StrideType<MatType,1>
32+
{
33+
typedef Eigen::InnerStride<Eigen::Dynamic> type;
34+
};
35+
36+
template<typename PlainObjectType>
37+
struct Ref : Eigen::Ref<PlainObjectType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,typename StrideType<PlainObjectType>::type>
38+
{
39+
public:
40+
typedef Eigen::Ref<PlainObjectType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,typename StrideType<PlainObjectType>::type> Base;
41+
42+
private:
43+
typedef Eigen::internal::traits<Base> Traits;
44+
template<typename Derived>
45+
EIGEN_DEVICE_FUNC inline Ref(const Eigen::PlainObjectBase<Derived>& expr,
46+
typename Eigen::internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
47+
48+
public:
49+
50+
typedef typename Eigen::internal::traits<Base>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \
51+
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \
52+
typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \
53+
typedef typename Eigen::internal::ref_selector<Base>::type Nested; \
54+
typedef typename Eigen::internal::traits<Base>::StorageKind StorageKind; \
55+
typedef typename Eigen::internal::traits<Base>::StorageIndex StorageIndex; \
56+
enum { RowsAtCompileTime = Eigen::internal::traits<Base>::RowsAtCompileTime, \
57+
ColsAtCompileTime = Eigen::internal::traits<Base>::ColsAtCompileTime, \
58+
Flags = Eigen::internal::traits<Base>::Flags, \
59+
SizeAtCompileTime = Base::SizeAtCompileTime, \
60+
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
61+
IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \
62+
using Base::derived; \
63+
using Base::const_cast_derived;
64+
typedef typename Base::PacketScalar PacketScalar;
65+
66+
template<typename Derived>
67+
EIGEN_DEVICE_FUNC inline Ref(Eigen::PlainObjectBase<Derived>& expr,
68+
typename Eigen::internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
69+
: Base(expr.derived())
70+
{}
71+
72+
template<typename Derived>
73+
EIGEN_DEVICE_FUNC inline Ref(const Eigen::DenseBase<Derived>& expr,
74+
typename Eigen::internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
75+
: Base(expr.derived())
76+
{}
77+
78+
#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || defined(__CUDACC_VER__)) // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
79+
using Base::operator =;
80+
#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
81+
using Base::operator =; \
82+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Ref& operator=(const Ref& other) { Base::operator=(other); return *this; } \
83+
template <typename OtherDerived> \
84+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Ref& operator=(const Eigen::DenseBase<OtherDerived>& other) { Base::operator=(other.derived()); return *this; }
85+
#else
86+
using Base::operator =; \
87+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Ref& operator=(const Ref& other) \
88+
{ \
89+
Base::operator=(other); \
90+
return *this; \
91+
}
92+
#endif
93+
94+
}; // struct Ref<PlainObjectType>
95+
}
96+
97+
#endif // ifndef __eigenpy_ref_hpp__

0 commit comments

Comments
 (0)