← 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
Console.WriteLine()
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)
Console.WriteLine()
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()
Next
Console.WriteLine()
Console.WriteLine("Press Enter Key")
Console.Read()
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()
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()
Next
Next
Return signals
End Function
End Module
End Namespace
← All NMath Code Examples