Skip to content

In-place functions should assert inputs are not equal to this

Summary

Functions like computeInverseWithCheck are const and take a matrix as an input argument. If that matrix is the object itself then the computed inverse is wrong since the algorithm doesn't really make sense in that case.

I looked through Eigen and I don't see any similar assertions, but I believe the best fix would be to assert that the first argument to computeInverseWithCheck and computeInverseAndDetWithCheck is not the same object as this.

Environment

  • Operating System : Linux (this is probably irrelevant)
  • Architecture : x64
  • Eigen Version : 3.2.5 - 3.3.9 (I checked them all - they all produce the same wrong answer in this case)
  • Compiler Version : GCC11.1 (unlikely to be relevant)
  • Compile Flags : any (it's independent of optimization levels)
  • Vector Extension : any (it's independent of optimization levels)

Minimal Example

#include <Eigen/Core>
#include <Eigen/LU>

#include <cmath>
#include <iostream>

int main()
{
    Eigen::Matrix<double, 2, 2> matrix;
    matrix(0, 0) = 0.403576;
    matrix(0, 1) = 0.27598;
    matrix(1, 0) = 0.27598;
    matrix(1, 1) = 0.827524;

    bool invertible = false;
    decltype(matrix) inv = matrix;
    // always the wrong inverse
    inv.computeInverseWithCheck(inv, invertible);
    decltype(matrix) error = decltype(matrix)::Identity() - inv * matrix;

    std::cout << "Eigen3 version " << EIGEN_WORLD_VERSION << '.'
              << EIGEN_MAJOR_VERSION << '.' << EIGEN_MINOR_VERSION << std::endl;
    std::cout << inv << std::endl;
    std::cout << "error = " << error.norm() << std::endl;
}

output is

Eigen3 version 3.3.9
 3.2099 -1.0705
-1.0705 12.4509
error = 9.49575

The bottom right should be 0.827524: the other inverse entries are correct.

Steps to reproduce

Call a const function with an output variable equal to this

What is the current bug behavior?

The computed inverse is wrong

What is the expected correct behavior?

An assertion failure

Relevant logs

N/A