VB Symmetric Band Matrix Example

← 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 banded symmetric matrix classes.
  Module SymmetricBandMatrixExample

    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 a symmetric banded matrix B by creating a banded matrix, A, 
      with random entries, and setting B equal to the product of the transpose 
      of that matrix with itself.
      Dim A As New DoubleBandMatrix(Order, Order, HalfBandwidth, HalfBandwidth)
      Dim Rng As New RandGenUniform(-1, 1)
      Rng.Reset(&H124)
      Dim Diag As DoubleVector

      Fill the non-zero entries of A, a diagonal at a time, with random numbers.
      Dim I As Integer
      For I = -A.LowerBandwidth To A.UpperBandwidth
        Diag = A.Diagonal(I)
        Dim J As Integer
        For J = 0 To Diag.Length - 1
          Diag(J) = Rng.Next()
        Next
      Next

      Dim B As New DoubleSymBandMatrix(MatrixFunctions.TransposeProduct(A, A))

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

      B =
      0.249   -0.0333 0.0835  0       0       0       0
      -0.0333 0.121   -0.12   -0.0858 0       0       0
      0.0835  -0.12   0.196   0.154   0.231   0       0
      0       -0.0858 0.154   0.477   0.581   0.358   0
      0       0       0.231   0.581   1.21    0.408   0.152
      0       0       0       0.358   0.408   0.512   0.277
      0       0       0       0       0.152   0.277   0.647

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

      You can set the values of elements in the bandwidth
      of a symmetric 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 same value.
      Dim Scalar As Double = 99
      B(2, 1) = Scalar
      Console.WriteLine("B[2,1] = " & B(2, 1)) 99
      Console.WriteLine("B[1,2] = " & B(1, 2)) 99

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

      Scalar multiplication and matrix addition/subtraction are supported.
      Dim C As DoubleSymBandMatrix = Scalar * B
      Dim D As DoubleSymBandMatrix = C + B

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

      Matrix/vector inner products too.
      Dim X As New DoubleVector(B.Cols, Rng)
      Dim Y As DoubleVector = MatrixFunctions.Product(B, X)

      Console.Write("Bx = " & Y.ToString("G3"))

      You can transform the non-zero elements of a banded matrix object by using
      the Transform() method on its data vector.
      Change every element of C to its natural log.
      C.DataVector.Transform(NMathFunctions.LogFunc)

      Console.WriteLine("ln(C) =")
      Console.WriteLine(C.ToTabDelimited("G3"))

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

      x and x2 should be the same. Lets look at the l2 norm of
      their difference.
      Dim Residual As DoubleVector = DoubleVector.Subtract(X, X2)
      Dim ResidualL2Norm As Double = Math.Sqrt(NMathFunctions.Dot(Residual, Residual))

      Console.WriteLine()
      Console.Write("||x - x2|| = " & ResidualL2Norm)

      You can calculate the determinant too.
      Dim Det As Double = MatrixFunctions.Determinant(B)

      Console.WriteLine()
      Console.WriteLine()
      Console.Write("Determinant of B = " & Det)

      If your symmetric 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 DoubleSymBandMatrix(MatrixFunctions.TransposeProduct(A, 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.Dot(Residual, Residual))

      Console.WriteLine()
      Console.WriteLine()
      Console.Write("PD ||x - x2|| = " & ResidualL2Norm)
      Console.WriteLine()

      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