VB Moving Window Filter Example

← All NMath Code Examples


Imports System
Imports System.IO

Imports CenterSpace.NMath.Core

Namespace CenterSpace.NMath.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 dont have any points to the left, similarly, when 
      replacing the last input value, we dont 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