Eigen can't match unary function

72 Views Asked by At

I am encountering a compile issue with Eigen 3.4.0.

Specifically, I have a template function for calculating the area of a triangle:

template <typename T, int D>
auto TriangleArea(const Eigen::Matrix<T, D, 1>& p0, const Eigen::Matrix<T, D, 1>& p1, const Eigen::Matrix<T, D, 1>& p2) {
    const auto e01 = p1 - p0;
    const auto e02 = p2 - p0;
    return Eigen::sqrt(e01.dot(e01) * e02.dot(e02) - e01.dot(e02) * e01.dot(e02)) / T{2};
}

This code results in an error:

no matching function for call to ‘sqrt(Eigen::ScalarBinaryOpTraits<double, double, Eigen::internal::scalar_product_op<double, double> >::ReturnType)’

How do I fix this issue with sqrt not being found?

1

There are 1 best solutions below

0
Matt On BEST ANSWER

The problem with the template is that dot results in a scalar. Eigen::sqrt is defined for ArrayBase< Derived > as seen here.

dot may be replaced by transpose multiplication which will instead return an Eigen object.

template <typename T, int D>
auto TriangleArea(const Eigen::Matrix<T, D, 1>& p0, const Eigen::Matrix<T, D, 1>& p1, const Eigen::Matrix<T, D, 1>& p2) {
    const auto e01 = p1 - p0;
    const auto e02 = p2 - p0;
    return Eigen::sqrt(
        (e01.transpose() * e01 * e02.transpose() * e02
        - e01.transpose() * e02 * e01.transpose() * e02).array()) / T{2};
}

  Alternatively, since the input to sqrt is a scalar in this case, the standard sqrt may be used.

#include <cmath>
...    
template <typename T, int D>
auto TriangleArea(const Eigen::Matrix<T, D, 1>& p0, const Eigen::Matrix<T, D, 1>& p1, const Eigen::Matrix<T, D, 1>& p2) {
    const auto e01 = p1 - p0;
    const auto e02 = p2 - p0;
    return std::sqrt(e01.dot(e01) * e02.dot(e02) - e01.dot(e02) * e01.dot(e02)) / T{ 2 };
}