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)); }
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)); }
/// <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); }
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); }