2

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;
}
2
  • Error: no matching function for call to ‘makeSkewSymmetric(const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, const Eigen::Matrix<double, 3, 1>, const Eigen::Matrix<double, 3, 1> >) Commented Sep 11, 2013 at 0:12
  • Was just about to post the static_assert solution, although with c++11's static assert instead of boost's... I can't think of anything else (apart from assigning the result of a+a to another Vector3d first, but of course that defeats the point of having expression templates in the first place...) Commented Sep 11, 2013 at 0:31

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.