VB Hermitian Band Matrix 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 banded Hermitian matrix classes.
  Module HermitianBandMatrixExample

    Sub Main()

      ' Set up the parameters that describe the shape of a Hermitian banded matrix.
      Dim HalfBandwidth As Integer = 1
      Dim Order As Integer = 7

      ' Set up an Hermitian banded matrix B by creating a banded complex matrix and setting
      ' B equal to the product of the conjugate transpose of that matrix with itself.
      Dim A As New FloatComplexBandMatrix(Order, Order, HalfBandwidth, HalfBandwidth)
      Dim I As Integer
      For I = -A.LowerBandwidth To A.UpperBandwidth
        A.Diagonal(I).Set(Slice.All, New FloatComplex(I + 2, I - 1))
      Next
      Dim B As New FloatHermitianBandMatrix(MatrixFunctions.Product(A.ConjTranspose(), A))

      Console.WriteLine()
      Console.WriteLine("B = ")
      Console.WriteLine(B.ToTabDelimited("G3"))

      ' B =
      ' (10,0)  (10,6)  (3,6)   (0,0)   (0,0)   (0,0)   (0,0)
      ' (10,-6) (19,0)  (10,6)  (3,6)   (0,0)   (0,0)   (0,0)
      ' (3,-6)  (10,-6) (19,0)  (10,6)  (3,6)   (0,0)   (0,0)
      ' (0,0)   (3,-6)  (10,-6) (19,0)  (10,6)  (3,6)   (0,0)
      ' (0,0)   (0,0)   (3,-6)  (10,-6) (19,0)  (10,6)  (3,6)
      ' (0,0)   (0,0)   (0,0)   (3,-6)  (10,-6) (19,0)  (10,6)
      ' (0,0)   (0,0)   (0,0)   (0,0)   (3,-6)  (10,-6) (14,0)

      ' Indexer accessor works just like it does for general matrices. 
      Console.Write("B[2,2] = ")
      Console.WriteLine(B(2, 2))
      Console.Write("B[5,0] = ")
      Console.WriteLine(B(5, 0))

      ' You can set the values of elements in the bandwidth
      ' of an Hermitian banded matrix using the indexer. Note that setting 
      ' the element in row i and column j to a value implicitly sets the 
      ' element in column j and row i to the complex conjugate of that value.
      Dim Z As New FloatComplex(99, -99)
      B(2, 1) = Z
      Console.Write("B[2,1] = ")
      Console.WriteLine(B(2, 1)) ' (99, -99)
      Console.Write("B[1,2] = ")
      Console.WriteLine(B(1, 2)) ' (99, 99 )

      ' But setting an element outside the bandwidth of the
      ' matrix raises a NonModifiableElementException exception.
      Try
        B(6, 0) = Z
      Catch E As NonModifiableElementException
        Console.WriteLine()
        Console.WriteLine("NonModifiableElementException: " & E.Message)
      End Try

      ' Scalar multiplication and matrix addition/subtraction are supported.
      Z = New FloatComplex(0.0001, 0.0001)
      Dim C As FloatHermitianBandMatrix = Z * B
      Dim D As FloatHermitianBandMatrix = C - B
      Console.WriteLine()
      Console.WriteLine("D =")
      Console.WriteLine(D.ToTabDelimited("F5"))

      ' Matrix/vector inner products too.
      Dim Rng As New RandGenUniform(-1, 1)
      Rng.Reset(&H124)
      Dim X As New FloatComplexVector(B.Cols, Rng)
      Dim Y As FloatComplexVector = MatrixFunctions.Product(B, X)
      Console.Write("Bx = ")
      Console.WriteLine(Y.ToString())

      ' You can transform the non-zero elements of a banded matrix object by using
      ' the Transform() method on its data vector.
      C.DataVector.Transform(NMathFunctions.FloatComplexExpFunc)
      Console.WriteLine()
      Console.WriteLine("exp(C) = ")
      Console.WriteLine(C.ToTabDelimited("F5"))

      ' You can also solve linear systems.
      Dim X2 As FloatComplexVector = MatrixFunctions.Solve(B, Y)

      ' x and x2 should be the same. Let's look at the l2 norm of
      ' their difference.
      Dim Residual As FloatComplexVector = FloatComplexVector.Subtract(X, X2)
      Dim ResidualL2Norm As Double = Math.Sqrt(NMathFunctions.ConjDot(Residual, Residual).Real)
      Console.Write("||x - x2|| = ")
      Console.WriteLine(ResidualL2Norm)

      ' You can calculate inverses too.
      Dim BInv As FloatComplexMatrix = MatrixFunctions.Inverse(B)
      Console.WriteLine()
      Console.WriteLine("BInv = ")
      Console.WriteLine(BInv.ToTabDelimited("F5"))

      ' If your Hermitian banded matrix is positive definite, you can invoke
      ' the Solve function with a third - the isPositiveDefinite 
      ' parameter - set to true. 
      ' First make sure B is positive definite.
      B = New FloatHermitianBandMatrix(MatrixFunctions.Product(A.ConjTranspose(), A))
      Y = MatrixFunctions.Product(B, X)
      X2 = MatrixFunctions.Solve(B, Y, True)   ' 3rd parameter isPositiveDefinite set to true.

      ' See how close Bx is to y by computing the l2 norm of their difference.
      Residual = X - X2
      ResidualL2Norm = Math.Sqrt(NMathFunctions.ConjDot(Residual, Residual).Real)
      Console.Write("PD ||x - x2|| = ")
      Console.WriteLine(ResidualL2Norm)

      ' You can use the Resize() method to change the bandwidths.
      D.Resize(D.Order, 2)

      Console.WriteLine()
      Console.WriteLine("Press Enter Key")
      Console.Read()

    End Sub
  End Module
End Namespace

← All NMath Code Examples
Top