OSDN Git Service

Merge branch 'master' of git.sourceforge.jp:/gitroot/karinto/karinto
[karinto/karinto.git] / Karinto / WindowFunction.cs
index 9ceed8f..fb05d81 100755 (executable)
@@ -26,9 +26,8 @@ namespace Karinto
             Gaussian,\r
             Hamming,\r
             Hann,\r
+            Kaiser,\r
             Lanczos,\r
-            Lanczos2,\r
-            Lanczos3,\r
             Nuttall,\r
             Rectangular,\r
             Triangular,\r
@@ -39,8 +38,11 @@ namespace Karinto
 \r
         #region private or protected fields\r
 \r
-        private Function function;\r
         private static Function[] library;\r
+        private Function function;\r
+        private double parameter;\r
+        private double powerCorrectionFactor;\r
+        private double amplitudeCorrectionFactor;\r
 \r
         #endregion\r
 \r
@@ -49,22 +51,20 @@ namespace Karinto
         static WindowFunction()\r
         {\r
             library = new Function[]{\r
-                null,\r
+                null/*Unknown*/,\r
                 BartlettHann,\r
                 Blackman,\r
                 BlackmanNuttall,\r
                 FlatTop,\r
-                Gaussian,\r
+                null/*Gaussian*/,\r
                 Hamming,\r
                 Hann,\r
-                Lanczos,\r
-                Lanczos2,\r
-                Lanczos3,\r
+                null/*Kaiser*/,\r
+                null/*Lanczos*/,\r
                 Nuttall,\r
                 Rectangular,\r
                 Triangular,\r
             };\r
-\r
         }\r
 \r
         public WindowFunction(FunctionType type)\r
@@ -73,9 +73,52 @@ namespace Karinto
         }\r
 \r
         public WindowFunction(FunctionType type, Range range)\r
+            : this(type, 0.0, range)\r
+        {\r
+            switch (type)\r
+            {\r
+                case FunctionType.Gaussian:\r
+                    parameter = 0.4;\r
+                    break;\r
+                case FunctionType.Kaiser:\r
+                    parameter = 2.0;\r
+                    break;\r
+                case FunctionType.Lanczos:\r
+                    parameter = 1.0;\r
+                    break;\r
+                default:\r
+                    break;\r
+            }\r
+        }\r
+\r
+        public WindowFunction(FunctionType type, double parameter)\r
+            : this(type, parameter, null)\r
         {\r
+        }\r
+\r
+        public WindowFunction(FunctionType type, double parameter, Range range)\r
+        {\r
+            Type = type;\r
             Range = range;\r
-            function = library[(int)type];\r
+            this.parameter = parameter;\r
+            switch (type)\r
+            {\r
+                case FunctionType.UserDefined:\r
+                    Window = null;\r
+                    break;\r
+                case FunctionType.Gaussian:\r
+                    Window = Gaussian;\r
+                    break;\r
+                case FunctionType.Kaiser:\r
+                    Window = Kaiser;\r
+                    break;\r
+                case FunctionType.Lanczos:\r
+                    Window = Lanczos;\r
+                    break;\r
+                default:\r
+                    Window = library[(int)type];\r
+                    break;\r
+            }\r
         }\r
 \r
         public WindowFunction(Function function)\r
@@ -84,9 +127,9 @@ namespace Karinto
         }\r
 \r
         public WindowFunction(Function function, Range range)\r
+            : this(FunctionType.UserDefined, range)\r
         {\r
-            Range = range;\r
-            this.function = function;\r
+            Window = function;\r
         }\r
 \r
         #endregion\r
@@ -105,6 +148,47 @@ namespace Karinto
             set;\r
         }\r
 \r
+        public Function Window\r
+        {\r
+            get\r
+            {\r
+                return function;\r
+            }\r
+            private set\r
+            {\r
+                function = value;\r
+                if (function != null)\r
+                {\r
+                    powerCorrectionFactor = CalculatePowerCorrectionFactor();\r
+                    amplitudeCorrectionFactor = CalculateAmplitudeCorrectionFactor();\r
+                }\r
+            }\r
+        }\r
+\r
+        public double PowerCorrectionFactor\r
+        {\r
+            get\r
+            {\r
+                if (powerCorrectionFactor > 0.0)\r
+                {\r
+                    return powerCorrectionFactor;\r
+                }\r
+                return CalculatePowerCorrectionFactor();\r
+            }\r
+        }\r
+\r
+        public double AmplitudeCorrectionFactor\r
+        {\r
+            get\r
+            {\r
+                if (amplitudeCorrectionFactor > 0.0)\r
+                {\r
+                    return amplitudeCorrectionFactor;\r
+                }\r
+                return CalculateAmplitudeCorrectionFactor();\r
+            }\r
+        }\r
+\r
         #endregion\r
 \r
         #region public methods\r
@@ -125,10 +209,46 @@ namespace Karinto
             }\r
             return series;\r
         }\r
+\r
         #endregion\r
 \r
         #region private methods\r
 \r
+        private double CalculatePowerCorrectionFactor()\r
+        {\r
+            if (Range == null) return 0.0;\r
+            if (!(Range.First is int)) throw new Exception();\r
+\r
+            int n = (int)Range.Last - (int)Range.First;\r
+            int width = n + (Range.ExcludesEnd ? 0 : 1);\r
+\r
+            double scale = 1.0 / n;\r
+            double pcf = 0.0;\r
+            for (int i = 0; i < width; ++i)\r
+            {\r
+                double f = function(scale * i);\r
+                pcf += f * f;\r
+            }\r
+            return pcf / width;\r
+        }\r
+\r
+        private double CalculateAmplitudeCorrectionFactor()\r
+        {\r
+            if (Range == null) return 0.0;\r
+            if (!(Range.First is int)) throw new Exception();\r
+\r
+            int n = (int)Range.Last - (int)Range.First;\r
+            int width = n + (Range.ExcludesEnd ? 0 : 1);\r
+\r
+            double scale = 1.0 / n;\r
+            double acf = 0.0;\r
+            for (int i = 0; i < width; ++i)\r
+            {\r
+                acf += function(scale * i);\r
+            }\r
+            return acf / width;\r
+        }\r
+\r
         private static double BartlettHann(double x)\r
         {\r
             throw new NotImplementedException();\r
@@ -156,9 +276,10 @@ namespace Karinto
                                 a3 * Cos2Pi(3.0 * x) + a4 * Cos2Pi(4.0 * x);\r
         }\r
 \r
-        private static double Gaussian(double x)\r
+        private double Gaussian(double x)\r
         {\r
-            throw new NotImplementedException();\r
+            double r = (x - 0.5) / parameter;\r
+            return Math.Exp(-r * r);\r
         }\r
 \r
         private static double Hamming(double x)\r
@@ -171,17 +292,12 @@ namespace Karinto
             return 0.5 - 0.5 * Cos2Pi(x);\r
         }\r
 \r
-        private static double Lanczos(double x)\r
-        {\r
-            throw new NotImplementedException();\r
-        }\r
-\r
-        private static double Lanczos2(double x)\r
+        private double Kaiser(double x)\r
         {\r
             throw new NotImplementedException();\r
         }\r
 \r
-        private static double Lanczos3(double x)\r
+        private double Lanczos(double x)\r
         {\r
             throw new NotImplementedException();\r
         }\r