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