/// <summary> /// Multilevel 1-D Discreete Wavelet Transform /// </summary> /// <param name="signal">The signal. Example: new Signal(5, 6, 7, 8, 1, 2, 3, 4)</param> /// <param name="motherWavelet">The mother wavelet to be used. Example: CommonMotherWavelets.GetWaveletFromName("DB4")</param> /// <param name="level">The depth-level to perform the DWT</param> /// <param name="extensionMode">Signal extension mode</param> /// <param name="convolutionMode">Defines what convolution function should be used</param> /// <returns></returns> public static List <DecompositionLevel> ExecuteDWT(Signal signal, MotherWavelet motherWavelet, int level, SignalExtension.ExtensionMode extensionMode = SignalExtension.ExtensionMode.SymmetricHalfPoint, ConvolutionModeEnum convolutionMode = ConvolutionModeEnum.ManagedFFT) { var levels = new List <DecompositionLevel>(); var approximation = (double[])signal.Samples.Clone(); var details = (double[])signal.Samples.Clone(); var realLength = signal.Samples.Length; for (var i = 1; i <= level; i++) { var extensionSize = motherWavelet.Filters.DecompositionLowPassFilter.Length - 1; approximation = SignalExtension.Extend(approximation, extensionMode, extensionSize); details = SignalExtension.Extend(details, extensionMode, extensionSize); approximation = WaveMath.Convolve(convolutionMode, approximation, motherWavelet.Filters.DecompositionLowPassFilter); approximation = WaveMath.DownSample(approximation); details = WaveMath.Convolve(convolutionMode, details, motherWavelet.Filters.DecompositionHighPassFilter); details = WaveMath.DownSample(details); realLength = realLength / 2; levels.Add(new DecompositionLevel { Signal = signal, Index = i - 1, Approximation = approximation, Details = details }); details = (double[])approximation.Clone(); } return(levels); }
/// <summary> /// Executes the block /// </summary> public override void Execute() { var inputNode1 = InputNodes[0].ConnectingNode as BlockOutputNode; var inputNode2 = InputNodes[1].ConnectingNode as BlockOutputNode; if (inputNode1 == null || inputNode1.Object == null || inputNode2 == null || inputNode2.Object == null) { return; } var outputs = new List <Signal>(); var signals = inputNode1.Object; var filters = inputNode2.Object; for (var i = 0; i < signals.Count; i++) { var signal = signals[i]; if (filters.Count == 0) { outputs.Add(signal.Clone()); continue; } var output = signal.Copy(); var filterIndex = i < filters.Count ? i : 0; output.Samples = WaveMath.Convolve(ConvolutionMode, signal.Samples, filters[filterIndex].Samples, ReturnOnlyValid, 0, FFTMode); outputs.Add(output); } OutputNodes[0].Object = outputs; if (Cascade && OutputNodes[0].ConnectingNode != null) { OutputNodes[0].ConnectingNode.Root.Execute(); } }
public void TestConvolve() { var signal = new double[] { 1, 2, 3, 4, 5, 6, 7, 8 }; var filter = new double[] { 1, 2, 3 }; var convolved = WaveMath.Convolve(ConvolutionModeEnum.Normal, signal, filter); var expected = new double[] { 10, 16, 22, 28, 34, 40 }; Assert.IsTrue(convolved.SequenceEqual(expected)); signal = new double[] { 1, 2, 3 }; filter = new double[] { 1, 2, 3, 4, 5 }; convolved = WaveMath.ConvolveNormal(signal, filter); expected = new double[] { 10, 16, 22 }; Assert.IsTrue(convolved.SequenceEqual(expected)); signal = new double[] { 1, 2, 3, 4, 5, 6, 7, 8 }; filter = new double[] { 1, 2, 3, 4 }; convolved = WaveMath.ConvolveNormal(signal, filter, false); expected = new double[] { 1, 4, 10, 20, 30, 40, 50, 60, 61, 52, 32 }; Assert.IsTrue(convolved.SequenceEqual(expected)); }
/// <summary> /// Multilevel inverse discrete 1-D wavelet transform /// </summary> /// <param name="decompositionLevels">The decomposition levels of the DWT</param> /// <param name="motherWavelet">The mother wavelet to be used. Example: CommonMotherWavelets.GetWaveletFromName("DB4") </param> /// <param name="level">The depth-level to perform the DWT</param> /// <param name="convolutionMode">Defines what convolution function should be used</param> /// <returns></returns> public static double[] ExecuteIDWT(List <DecompositionLevel> decompositionLevels, MotherWavelet motherWavelet, int level = 0, ConvolutionModeEnum convolutionMode = ConvolutionModeEnum.ManagedFFT) { if (level == 0 || level > decompositionLevels.Count) { level = decompositionLevels.Count; } if (level <= 0) { return(null); } var approximation = (double[])decompositionLevels[level - 1].Approximation.Clone(); var details = (double[])decompositionLevels[level - 1].Details.Clone(); for (var i = level - 1; i >= 0; i--) { approximation = WaveMath.UpSample(approximation); approximation = WaveMath.Convolve(convolutionMode, approximation, motherWavelet.Filters.ReconstructionLowPassFilter, true, -1); details = WaveMath.UpSample(details); details = WaveMath.Convolve(convolutionMode, details, motherWavelet.Filters.ReconstructionHighPassFilter, true, -1); //sum approximation with details approximation = WaveMath.Add(approximation, details); if (i <= 0) { continue; } if (approximation.Length > decompositionLevels[i - 1].Details.Length) { approximation = SignalExtension.Deextend(approximation, decompositionLevels[i - 1].Details.Length); } details = (double[])decompositionLevels[i - 1].Details.Clone(); } return(approximation); }
public void TestConvolveManagedFFT() { var signal = new double[] { 1, 2, 3, 4, 5, 6, 7, 8 }; var filter = new double[] { 1, 2, 3 }; var convolved = WaveMath.Convolve(ConvolutionModeEnum.ManagedFFT, signal, filter); var expected = new double[] { 10, 16, 22, 28, 34, 40 }; Assert.IsTrue(TestUtils.SequenceEquals(convolved, expected)); signal = new double[] { 1, 2, 3 }; filter = new double[] { 1, 2, 3, 4, 5 }; convolved = WaveMath.ConvolveManagedFFT(signal, filter); expected = new double[] { 10, 16, 22 }; Assert.IsTrue(TestUtils.SequenceEquals(convolved, expected)); signal = new double[] { 1, 2, 3, 4, 5, 6, 7, 8 }; filter = new double[] { 1, 2, 3, 4 }; convolved = WaveMath.ConvolveManagedFFT(signal, filter, false); expected = new double[] { 1, 4, 10, 20, 30, 40, 50, 60, 61, 52, 32 }; Assert.IsTrue(TestUtils.SequenceEquals(convolved, expected)); Assert.IsNull(WaveMath.ConvolveManagedFFT(null, null, false)); }