VB.NET SV Decomp Example

[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]