c++eigen3

Eigen can't match unary function


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?


Solution

  • 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 };
    }