public static double[] MovingBoxPlot(double[] values, double[] controlValues, int nbins, SignificanceType type) { double[] lowerQuart; double[] median; double[] upperQuart; double[] binBoundaries; return(MovingBoxPlot(values, controlValues, nbins, out lowerQuart, out median, out upperQuart, out binBoundaries, type)); }
public static double[] MovingBoxPlot(double[] values, double[] controlValues, int nbins, out double[] lowerQuart, out double[] median, out double[] upperQuart, out double[] binBoundaries, SignificanceType type) { int n = values.Length; if (n == 0) { lowerQuart = new double[0]; median = new double[0]; upperQuart = new double[0]; binBoundaries = new double[0]; return(new double[0]); } nbins = nbins < 0 ? Math.Max(1, (int)Math.Round(n / (double)minBinsize)) : Math.Min(nbins, 1 + n / 4); int[] pos = new int[nbins + 1]; for (int i = 0; i < nbins + 1; i++) { pos[i] = (int)Math.Round(i / (double)nbins * n); } double[] result = new double[n]; lowerQuart = new double[nbins]; median = new double[nbins]; upperQuart = new double[nbins]; binBoundaries = new double[nbins]; int[] o = ArrayUtil.Order(controlValues); int[][] indices = new int[nbins][]; for (int i = 0; i < nbins; i++) { indices[i] = new int[pos[i + 1] - pos[i]]; Array.Copy(o, pos[i], indices[i], 0, pos[i + 1] - pos[i]); } for (int i = 0; i < nbins; i++) { double[] r = ArrayUtil.SubArray(values, indices[i]); double[] c = ArrayUtil.SubArray(controlValues, indices[i]); int[] o1 = ArrayUtil.Order(r); double rlow = r[o1[(int)Math.Round(0.1587 * (r.Length - 1))]]; double rmed = r[o1[(int)Math.Round(0.5 * (r.Length - 1))]]; double rhigh = r[o1[(int)Math.Round(0.8413 * (r.Length - 1))]]; lowerQuart[i] = rlow; median[i] = rmed; upperQuart[i] = rhigh; binBoundaries[i] = ArrayUtil.Min(c); if (indices[i].Length > 2) { for (int j = 0; j < indices[i].Length; j++) { double ratio = r[j]; switch (type) { case SignificanceType.upper: if (rhigh == rmed) { result[indices[i][j]] = 1; } else { double z = (ratio - rmed) / (rhigh - rmed); result[indices[i][j]] = Errfunc(z); } break; case SignificanceType.lower: if (rlow == rmed) { result[indices[i][j]] = 1; } else { double z = (ratio - rmed) / (rlow - rmed); result[indices[i][j]] = Errfunc(z); } break; default: if (ratio >= rmed) { if (rhigh == rmed) { result[indices[i][j]] = 1; } else { double z = (ratio - rmed) / (rhigh - rmed); result[indices[i][j]] = Errfunc(z); } } else { if (rlow == rmed) { result[indices[i][j]] = 1; } else { double z = (ratio - rmed) / (rlow - rmed); result[indices[i][j]] = Errfunc(z); } } break; } } } else { for (int j = 0; j < indices[i].Length; j++) { result[indices[i][j]] = 1; } } } return(result); }