コード例 #1
0
        private static double EstimateDensity(double x, double y, double[,] data, double[,] hinv)
        {
            double result = 0;

            for (int i = 0; i < data.GetLength(0); i++)
            {
                double[] w = new double[] { x - data[i, 0], y - data[i, 1] };
                double[] b = NumUtil.MatrixTimesVector(hinv, w);
                result += NumUtil.StandardGaussian(b);
            }
            result *= NumUtil.Determinant2x2(hinv) / data.Length;
            return(result);
        }
コード例 #2
0
        private static void Invert(double[,] falseData, double[,] trueData, double falseP, out double[] xRes,
                                   out double[] yRes, out double[,] zRes, out double[,] forwardOut, out double[,] reverseOut,
                                   bool debug)
        {
            double xmin = double.MaxValue;
            double xmax = -double.MaxValue;
            double ymin = double.MaxValue;
            double ymax = -double.MaxValue;

            for (int i = 0; i < falseData.GetLength(0); i++)
            {
                double xx = falseData[i, 0];
                double yy = falseData[i, 1];
                if (xx < xmin)
                {
                    xmin = xx;
                }
                if (xx > xmax)
                {
                    xmax = xx;
                }
                if (yy < ymin)
                {
                    ymin = yy;
                }
                if (yy > ymax)
                {
                    ymax = yy;
                }
            }
            for (int i = 0; i < trueData.GetLength(0); i++)
            {
                double xx = trueData[i, 0];
                double yy = trueData[i, 1];
                if (xx < xmin)
                {
                    xmin = xx;
                }
                if (xx > xmax)
                {
                    xmax = xx;
                }
                if (yy < ymin)
                {
                    ymin = yy;
                }
                if (yy > ymax)
                {
                    ymax = yy;
                }
            }
            double dx = xmax - xmin;

            xmin -= 0.1 * dx;
            xmax += 0.1 * dx;
            double dy = ymax - ymin;

            ymin -= 0.1 * dy;
            ymax += 0.1 * dy;
            double[] falseX;
            double[] falseY;
            double[,] falseZ;
            int n = trueData.GetLength(0);

            double[,] cov = NumUtil.CalcCovariance(trueData);
            double fact = Math.Pow(n, 1.0 / 6.0);

            double[,] hinv = null;
            try {
                hinv = NumUtil.ApplyFunction(cov, delegate(double w) { return(fact / Math.Sqrt(w)); });
            } catch {
            }
            if (hinv == null || !IsValidMatrix(hinv))
            {
                xRes       = null;
                yRes       = null;
                zRes       = null;
                forwardOut = null;
                reverseOut = null;
                return;
            }
            EstimateBivariateDensity(falseData, out falseX, out falseY, out falseZ, xmin, xmax, ymin, ymax, hinv);
            double[] trueX;
            double[] trueY;
            double[,] trueZ;
            EstimateBivariateDensity(trueData, out trueX, out trueY, out trueZ, xmin, xmax, ymin, ymax, hinv);
            double[] x = UnifySupport(falseX, trueX);
            double[] y = UnifySupport(falseY, trueY);
            falseZ            = Interpolate(x, y, falseX, falseY, falseZ);
            trueZ             = Interpolate(x, y, trueX, trueY, trueZ);
            double[,] inverse = new double[x.Length, y.Length];
            for (int i = 0; i < x.Length; i++)
            {
                for (int j = 0; j < y.Length; j++)
                {
                    inverse[i, j] = falseZ[i, j] <= 0 ? double.Epsilon : Math.Max((falseZ[i, j] * 0.5) / trueZ[i, j], double.Epsilon);
                }
            }
            for (int j = 0; j < y.Length; j++)
            {
                double maxVal = double.MinValue;
                int    maxInd = -1;
                for (int i = 0; i < x.Length; i++)
                {
                    if (inverse[i, j] > maxVal)
                    {
                        maxVal = inverse[i, j];
                        maxInd = i;
                    }
                }
                for (int i = 0; i < maxInd; i++)
                {
                    inverse[i, j] = maxVal;
                }
            }
            xRes = x;
            yRes = y;
            zRes = inverse;
            if (debug)
            {
                forwardOut = trueZ;
                reverseOut = falseZ;
            }
            else
            {
                forwardOut = null;
                reverseOut = null;
            }
        }