using System; using System.Globalization; using System.Threading; using System.Text; using CenterSpace.NMath.Core; namespace CenterSpace.NMath.Examples.CSharp { /// <summary> /// .NET example in C# showing how to use the convolution classes. /// </summary> class ConvolutionExample { static void Main( string[] args ) { # region moving average filter with convolution // // Simple example to compute a moving average filter with convolution // // Create some random signal data. var rand = new RandGenMTwist( 4230987 ); var data = new DoubleVector( 500, rand ); // Create a simple averaging kernel. var kernel = new DoubleVector( "[.2 .2 .2 .2 .2]" ); // Create the convolution class. var convolution = new Double1DConvolution( kernel, data.Length ); // Compute the convolution. DoubleVector smoothed = convolution.Convolve( data ); Console.WriteLine(); Console.WriteLine(); Console.WriteLine( "Double precision 1D convolution computed." ); Console.WriteLine( "-----------------------------------------\n" ); #endregion # region single precision convolution example // // Simple example to compute a single precision convolution // // Create some random signal data. var dataF = new FloatVector( "[ 1, 2, 3, 7, 2, 1 ]" ); // Create the averaging kernel float[] kernelF = { .2f, .2f, .2f, .2f, .2f, }; // Create the convolution class and compute the convolution // When only the kernel and data length is specified in this constructor, the // convolution results are truncated to match the length of the input data. // This is typically what most users need. var convolutionF = new Float1DConvolution( new FloatVector( kernelF ), dataF.Length ); // Using the convolution length allows up to exactly size the output data buffer. var smoothedF = new FloatVector( convolutionF.Length ); // Execute the convolution convolutionF.Convolve( dataF, ref smoothedF ); // Trim the results of the convolution where the kernel fully overlapped the data set. // NOTE: This trim just makes a new view into the convolution result, no data is copied. FloatVector trimmedKernelSmoothedDataF = convolutionF.TrimConvolution( smoothedF, ConvolutionBase.Windowing.FullKernelOverlap ); // Trim the results to the center of the convolution that matches the input data size. FloatVector trimmedDataSmoothedDataF = convolutionF.TrimConvolution( smoothedF, ConvolutionBase.Windowing.CenterWindow ); // Write out results Console.WriteLine( "Convolution results showing smoothed data." ); Console.WriteLine( "Input data = " ); Console.WriteLine( dataF.ToString() ); Console.WriteLine( "Convolution kernel = " ); Console.WriteLine( new FloatVector( kernelF ).ToString() ); Console.WriteLine( "Convolved data = " ); Console.WriteLine( smoothedF.ToString() ); Console.WriteLine( "Trimmed smooth data to fully overlapping kernel = " ); Console.WriteLine( trimmedKernelSmoothedDataF.ToString() ); Console.WriteLine( "Trimmed smooth data centered on data length = " ); Console.WriteLine( trimmedDataSmoothedDataF.ToString() ); Console.WriteLine( "-----------------------------------\n" ); #endregion # region complex double precision convolution example // // Simple example to compute a complex double precision convolution with real data. // // Create some real signal data and complex kernel // Naturally the data could be complex, and the following code would be unchanged. var kernelZ = new DoubleComplexVector( "(1,1) (2,2) (3,3) (4,4)" ); var dataZ = new DoubleComplexVector( "(1,0) (2,0) (3,0) (4,0) (5,0) (6,0)" ); // Create the convolution class and compute the convolution // When only the kernel and data length is specified in this constructor, the // convolution results are truncated to match the length of the input data. // This is typically what most users need, with the convolution edge effects removed. var convolutionZ = new DoubleComplex1DConvolution( kernelZ, dataZ.Length ); DoubleComplexVector smoothedDataZ = convolutionZ.Convolve( dataZ ); // Write out results Console.WriteLine( "Complex convolution results with a complex kernel and real data." ); Console.WriteLine( "Input data = " ); Console.WriteLine( dataZ.ToString() ); Console.WriteLine( "Complex convolution kernel = " ); Console.WriteLine( kernelZ.ToString() ); Console.WriteLine( "Convolved data = " ); Console.WriteLine( smoothedDataZ.ToString() ); Console.WriteLine( "-----------------------------------\n" ); #endregion # region single precision convolution with full length output and strided kernel // // Simple example to compute a single precision convolution with full length output // and a strided kernel. // // Create some random signal data. float[] dataFS = { 1, 2, 3, 7, 2, 1 }; // Create the strided averaging kernel float[] kernelFS = { .2f, -1f, .2f, -1f, .2f, -1f, .2f, -1f, .2f, }; // Create the convolution class and compute the convolution // Using this constructor we can specific an offset and strided kernel, the length // of the data, and the output length. To find the full length of the // convolution data, use the Float1DConvolution.OutputLength property as seen below. // (This may be shorter than the length specified in this constructor.) var convolutionFS = new Float1DConvolution( kernelFS, 0, 2, dataFS.Length ); // Do the convolution and get the generated result. float[] smoothedDataFS = convolutionFS.Convolve( dataFS ); // Write out results Console.WriteLine( "Convolution results with a 2-strided kernel." ); Console.WriteLine( "Input data = " ); Console.Write( "[ " ); for ( int i = 0; i < dataFS.Length; i++ ) { Console.Write( "{0,2:0.#} ", dataFS[i] ); } Console.WriteLine( "]" ); Console.WriteLine( "Strided convolution kernel = " ); Console.Write( "[ " ); for ( int i = 0; i < kernelFS.Length; i++ ) { Console.Write( "{0,2:0.#} ", kernelFS[i] ); } Console.WriteLine( "]" ); Console.WriteLine( "Convolved data = " ); Console.Write( "[ " ); for ( int i = 0; i < convolutionFS.Length; i++ ) { Console.Write( "{0,2:0.#} ", smoothedDataFS[i] ); } Console.WriteLine( "]" ); Console.WriteLine( "-----------------------------------\n" ); #endregion Console.WriteLine(); Console.WriteLine( "Finished. Press Enter Key." ); Console.Read(); } } }← All NMath Code Examples