← All NMath Code Examples
Imports System
Imports CenterSpace.NMath.Core
Namespace CenterSpace.NMath.Examples.VisualBasic
A .NET example in Visual Basic demonstrating the features of the singular value decomposition class.
Module SVDecompExample
Sub Main()
A general m x n system with random entries.
Dim Rng As New RandGenUniform(-1, 1)
Rng.Reset(&H124)
Dim Rows As Integer = 6
Dim Cols As Integer = 3
Dim A As New DoubleComplexMatrix(Rows, Cols, Rng)
Construct a QR decomposition of A.
Dim Decomp As New DoubleComplexSVDecomp(A)
Console.WriteLine()
Look at the components of the factorization A = USV.
Console.WriteLine("U = ")
Console.WriteLine(Decomp.LeftVectors.ToTabDelimited("G3"))
Console.WriteLine("B = ")
Console.WriteLine(Decomp.RightVectors.ToTabDelimited("G3"))
Console.Write("s = ")
Console.WriteLine(Decomp.SingularValues)
U =
(-0.177,0.467) (-0.204,0.0897) (0.0996,-0.151)
(0.102,0.0811) (0.211,0.12) (0.0504,-0.243)
(0.0774,-0.56) (-0.261,0.0474) (0.133,0.382)
(0.247,-0.152) (0.026,0.287) (-0.449,-0.173)
(0.13,-0.513) (0.165,-0.241) (0.287,-0.644)
(-0.147,-0.168) (0.298,0.751) (-0.0955,-0.0581)
B =
(0.556,0) (0.674,0) (-0.486,0)
(-0.644,-0.174) (0.512,-0.214) (-0.0265,-0.496)
(-0.454,0.199) (0.336,0.353) (-0.0537,0.717)
s = [ 2.30473458507626 1.59555281597513 1.05912909184625 ]
Note that the singular values, elements on the main diagonal of
the diagonal matrix S, are returned as a vector.
The class DoubleComplexSVDecompServer allows more control over the
computation. Suppose that you am only interested in the singular values,
not the vectors. You can configure a DoubleComplexSVDecompServer object
to compute just the singular values.
Dim DecompServer As New DoubleComplexSVDecompServer()
DecompServer.ComputeLeftVectors = False
DecompServer.ComputeRightVectors = False
Decomp = DecompServer.GetDecomp(A)
Console.WriteLine()
Console.Write("Number of right vectors computed: ")
Console.WriteLine(Decomp.NumberRightVectors) 0
Console.WriteLine()
Console.Write("Number of left vectors computed: ")
Console.WriteLine(Decomp.NumberLeftVectors) 0
By default, the "reduced" SVD is computed, that is, if A is m x n then U
is m x n. The "full" SVD is obtained by adjoining an addition m -n
(assuming m > n) orthonormal columns to U making it a m x m unitary matrix.
The singular value decomposition server object can be configured to
compute the full SVD:
DecompServer.ComputeLeftVectors = True
DecompServer.ComputeFull = True
Decomp = DecompServer.GetDecomp(A)
Console.WriteLine()
Console.WriteLine("Full SVD, U = ")
Console.WriteLine(Decomp.LeftVectors.ToTabDelimited("G5"))
Full SVD, U =
(-0.17729,0.46733) (-0.20351,0.089678) (0.099576,-0.15138) (0.15718,-0.15252) (0.62805,0.4364) (-0.052634,-0.17958)
(0.10202,0.081075) (0.21072,0.11971) (0.0504,-0.2434) (-0.1824,0.22817) (-0.081697,0.34255) (-0.60561,0.53516)
(0.077361,-0.55956) (-0.26138,0.047439) (0.13273,0.38226) (0.038401,0.41859) (0.431,0.038413) (-0.2681,-0.10388)
(0.24748,-0.15212) (0.026012,0.28707) (-0.44923,-0.17313) (0.70087,-0.030787) (-0.1625,0.13184) (-0.17238,-0.1873)
(0.12984,-0.51288) (0.16486,-0.24073) (0.28688,-0.64427) (-0.073218,-0.25794) (0.1492,0.089866) (0.038802,-0.18397)
(-0.14678,-0.16813) (0.29846,0.75096) (-0.095458,-0.058056) (-0.33519,0.11664) (0.071816,0.15674) (0.33872,-0.11948)
You can also set a tolerance for the singular values. Singular values
whose value is less than the tolerance are set to zero. The number of
singular vectors are adjusted accordingly.
Make A rank deficient.
A.Col(0)(Slice.All) = A.Col(1) Two equal columns.
DecompServer.ComputeFull = False
DecompServer.ComputeLeftVectors = True
DecompServer.ComputeRightVectors = True
Decomp = DecompServer.GetDecomp(A)
Console.Write("Rank of A = ")
Console.WriteLine(Decomp.Rank) 3
Apparently A has full rank. Lets look at the smallest
singular value. Singular values are arranged in descending
order, so the smallest value is the last value.
Console.WriteLine()
Console.Write("Smallest singular value = ")
Console.WriteLine(Decomp.SingularValue(2)) 5.48294957152069E-17
This singular value is equal to 0, within machine precision. Truncating the SVD
will set this value to 0.
Dim Tolerance As Double = 0.0000000000000001
DecompServer.Tolerance = 0.0000000000000001
Decomp = DecompServer.GetDecomp(A)
Now look at the rank.
Console.WriteLine()
Console.Write("Rank of A = ")
Console.WriteLine(Decomp.Rank) 2
You can also truncate an existing decomp by calling its
truncate method with a specified tolerance.
Tolerance *= 10000
Decomp.Truncate(Tolerance)
Console.WriteLine()
Console.WriteLine("Press Enter Key")
Console.Read()
End Sub
End Module
End Namespace
← All NMath Code Examples