# C# Convolution Example

← All NMath Code Examples

```using System;
using System.Globalization;
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." );