From 2a839bac2889682d147fd3418f2b72bdbebdd86c Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Thu, 12 Dec 2013 21:10:50 +0100 Subject: [PATCH] Windows: port window functions from neodym --- src/NativeProviders/Common/resource.rc | 2 +- src/Numerics/Numerics.csproj | 1 + src/Numerics/Trigonometry.cs | 10 + src/Numerics/Window.cs | 316 +++++++++++++++++++++++++ 4 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 src/Numerics/Window.cs diff --git a/src/NativeProviders/Common/resource.rc b/src/NativeProviders/Common/resource.rc index 5609b91a..6a29d47f 100644 --- a/src/NativeProviders/Common/resource.rc +++ b/src/NativeProviders/Common/resource.rc @@ -69,7 +69,7 @@ BEGIN BEGIN VALUE "Comments", "http://numerics.mathdotnet.com/" VALUE "CompanyName", "Math.NET" - VALUE "FileDescription", "MathNET Numerics Native Wrapper" + VALUE "FileDescription", "MathNET Numerics Native Provider" VALUE "FileVersion", "1.3.0.0" VALUE "InternalName", "Math.NET" VALUE "LegalCopyright", "Copyright (C) Math.NET 2009-2013" diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index ff7e5d47..684c5d2b 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -433,6 +433,7 @@ + diff --git a/src/Numerics/Trigonometry.cs b/src/Numerics/Trigonometry.cs index d509c66d..c05383d1 100644 --- a/src/Numerics/Trigonometry.cs +++ b/src/Numerics/Trigonometry.cs @@ -107,6 +107,16 @@ namespace MathNet.Numerics } + /// + /// Normalized Sinc function. sinc(x) = sin(pi*x)/(pi*x). + /// + public static double Sinc(double x) + { + double z = Math.PI*x; + return z.AlmostEqual(0.0, 15) ? 1.0 : Math.Sin(z)/z; + } + + /// /// Trigonometric Sine of an angle in radian, or opposite / hypotenuse. /// diff --git a/src/Numerics/Window.cs b/src/Numerics/Window.cs new file mode 100644 index 00000000..0793a91c --- /dev/null +++ b/src/Numerics/Window.cs @@ -0,0 +1,316 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace MathNet.Numerics +{ + public static class Window + { + /// + /// Hamming window. Named after Richard Hamming. + /// + public static double[] Hamming(int width) + { + const double a = 0.53836; + const double b = -0.46164; + + double phaseStep = (2.0*Math.PI)/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + b*Math.Cos(i*phaseStep); + } + return w; + } + + /// + /// Hann window. Named after Julius von Hann. + /// + public static double[] Hann(int width) + { + double phaseStep = (2.0*Math.PI)/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = 0.5 - 0.5*Math.Cos(i*phaseStep); + } + return w; + } + + /// + /// Cosine window. + /// + public static double[] Cosine(int width) + { + double phaseStep = Math.PI/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = Math.Sin(i*phaseStep); + } + return w; + } + + /// + /// Lanczos window. + /// + public static double[] Lanczos(int width) + { + double phaseStep = 2.0/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = Trig.Sinc(i*phaseStep - 1.0); + } + return w; + } + + /// + /// Gauss window. + /// + public static double[] Gauss(int width, double sigma) + { + double a = (width - 1)/2.0; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + double exponent = (i - a)/(sigma*a); + w[i] = Math.Exp(-0.5*exponent*exponent); + } + return w; + } + + /// + /// Blackman window. + /// + public static double[] Blackman(int width) + { + const double alpha = 0.16; + const double a = 0.5 - 0.5*alpha; + const double b = 0.5*alpha; + + int last = width - 1; + double c = 2.0*Math.PI/last; + double d = 2.0*c; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + - 0.5*Math.Cos(i*c) + + b*Math.Cos(i*d); + } + return w; + } + + /// + /// Blackman-Harris window. + /// + public static double[] BlackmanHarris(int width) + { + const double a = 0.35875; + const double b = -0.48829; + const double c = 0.14128; + const double d = -0.01168; + + int last = width - 1; + double e = 2.0*Math.PI/last; + double f = 2.0*e; + double g = 3.0*e; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(e*i) + + c*Math.Cos(f*i) + + d*Math.Cos(g*i); + } + return w; + } + + /// + /// Blackman-Nuttall window. + /// + public static double[] BlackmanNuttall(int width) + { + const double a = 0.3635819; + const double b = -0.4891775; + const double c = 0.1365995; + const double d = -0.0106411; + + int last = width - 1; + double e = 2.0*Math.PI/last; + double f = 2.0*e; + double g = 3.0*e; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(e*i) + + c*Math.Cos(f*i) + + d*Math.Cos(g*i); + } + return w; + } + + /// + /// Bartlett window. + /// + public static double[] Bartlett(int width) + { + int last = width - 1; + double a = 2.0/last; + double b = last/2.0; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a*(b - Math.Abs(i - b)); + } + return w; + } + + /// + /// Bartlett-Hann window. + /// + public static double[] BartlettHann(int width) + { + const double a = 0.62; + const double b = -0.48; + const double c = -0.38; + + int last = width - 1; + double d = 1.0/last; + double e = 2.0*Math.PI/last; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Abs(i*d - 0.5) + + c*Math.Cos(i*e); + } + return w; + } + + /// + /// Nuttall window. + /// + public static double[] Nuttall(int width) + { + const double a = 0.355768; + const double b = -0.487396; + const double c = 0.144232; + const double d = -0.012604; + + int last = width - 1; + double e = 2.0*Math.PI/last; + double f = 2.0*e; + double g = 3.0*e; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(e*i) + + c*Math.Cos(f*i) + + d*Math.Cos(g*i); + } + return w; + } + + /// + /// Flat top window. + /// + public static double[] FlatTop(int width) + { + const double a = 1.0; + const double b = -1.93; + const double c = 1.29; + const double d = -0.388; + const double e = 0.032; + + int last = width - 1; + double f = 2.0*Math.PI/last; + double g = 2.0*f; + double h = 3.0*f; + double k = 4.0*f; + + double[] w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(f*i) + + c*Math.Cos(g*i) + + d*Math.Cos(h*i) + + e*Math.Cos(k*i); + } + return w; + } + + /// + /// Uniform rectangular (dirichlet) window. + /// + public static double[] Dirichlet(int width) + { + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = 1.0; + } + return w; + } + + /// + /// Triangular window. + /// + public static double[] Triangular(int width) + { + double a = 2.0/width; + double b = width/2.0; + double c = (width - 1)/2.0; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a*(b - Math.Abs(i - c)); + } + return w; + } + } +}