OSDN Git Service

パラメータをとる窓関数への対応(準備)
[karinto/karinto.git] / Karinto / WindowFunction.cs
1 /*\r
2  *      Karinto Library Project\r
3  *\r
4  *      This software is distributed under a zlib-style license.\r
5  *      See license.txt for more information.\r
6  */\r
7 \r
8 using System;\r
9 using System.Collections.Generic;\r
10 using System.Text;\r
11 \r
12 namespace Karinto\r
13 {\r
14     public class WindowFunction\r
15     {\r
16         #region type definitions\r
17 \r
18         public enum FunctionType\r
19         {\r
20             UserDefined = -1,\r
21             Unknown = 0,\r
22             BartlettHann,\r
23             Blackman,\r
24             BlackmanNuttall,\r
25             FlatTop,\r
26             Gaussian,\r
27             Hamming,\r
28             Hann,\r
29             Kaiser,\r
30             Lanczos,\r
31             Nuttall,\r
32             Rectangular,\r
33             Triangular,\r
34         }\r
35         public delegate double Function(double x);\r
36 \r
37         #endregion\r
38 \r
39         #region private or protected fields\r
40 \r
41         private Function function;\r
42         private static Function[] library;\r
43         private double parameter;\r
44 \r
45         #endregion\r
46 \r
47         #region constructors\r
48 \r
49         static WindowFunction()\r
50         {\r
51             library = new Function[]{\r
52                 null/*Unknown*/,\r
53                 BartlettHann,\r
54                 Blackman,\r
55                 BlackmanNuttall,\r
56                 FlatTop,\r
57                 null/*Gaussian*/,\r
58                 Hamming,\r
59                 Hann,\r
60                 null/*Kaiser*/,\r
61                 null/*Lanczos*/,\r
62                 Nuttall,\r
63                 Rectangular,\r
64                 Triangular,\r
65             };\r
66 \r
67         }\r
68 \r
69         public WindowFunction(FunctionType type)\r
70             : this(type, null)\r
71         {\r
72         }\r
73 \r
74         public WindowFunction(FunctionType type, Range range)\r
75         {\r
76             Type = type;\r
77             Range = range;\r
78             switch (type)\r
79             {\r
80                 case FunctionType.Gaussian:\r
81                     function = Gaussian;\r
82                     parameter = 0.4;\r
83                     break;\r
84                 case FunctionType.Kaiser:\r
85                     function = Kaiser;\r
86                     parameter = 2.0;\r
87                     break;\r
88                 case FunctionType.Lanczos:\r
89                     function = Lanczos;\r
90                     parameter = 1.0;\r
91                     break;\r
92                 default:\r
93                     function = library[(int)type];\r
94                     break;\r
95             }\r
96         }\r
97 \r
98         public WindowFunction(FunctionType type, double parameter)\r
99             : this(type, parameter, null)\r
100         {\r
101         }\r
102 \r
103         public WindowFunction(FunctionType type, double parameter, Range range)\r
104         {\r
105             Type = type;\r
106             Range = range;\r
107             this.parameter = parameter;\r
108             switch (type)\r
109             {\r
110                 case FunctionType.Gaussian:\r
111                     function = Gaussian;\r
112                     break;\r
113                 case FunctionType.Kaiser:\r
114                     function = Kaiser;\r
115                     break;\r
116                 case FunctionType.Lanczos:\r
117                     function = Lanczos;\r
118                     break;\r
119                 default:\r
120                     function = library[(int)type];\r
121                     break;\r
122             }\r
123         }\r
124 \r
125         public WindowFunction(Function function)\r
126             : this(function, null)\r
127         {\r
128         }\r
129 \r
130         public WindowFunction(Function function, Range range)\r
131         {\r
132             Range = range;\r
133             Type = FunctionType.UserDefined;\r
134             this.function = function;\r
135         }\r
136 \r
137         #endregion\r
138 \r
139         #region properties\r
140 \r
141         public FunctionType Type\r
142         {\r
143             get;\r
144             private set;\r
145         }\r
146 \r
147         public Range Range\r
148         {\r
149             get;\r
150             set;\r
151         }\r
152 \r
153         #endregion\r
154 \r
155         #region public methods\r
156 \r
157         public double[] ApplyTo(double[] target)\r
158         {\r
159             if (!(Range.First is int)) throw new Exception();\r
160 \r
161             int n = (int)Range.Last - (int)Range.First;\r
162             double[] series = new double[n + (Range.ExcludesEnd ? 0 : 1)];\r
163 \r
164             double scale = 1.0 / n;\r
165             int i = 0;\r
166             foreach (int x in Range)\r
167             {\r
168                 series[i] = target[x] * function(scale * i);\r
169                 i++;\r
170             }\r
171             return series;\r
172         }\r
173         #endregion\r
174 \r
175         #region private methods\r
176 \r
177         private static double BartlettHann(double x)\r
178         {\r
179             throw new NotImplementedException();\r
180         }\r
181 \r
182         private static double Blackman(double x)\r
183         {\r
184             throw new NotImplementedException();\r
185         }\r
186 \r
187         private static double BlackmanNuttall(double x)\r
188         {\r
189             throw new NotImplementedException();\r
190         }\r
191 \r
192         private static double FlatTop(double x)\r
193         {\r
194             const double a0 = 1.0;\r
195             const double a1 = 1.93;\r
196             const double a2 = 1.29;\r
197             const double a3 = 0.388;\r
198             const double a4 = 0.032;\r
199             double theta = 2.0 * Math.PI * x;\r
200             return a0 - a1 * Cos2Pi(x) + a2 * Cos2Pi(x + x) -\r
201                                 a3 * Cos2Pi(3.0 * x) + a4 * Cos2Pi(4.0 * x);\r
202         }\r
203 \r
204         private double Gaussian(double x)\r
205         {\r
206             double r = (x - 0.5) / parameter;\r
207             return Math.Exp(-r * r);\r
208         }\r
209 \r
210         private static double Hamming(double x)\r
211         {\r
212             return 0.54 - 0.46 * Cos2Pi(x);\r
213         }\r
214 \r
215         private static double Hann(double x)\r
216         {\r
217             return 0.5 - 0.5 * Cos2Pi(x);\r
218         }\r
219 \r
220         private double Kaiser(double x)\r
221         {\r
222             throw new NotImplementedException();\r
223         }\r
224 \r
225         private double Lanczos(double x)\r
226         {\r
227             throw new NotImplementedException();\r
228         }\r
229 \r
230         private static double Nuttall(double x)\r
231         {\r
232             throw new NotImplementedException();\r
233         }\r
234 \r
235         private static double Rectangular(double x)\r
236         {\r
237             return 1.0;\r
238         }\r
239 \r
240         private static double Triangular(double x)\r
241         {\r
242             return (x < 0.5) ? x + x : 2.0 - x - x;\r
243         }\r
244 \r
245         private static double Cos2Pi(double x)\r
246         {\r
247             return Math.Cos(2.0 * Math.PI * x);\r
248         }\r
249 \r
250         #endregion\r
251     }\r
252 }\r