Skip to content
This repository has been archived by the owner on Nov 19, 2020. It is now read-only.

Add an overload to IsSymmetric that accepts a tolerance #856

Closed
CatchemAL opened this issue Sep 10, 2017 · 6 comments
Closed

Add an overload to IsSymmetric that accepts a tolerance #856

CatchemAL opened this issue Sep 10, 2017 · 6 comments

Comments

@CatchemAL
Copy link
Collaborator

Currently IsSymmetric() is implemented as a generic method on IComparable. It would be good if it accepted a tolerance. For large symmetric matrices, it feels restrictive if a tiny floating point error caused this to return false.

Will need to be a T4 template job (or just a few special cases like double and float) as IComparable does not allow difference comparisons (AFAIK). I imagine it is faster if it's not generic. Proposed API:

/// Some lovely comments...
/// param isRelative: whether matrix is symmetric based on the relative or absolute error
public static double IsSymmetric(this double[,] a, double tol = 0, bool isRelativeError = false)

so you could say, M[i,j] cannot be different to M[j,i] by more than 0.0001% or maybe 1e-12 etc.

Question

@cesarsouza Is this useful or am I being paranoid (I want it for #832)? Can you envisage any scenario where a matrix that should be symmetric is not exactly symmetric because of tiny rounding errors? if you can, assign this to me, if you can't, feel free to close this issue.

Thanks!
Alex

@CatchemAL
Copy link
Collaborator Author

Not paranoid ;)
I've never seen this get past the third loop.

[Test]
public void IsSymmetricTest2()
{
    for (int i = 0; i < 1000; i++)
    {
        double[,] a = Matrix.Random(2);
        double[,] b = Matrix.Random(2);

        var result = a.Add(b).Add(a.Transpose()).Add(b.Transpose());

        if (!result.IsSymmetric())
            throw new NonSymmetricMatrixException();
    }
}

@cesarsouza
Copy link
Member

Hi @AlexJCross,

Thanks for opening the issue 😄 No, you are not paranoid. It is quite common for almost symmetric - but not quite symmetric - matrices to exist. However, I would suggest using the same API as the IsEquals method, using "atol" and "rtol" parameters. The reason for that is that this is similar to the API used in sklearn and scipy and that therefore some users might be more used to.

However, unless you need such a method for the other issues you have been working on, maybe you could leave this one as a future task. I can also try to take care of this issue - but if you think you would like to give you a try, please feel free to do so!

Regards,
Cesar

@CatchemAL
Copy link
Collaborator Author

I like it (never knew the IsEquals can compare relative!):

public static double IsSymmetric(this double[,] a, double atol = 0, double rtol = 0)

Ok, well I need it for an issue so I'll check in something but it might be an internal static for now. If you get time to industrialise it before me, by all means do.

Thanks v much,
Alex

@cesarsouza cesarsouza self-assigned this Sep 10, 2017
@cesarsouza
Copy link
Member

It wasn't too hard to adapt it from the existing IsEqual implementations, I might be able to commit it in the following minutes. Tests are still running though.

@CatchemAL
Copy link
Collaborator Author

Thanks!

@cesarsouza
Copy link
Member

Added in 3.8.0.

@cesarsouza cesarsouza added this to the 3.8 milestone Oct 22, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants