private static void Invert(double[] falseData, double[] trueData, out double[] xRes, out double[] zRes, out double[] forwardOut, out double[] reverseOut, bool debug) { double xmin = double.MaxValue; double xmax = -double.MaxValue; for (int i = 0; i < falseData.GetLength(0); i++) { double xx = falseData[i]; if (xx < xmin) { xmin = xx; } if (xx > xmax) { xmax = xx; } } for (int i = 0; i < trueData.GetLength(0); i++) { double xx = trueData[i]; if (xx < xmin) { xmin = xx; } if (xx > xmax) { xmax = xx; } } double dx = xmax - xmin; xmin -= 0.1 * dx; xmax += 0.1 * dx; double[] falseX; double[] falseZ; int n = trueData.GetLength(0); double cov = ArrayUtils.CalcCovariance(trueData); double fact = Math.Pow(n, 1.0 / 5.0); double hinv = fact / Math.Sqrt(cov); if (hinv == 0) { xRes = null; zRes = null; forwardOut = null; reverseOut = null; return; } EstimateBivariateDensity(falseData, out falseX, out falseZ, xmin, xmax, hinv); double[] trueX; double[] trueZ; EstimateBivariateDensity(trueData, out trueX, out trueZ, xmin, xmax, hinv); double[] x = UnifySupport(falseX, trueX); falseZ = Interpolate(x, falseX, falseZ); trueZ = Interpolate(x, trueX, trueZ); double[] inverse = new double[x.Length]; for (int i = 0; i < x.Length; i++) { inverse[i] = falseZ[i] <= 0 ? double.Epsilon : Math.Max((falseZ[i] * 0.5) / trueZ[i], double.Epsilon); } double maxVal = double.MinValue; int maxInd = -1; for (int i = 0; i < x.Length; i++) { if (inverse[i] > maxVal) { maxVal = inverse[i]; maxInd = i; } } for (int i = 0; i < maxInd; i++) { inverse[i] = maxVal; } xRes = x; zRes = inverse; if (debug) { forwardOut = trueZ; reverseOut = falseZ; } else { forwardOut = null; reverseOut = null; } }