问题
I am trying to write a function that takes fixed size Eigen Types (but templated on Scalar type e.g. float/double). I have read http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html but I am not able to make it work perfectly.
Here is the function definition:
template <typename T>
inline Matrix<T, 3, 3> makeSkewSymmetric(const Matrix<T, 3, 1>& v)
{
Matrix<T, 3, 3> out;
out << 0, -v[2], v[1],
v[2], 0, -v[0],
-v[1], v[0], 0;
return out;
}
Now I am using this as following:
Vector3d a(1,2,3);
Matrix3d ass = makeSkewSymmetric(a); // Compiles
Matrix3d ass = makeSkewSymmetric(a + a); // does NOT compile
I guess, I need to use some sort of MatrixBase<Derived>
, but then how do I restrict the size, as the function only makes sense for vectors of length 3.
Edit: I redefined the function as following. It works, but is there a better way?
template <typename Derived>
inline Matrix<typename Derived::Scalar, 3, 3> makeSkewSymmetric(const MatrixBase<Derived>& v)
{
BOOST_STATIC_ASSERT(Derived::RowsAtCompileTime == 3 && Derived::ColsAtCompileTime == 1);
Matrix<typename Derived::Scalar, 3, 3> out;
out << 0, -v[2], v[1],
v[2], 0, -v[0],
-v[1], v[0], 0;
return out;
}
回答1:
I just thought of a good way of checking the way the Eigen developers would want you to solve this problem. Eigen comes with a cross
function on MatrixBase
, but this function, like yours, is only sensible for 3D vectors - so I dug up the relevant part from the Eigen3 source: (cf Eigen/src/Geometry/OrthoMethods.h
)
...
inline typename MatrixBase<Derived>::template cross_product_return_type<OtherDerived>::type
MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3)
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3)
...
and indeed, Eigen itself uses asserts (albeit its own flavor) to check for dimensions in generalized functions.
来源:https://stackoverflow.com/questions/18730623/fixed-sized-eigen-types-as-parameters