gradientspace / geometry3Sharp

C# library for 2D/3D geometric computation, mesh algorithms, and so on. Boost license.
http://www.gradientspace.com
Boost Software License 1.0
1.69k stars 380 forks source link

My first test case for SingularValueDecomposition fails #168

Open ScottJohnson2718 opened 2 years ago

ScottJohnson2718 commented 2 years ago

I'm trying out the SingularValueDecomposition and so I made up a simple test case to see if I am using it correctly. It failed though. The SVD factors a matrix into A = U S V^T. So of course I should be able to multiply them back to get the original matrix A.

Any help is appreciated.

public static void Test()
{
        var RotX30 = Matrix3d.AxisAngleD(Vector3d.AxisX, 30.0);

        // Computes U/S/V of  A = U * S * V^T
        var svd = new SingularValueDecomposition(3, 3, 100);
        svd.Solve(RotX30.ToBuffer());

        double[] singularValues = new double[3];
        svd.GetSingularValues(singularValues);
        var S = new Matrix3d(singularValues[0], singularValues[1], singularValues[2]);

        double[] Varray = new double[9];
        svd.GetV(Varray);
        var Vt = new Matrix3d(Varray);
        Vt = Vt.Transpose();    

        double[] Uarray = new double[9];
        svd.GetU(Uarray);
        Matrix3d U = new Matrix3d(Uarray);

        var A = U * S * Vt;
        if (A.EpsilonEqual(RotX30, 0.0001))
        {
            Debug.Log("Test03 : passed");
        }
        else
        {
            Debug.Log("Test03 : failed");
        }
 }

The computed answer is off by a negative sign. The result is not a valid rotation matrix.

ScottJohnson2718 commented 2 years ago

I posted a C++ version of this to the Geometric Tools site and Eberly rewrote the SVD as a result. The code needs to be ported to C# again in order to use it.