Skip to content

JacobiSVD Outputs Invalid U (Reads Past End of Array)

Summary

In Eigen 3.4-rc1 and the current master, but not not in 3.3.9, when given an array with a lot of NaNs, calls to Eigen::JacobiSVDEigen::MatrixXd CSVD(C, Eigen::ComputeFullU); Eigen::MatrixXd U=CSVD.matrixU(); return an invalid U matrix and the creation of the matrix appears to involve reading past the end of an array.

Environment

The problem was seen was run using Clang on Mac OS X 11.4 and using Microsoft Visual Studio on Windows 10. It is NOT in Eigen 3.3.9, but it is in Eigen 3.4-rc1 and the current Master. No compilers flags were used for the minimal example below.

Minimal Example

#include "Eigen/Dense"
#include "Eigen/SVD"

//For NAN
#include <cmath>
#include <iostream>
int main() {
    Eigen::MatrixXd C(2,2);
    C(0,0)=0;
    C(1,1)=NAN;
    C(0,1)=NAN;
    C(1,0)=NAN;
    std::cout << "C=" << C << std::endl << std::endl;

    const Eigen::JacobiSVD<Eigen::MatrixXd> CSVD(C, Eigen::ComputeFullU);
    Eigen::MatrixXd s=CSVD.singularValues();
    const Eigen::MatrixXd U=CSVD.matrixU();

    std::cout << "U=" << U << std::endl << std::endl;
}

Steps to reproduce

  1. Compile just with something like g++ linking to Eigen/src.
  2. Run the compiled program.
  3. Look at the cout'ted output.

What is the current bug behavior?

One will typically see C= 0 nan nan nan

U=0 0 0 0 However the value for U can be different. It tends to be all zeros when compiled with clang under OS X, but when compiled with Visual Studio on Windows, it is just random junk that is different every time the program is run.

What is the expected correct behavior?

The columns of U should be unit vectors. I'd expect it would probably be an identity matrix or some permutation of the columns of an identity matrix. However, any matrix whole columns are unit vectors would be valid. It should NOT be random. That indicates reading past the end of an array.

Relevant logs

Anything else that might help