diff --git a/src/Numerics.Tests/WindowTest.cs b/src/Numerics.Tests/WindowTest.cs new file mode 100644 index 00000000..3d913e8c --- /dev/null +++ b/src/Numerics.Tests/WindowTest.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; + +namespace MathNet.Numerics.Tests +{ + [TestFixture, Category("WindowFunctions")] + public class WindowTest + { + + [Test] + public void TukeyWin0() + { + + var expected = new[] { 1, 1, 1, 1, 1, 1 }; + var actual = Window.Tukey(6, 0); + + Assert.That(actual, Is.EqualTo(expected).Within(0.00005)); + + } + + [Test] + public void TukeyWin1() + { + + var expected = new[] { 0, 0.3455, 0.9045, 0.9045, 0.3455, 0 }; + var actual = Window.Tukey(6, 1); + + Assert.That(actual, Is.EqualTo(expected).Within(0.00005)); + + } + + [Test] + public void TukeyWin25() + { + + var expected = new[] { 0, 0.9698, 1, 1, 1, 1, 1, 1, 0.9698, 0 }; + var actual = Window.Tukey(10, 0.25); + + Assert.That(actual, Is.EqualTo(expected).Within(0.00005)); + + } + + [Test] + public void TukeyWin75() + { + + var expected = new[] { 0, 0.2014, 0.6434, 0.9698, 1, 1, 0.9698, 0.6434, 0.2014, 0 }; + var actual = Window.Tukey(10, 0.75F); + + Assert.That(actual, Is.EqualTo(expected).Within(0.00005)); + + } + + } +} diff --git a/src/Numerics/Window.cs b/src/Numerics/Window.cs index 66278fb0..f6d5d2a1 100644 --- a/src/Numerics/Window.cs +++ b/src/Numerics/Window.cs @@ -382,5 +382,43 @@ namespace MathNet.Numerics } return w; } + + /// + /// Tukey tapering window. A rectangular window bounded + /// by half a cosine window on each side. + /// + /// Width of the window + /// Fraction of the window occupied by the cosine parts + public static double[] Tukey(int width, double r = 0.5) + { + + if (r <= 0) + { + return Generate.Repeat(width, 1.0); + } + else if (r >= 1) + { + return Hann(width); + } + + var w = new double[width]; + var period = (width - 1) * r; + var step = 2* Math.PI / period; + var b1 = (int)Math.Floor((width - 1) * r * 0.5 + 1); + var b2 = width - b1; + for (var i = 0; i < b1; i++) + { + w[i] = (1 - Math.Cos(i * step)) * 0.5; + } + for (var i = b1; i < b2; i++) + { + w[i] = 1; + } + for (var i = b2; i < width; i++) + { + w[i] = w[width-i-1]; + } + return w; + } } }