VB Moving Window Filter Example

← All NMath Code Examples


Imports System
Imports System.IO

Imports CenterSpace.NMath.Core

Namespace CenterSpace.NMath.Core.Examples.VisualBasic

  ' A .NET example in Visual Basic showing the Savitzky-Golay algorithm for smoothing.
  Module MovingWindowFilterExample

    Sub Main()

      Dim SignalLength As Integer = 2000


      Dim Signal As DoubleVector = NoisySignal(SignalLength)
      Dim noisySignalVariance As Double = NMathFunctions.Variance(Signal)
      Console.WriteLine("Noisy signal variance = " & noisySignalVariance)

      ' Set up a moving average filter with an asymmetric window. A moving window
      ' filter replaces each input data point with a linear combination of 
      ' its surrounding points.  A filter is thus described by the number of
      ' of points to the left and right of the input point and the coefficients
      ' of the linear combination.
      ' This filter will replace each input data point with the average of 
      ' its value with the 4 values to the left, and the 5 values to the right.
      ' Thus the coefficients to use are all equal to one over the number of points 
      ' in the window, 10 in this case.
      Dim numberLeft As Integer = 4
      Dim numberRight As Integer = 5
      Dim filterCoefficients As DoubleVector = MovingWindowFilter.MovingAverageCoefficients(numberLeft, numberRight)
      Dim movingAverageFilter As New MovingWindowFilter(numberLeft, numberRight, filterCoefficients)

      ' Filter the signal. Note that we must specify a boundary option. When
      ' replacing the first input value, we don't have any points to the left, similarly, when 
      ' replacing the last input value, we don't have any point to the right. The "PadWithZeros"
      ' boundary option prepends "numberLeft" zeros and appends "numberRight" zeros to the 
      ' input vector to deal with this.
      Dim filteredSignal As DoubleVector = movingAverageFilter.Filter(Signal, MovingWindowFilter.BoundaryOption.PadWithZeros)
      Dim filteredSignalVariance As Double = NMathFunctions.Variance(filteredSignal)
      Console.WriteLine("Moving Average: filtered signal variance = " & filteredSignalVariance)

      ' Set up a Savitzky-Golay filter. This is a smoothing filter that replaces input values with
      ' the value of a polynomial of specified degree fit through the input value and its
      ' surrounding points. A least squares algorithm is used to determine the fitting polynomial.
      Dim Degree As Integer = 4
      filterCoefficients = MovingWindowFilter.SavitzkyGolayCoefficients(numberLeft, numberRight, Degree)
      Dim savitzkyGolayFilter As New MovingWindowFilter(numberLeft, numberRight, filterCoefficients)

      ' Filter the signal. Here we use a different boundary option: "DoNotFilterBoundaryPoints". 
      ' This option will not filter or replace the first "numberLeft" or last "numberRight"
      ' values of the input signal.
      filteredSignal = savitzkyGolayFilter.Filter(Signal, MovingWindowFilter.BoundaryOption.DoNotFilterBoundaryPoints)

      filteredSignalVariance = NMathFunctions.Variance(filteredSignal)
      Console.WriteLine("Savitzky-Golay: filtered signal variance = " & filteredSignalVariance)

      ' If you are filtering lots of signals with the same length, it is more
      ' economic to use the "Filter" method which allows you to specify
      ' the vector to place the output filtered signal in. This avoids having
      ' to allocate potentially large vectors on every call to "Filter".
      Dim NumSignals As Integer = 10
      Dim noisySignals As DoubleMatrix = NoisySignalsFunction(SignalLength, NumSignals)
      Dim Y As New DoubleVector(Signal.Length)

      Dim I As Integer
      For I = 0 To NumSignals - 1
        Dim S As DoubleVector = noisySignals.Col(I)
        Console.WriteLine(String.Format("Noisy signal {0} variance = {1}", I, NMathFunctions.Variance(S)))
        savitzkyGolayFilter.Filter(S, MovingWindowFilter.BoundaryOption.PadWithZeros, Y)
        Console.WriteLine(String.Format("Savitzky-Golay filtered signal {0} variance = {1}", I, NMathFunctions.Variance(Y)))

      Console.WriteLine("Press Enter Key")

    End Sub

    Function NoisySignal(ByVal Length As Integer) As DoubleVector

      Dim rng As New RandGenNormal()
      Dim Signal As New DoubleVector(Length)
      Dim I As Integer
      For I = 0 To Length - 1
        Signal(I) = Math.Cos(0.2 * I) + rng.Next()
      Return Signal

    End Function

    Function NoisySignalsFunction(ByVal Rows As Integer, ByVal Columns As Integer) As DoubleMatrix

      Dim RNG As New RandGenNormal()
      Dim signals As New DoubleMatrix(Rows, Columns)
      Dim i, j As Integer
      For i = 0 To Rows - 1
        For j = 0 To Columns - 1
          signals(i, j) = Math.Cos(0.2 * i * j) + RNG.Next()
      Return signals

    End Function

  End Module
End Namespace

← All NMath Code Examples