mathnet / mathnet-numerics

Math.NET Numerics
http://numerics.mathdotnet.com
MIT License
3.51k stars 898 forks source link

Matrix (5000x5000) inverse takes 25 minutes to compute #677

Open leonImpact opened 5 years ago

leonImpact commented 5 years ago

Hi all,

I'm trying to calculate the inverse of a 5000 by 5000 matrix with MathNet Numerics in F#. The same calculation in Python using numpy takes about 10 seconds. Using MathNet.Numerics.LinearAlgebra.Matrix.Inverse it took me 28 minutes. Probably, this is partly because my matrix is "almost singular" (as a cleaner matrix "only" takes 5 minutes to calculate). Using PsuedoInverse didn't make it much faster (25 minutes).

Am I missing something or is this an actual flaw?

Thanks, Leon

Evangelink commented 4 years ago

I gave up after 15min but I confirm that I am seeing the same behavior.

leonImpact commented 4 years ago

Thanks for trying @Evangelink!

mingzhao03 commented 4 years ago

@leonImpact Are you using the Intel MKL optimized version (MathNet.Numerics.MKL.Win-x64 etc.)? If I try to inverse a 5000x5000 double random matrix with Intel MKL, it took about 3 seconds on my desktop (i7 4770k). After I removed reference to the MKL native library and just use MathNet.Numerics, it's been 7 minutes and counting since I started the same matrix inversion.

Evangelink commented 4 years ago

@mingzhao03 In my case I wasn't using any optimized version.

TPLeon commented 4 years ago

@mingzhao03 thanks, that actually worked in order to quicken the pace of the programme to 5 seconds per matrix. Still, applying the function to a matrix that is singular gives an error message with no matrix to return. In Python, one gets a matrix in return with NaNs for the elements that make the matrix singular. This is a very handy feature when dealing with big datasets in which one can leave out such data points after the calculation.

If you have tips on this, I'd be very pleased! Otherwise, I'll close this issue.

mingzhao03 commented 4 years ago

@TPLeon It seems like the exception is not happening consistently for me. If I inverse a matrix with all zeros, it seems like the first time I run it I get a "MathNet.Numerics.SingularUMatrixException", but on subsequent runs I get a return matrix with all NaNs. If I change the matrix size and recompile the code, I get the exception on the first run again, and then subsequent runs returns matrix with NaN. I am using MathNet.Numerics v4.9.0 and MathNet.Numerics.MKL.Win-x64 v2.3.0 in C#. This inconsistency is weird.

I guess you can do try/catch (try/with in F#?) to capture the exception if it does happen, and manually return a NaN matrix instead when the exception occurs.

TPLeon commented 4 years ago

@mingzhao03 Thanks for your time! I have thought of a workaroung for the NaN problem :)