VB SV Decomp Example

← All NMath Code Examples

 

Imports System

Imports CenterSpace.NMath.Core
Imports CenterSpace.NMath.Matrix

Namespace CenterSpace.NMath.Matrix.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. 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.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
Top