[TOC]
Imports System
Imports CenterSpace.NMath.Core
Imports CenterSpace.NMath.Matrix
Namespace CenterSpace.NMath.Matrix.Examples.VisualBasic
' A .NET example in VB.NET 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)
' Look at the components of the factorization A = USV'.
Console.WriteLine()
Console.Write("U = ")
Console.WriteLine(Decomp.LeftVectors.ToString("F4"))
Console.WriteLine()
Console.Write("V = ")
Console.WriteLine(Decomp.RightVectors.ToString("F4"))
Console.WriteLine()
Console.Write("s = ")
Console.WriteLine(Decomp.SingularValues)
' U = 6x3 [ (-0.1773,0.4673) (-0.2035,0.0897) (0.0996,-0.1514)
' (0.1020,0.0811) (0.2107,0.1197) (0.0504,-0.2434)
' (0.0774,-0.5596) (-0.2614,0.0474) (0.1327,0.3823)
' (0.2475,-0.1521) (0.0260,0.2871) (-0.4492,-0.1731)
' (0.1298,-0.5129) (0.1649,-0.2407) (0.2869,-0.6443)
' (-0.1468,-0.1681) (0.2985,0.7510) (-0.0955,-0.0581) ]
'
' V = 3x3 [ (0.5561,0.0000) (0.6742,0.0000) (-0.4859,0.0000)
' (-0.6442,-0.1739) (0.5122,-0.2140) (-0.0265,-0.4959)
' (-0.4539,0.1988) (0.3357,0.3529) (-0.0537,0.7172) ]
'
' s = [ 2.30473458507626 1.59555281597513 1.05912909184625 ]
'
' Note that the singular values, elements on the main diagonal of
' the diagonal matrix S, the 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.Write("Full SVD, U = ")
Console.WriteLine(Decomp.LeftVectors.ToString("F4"))
' U = 6x6
' [ (-0.1773,0.4673) (-0.2035,0.0897) (0.0996,-0.1514) (0.1572,-0.1525) (0.6281,0.4364) (-0.0526,-0.1796)
' (0.1020,0.0811) (0.2107,0.1197) (0.0504,-0.2434) (-0.1824,0.2282) (-0.0817,0.3425) (-0.6056,0.5352)
' (0.0774,-0.5596) (-0.2614,0.0474) (0.1327,0.3823) (0.0384,0.4186) (0.4310,0.0384) (-0.2681,-0.1039)
' (0.2475,-0.1521) (0.0260,0.2871) (-0.4492,-0.1731) (0.7009,-0.0308) (-0.1625,0.1318) (-0.1724,-0.1873)
' (0.1298,-0.5129) (0.1649,-0.2407) (0.2869,-0.6443) (-0.0732,-0.2579) (0.1492,0.0899) (0.0388,-0.1840)
' (-0.1468,-0.1681) (0.2985,0.7510) (-0.0955,-0.0581) (-0.3352,0.1166) (0.0718,0.1567) (0.3387,-0.1195) ]
' 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.WriteLine()
Console.Write("Rank of A = ")
Console.WriteLine(Decomp.Rank) ' 3
' Apparently A has full rank. Let's 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.38294957152069E-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
[TOC]