2 * Karinto Library Project
\r
4 * This software is distributed under a zlib-style license.
\r
5 * See license.txt for more information.
\r
9 using System.Collections.Generic;
\r
14 public class WindowFunction
\r
16 #region type definitions
\r
18 public enum FunctionType
\r
35 public delegate double Function(double x);
\r
39 #region private or protected fields
\r
41 private static Function[] library;
\r
42 private Function function;
\r
43 private double parameter;
\r
44 private double powerCorrectionFactor;
\r
45 private double amplitudeCorrectionFactor;
\r
49 #region constructors
\r
51 static WindowFunction()
\r
53 library = new Function[]{
\r
70 public WindowFunction(FunctionType type)
\r
75 public WindowFunction(FunctionType type, Range range)
\r
76 : this(type, 0.0, range)
\r
80 case FunctionType.Gaussian:
\r
83 case FunctionType.Kaiser:
\r
86 case FunctionType.Lanczos:
\r
94 public WindowFunction(FunctionType type, double parameter)
\r
95 : this(type, parameter, null)
\r
99 public WindowFunction(FunctionType type, double parameter, Range range)
\r
103 this.parameter = parameter;
\r
106 case FunctionType.UserDefined:
\r
109 case FunctionType.Gaussian:
\r
112 case FunctionType.Kaiser:
\r
115 case FunctionType.Lanczos:
\r
119 Window = library[(int)type];
\r
124 public WindowFunction(Function function)
\r
125 : this(function, null)
\r
129 public WindowFunction(Function function, Range range)
\r
130 : this(FunctionType.UserDefined, range)
\r
139 public FunctionType Type
\r
151 public Function Window
\r
160 if (function != null)
\r
162 powerCorrectionFactor = CalculatePowerCorrectionFactor();
\r
163 amplitudeCorrectionFactor = CalculateAmplitudeCorrectionFactor();
\r
168 public double PowerCorrectionFactor
\r
172 if (powerCorrectionFactor > 0.0)
\r
174 return powerCorrectionFactor;
\r
176 return CalculatePowerCorrectionFactor();
\r
180 public double AmplitudeCorrectionFactor
\r
184 if (amplitudeCorrectionFactor > 0.0)
\r
186 return amplitudeCorrectionFactor;
\r
188 return CalculateAmplitudeCorrectionFactor();
\r
194 #region public methods
\r
196 public double[] ApplyTo(double[] target)
\r
198 if (!(Range.First is int)) throw new Exception();
\r
200 int n = (int)Range.Last - (int)Range.First;
\r
201 double[] series = new double[n + (Range.ExcludesEnd ? 0 : 1)];
\r
203 double scale = 1.0 / n;
\r
205 foreach (int x in Range)
\r
207 series[i] = target[x] * function(scale * i);
\r
215 #region private methods
\r
217 private double CalculatePowerCorrectionFactor()
\r
219 if (Range == null) return 0.0;
\r
220 if (!(Range.First is int)) throw new Exception();
\r
222 int n = (int)Range.Last - (int)Range.First;
\r
223 int width = n + (Range.ExcludesEnd ? 0 : 1);
\r
225 double scale = 1.0 / n;
\r
227 for (int i = 0; i < width; ++i)
\r
229 double f = function(scale * i);
\r
232 return pcf / width;
\r
235 private double CalculateAmplitudeCorrectionFactor()
\r
237 if (Range == null) return 0.0;
\r
238 if (!(Range.First is int)) throw new Exception();
\r
240 int n = (int)Range.Last - (int)Range.First;
\r
241 int width = n + (Range.ExcludesEnd ? 0 : 1);
\r
243 double scale = 1.0 / n;
\r
245 for (int i = 0; i < width; ++i)
\r
247 acf += function(scale * i);
\r
249 return acf / width;
\r
252 private static double BartlettHann(double x)
\r
254 throw new NotImplementedException();
\r
257 private static double Blackman(double x)
\r
259 throw new NotImplementedException();
\r
262 private static double BlackmanNuttall(double x)
\r
264 throw new NotImplementedException();
\r
267 private static double FlatTop(double x)
\r
269 const double a0 = 1.0;
\r
270 const double a1 = 1.93;
\r
271 const double a2 = 1.29;
\r
272 const double a3 = 0.388;
\r
273 const double a4 = 0.032;
\r
274 double theta = 2.0 * Math.PI * x;
\r
275 return a0 - a1 * Cos2Pi(x) + a2 * Cos2Pi(x + x) -
\r
276 a3 * Cos2Pi(3.0 * x) + a4 * Cos2Pi(4.0 * x);
\r
279 private double Gaussian(double x)
\r
281 double r = (x - 0.5) / parameter;
\r
282 return Math.Exp(-r * r);
\r
285 private static double Hamming(double x)
\r
287 return 0.54 - 0.46 * Cos2Pi(x);
\r
290 private static double Hann(double x)
\r
292 return 0.5 - 0.5 * Cos2Pi(x);
\r
295 private double Kaiser(double x)
\r
297 throw new NotImplementedException();
\r
300 private double Lanczos(double x)
\r
302 throw new NotImplementedException();
\r
305 private static double Nuttall(double x)
\r
307 throw new NotImplementedException();
\r
310 private static double Rectangular(double x)
\r
315 private static double Triangular(double x)
\r
317 return (x < 0.5) ? x + x : 2.0 - x - x;
\r
320 private static double Cos2Pi(double x)
\r
322 return Math.Cos(2.0 * Math.PI * x);
\r