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); }
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; } }