public void RandomUnitVector()
        {
            var epsilon = 0.0001;

            // unit vector should have length 1
            ThinSvd.RandomUnitVector(10).Magnitude().Should().BeApproximately(1, epsilon);
            // unit vector with single element should be [-1] or [+1]
            Math.Abs(ThinSvd.RandomUnitVector(1)[0]).Should().BeApproximately(1, epsilon);
            // two randomly generated unit vectors should not be equal
            ThinSvd.RandomUnitVector(10).Should().NotBeEquivalentTo(ThinSvd.RandomUnitVector(10));
        }
Exemple #2
0
        public void RandomUnitVector()
        {
            var epsilon = 0.0001;

            // unit vector should have length 1
            Assert.AreEqual(1, V.Magnitude(ThinSvd.RandomUnitVector(10)), epsilon);
            // unit vector with single element should be [-1] or [+1]
            Assert.AreEqual(1, Math.Abs(ThinSvd.RandomUnitVector(1)[0]), epsilon);
            // two randomly generated unit vectors should not be equal
            Assert.AreNotEqual(ThinSvd.RandomUnitVector(10), ThinSvd.RandomUnitVector(10));
        }
Exemple #3
0
        /// <summary>
        /// Return the pseudoinverse of a matrix based on the Moore-Penrose Algorithm.
        /// using Singular Value Decomposition (SVD).
        /// </summary>
        /// <param name="inMat">Input matrix to find its inverse to.</param>
        /// <returns>The inverse matrix approximation of the input matrix.</returns>
        public static double[,] PInv(double[,] inMat)
        {
            // To compute the SVD of the matrix to find Sigma.
            var(u, s, v) = ThinSvd.Decompose(inMat);

            // To take the reciprocal of each non-zero element on the diagonal.
            var len = s.Length;

            var sigma = new double[len];

            for (var i = 0; i < len; i++)
            {
                sigma[i] = (Math.Abs(s[i]) < 0.0001) ? 0 : 1 / s[i];
            }

            // To construct a diagonal matrix based on the vector result.
            var diag = sigma.ToDiagonalMatrix();

            // To construct the pseudo-inverse using the computed information above.
            var matinv = u.Multiply(diag).Multiply(v.Transpose());

            // To Transpose the result matrix.
            return(matinv.Transpose());
        }
        private void CheckSvd(double[,] testMatrix)
        {
            var epsilon = 1E-6;

            double[,] u;
            double[,] v;
            double[] s;
            (u, s, v) = ThinSvd.Decompose(testMatrix, 1e-6 * epsilon, 1000);

            for (var i = 1; i < s.Length; i++)
            {
                // singular values should be arranged from greatest to smallest
                // but there are rounding errors
                (s[i] - s[i - 1]).Should().BeLessThan(1);
            }

            for (var i = 0; i < u.GetLength(1); i++)
            {
                double[] extracted = new double[u.GetLength(0)];
                // extract a column of u
                for (var j = 0; j < extracted.Length; j++)
                {
                    extracted[j] = u[j, i];
                }

                if (s[i] > epsilon)
                {
                    // if the singular value is non-zero, then the basis vector in u should be a unit vector
                    extracted.Magnitude().Should().BeApproximately(1, epsilon);
                }
                else
                {
                    // if the singular value is zero, then the basis vector in u should be zeroed out
                    extracted.Magnitude().Should().BeApproximately(0, epsilon);
                }
            }

            for (var i = 0; i < v.GetLength(1); i++)
            {
                double[] extracted = new double[v.GetLength(0)];
                // extract column of v
                for (var j = 0; j < extracted.Length; j++)
                {
                    extracted[j] = v[j, i];
                }

                if (s[i] > epsilon)
                {
                    // if the singular value is non-zero, then the basis vector in v should be a unit vector
                    Assert.AreEqual(1, extracted.Magnitude(), epsilon);
                }
                else
                {
                    // if the singular value is zero, then the basis vector in v should be zeroed out
                    Assert.AreEqual(0, extracted.Magnitude(), epsilon);
                }
            }

            // convert singular values to a diagonal matrix
            double[,] expanded = new double[s.Length, s.Length];
            for (var i = 0; i < s.Length; i++)
            {
                expanded[i, i] = s[i];
            }


            // matrix = U * S * V^t, definition of Singular Vector Decomposition
            AssertMatrixEqual(testMatrix, u.Multiply(expanded).Multiply(v.Transpose()), epsilon);
            AssertMatrixEqual(testMatrix, u.Multiply(expanded.Multiply(v.Transpose())), epsilon);
        }
Exemple #5
0
        public void CheckSvd(double[,] testMatrix)
        {
            var epsilon = 1E-5;

            double[,] u;
            double[,] v;
            double[] s;
            (u, s, v) = ThinSvd.Decompose(testMatrix, 1E-8, 1000);

            for (var i = 1; i < s.Length; i++)
            {
                // singular values should be arranged from greatest to smallest
                Assert.GreaterOrEqual(s[i - 1], s[i]);
            }

            for (var i = 0; i < u.GetLength(1); i++)
            {
                double[] extracted = new double[u.GetLength(0)];
                // extract a column of u
                for (var j = 0; j < extracted.Length; j++)
                {
                    extracted[j] = u[j, i];
                }

                if (s[i] > epsilon)
                {
                    // if the singular value is non-zero, then the basis vector in u should be a unit vector
                    Assert.AreEqual(1, V.Magnitude(extracted), epsilon);
                }
                else
                {
                    // if the singular value is zero, then the basis vector in u should be zeroed out
                    Assert.AreEqual(0, V.Magnitude(extracted), epsilon);
                }
            }

            for (var i = 0; i < v.GetLength(1); i++)
            {
                double[] extracted = new double[v.GetLength(0)];
                // extract column of v
                for (var j = 0; j < extracted.Length; j++)
                {
                    extracted[j] = v[j, i];
                }

                if (s[i] > epsilon)
                {
                    // if the singular value is non-zero, then the basis vector in v should be a unit vector
                    Assert.AreEqual(1, V.Magnitude(extracted), epsilon);
                }
                else
                {
                    // if the singular value is zero, then the basis vector in v should be zeroed out
                    Assert.AreEqual(0, V.Magnitude(extracted), epsilon);
                }
            }

            // convert singular values to a diagonal matrix
            double[,] expanded = new double[s.Length, s.Length];
            for (var i = 0; i < s.Length; i++)
            {
                expanded[i, i] = s[i];
            }


            // matrix = U * S * V^t, definition of Singular Vector Decomposition
            AssertMatrixEqual(testMatrix, u.Multiply(expanded).Multiply(M.Transpose(v)), epsilon);
            AssertMatrixEqual(testMatrix, u.Multiply(expanded.Multiply(M.Transpose(v))), epsilon);
        }