InterquartileRangeCalculator extends Function1D<double[], Double> { @Override public Double evaluate(final double[] x) { Validate.notNull(x, "x"); final int n = x.length; Validate.isTrue(n > 3, "Need at least four points to calculate IQR"); final double[] copy = Arrays.copyOf(x, n); Arrays.sort(copy); double[] lower, upper; if (n % 2 == 0) { lower = Arrays.copyOfRange(copy, 0, n / 2); upper = Arrays.copyOfRange(copy, n / 2, n); } else { lower = Arrays.copyOfRange(copy, 0, n / 2 + 1); upper = Arrays.copyOfRange(copy, n / 2, n); } return MEDIAN.evaluate(upper) - MEDIAN.evaluate(lower); }  @Override Double evaluate(final double[] x);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNull() { IQR.evaluate((double[]) null); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testInsufficientData() { IQR.evaluate(new double[] {1., 2.}); }
@Test public void test() { final double[] x1 = new double[] {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}; final double[] x2 = new double[] {1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13.}; assertEquals(IQR.evaluate(x1), 5, 1e-15); assertEquals(IQR.evaluate(x2), 6, 1e-15); assertEquals(IQR.evaluate(UNIFORM_DATA), 0.5, EPS); assertEquals(IQR.evaluate(NORMAL_DATA), 2 * NORMAL.getInverseCDF(0.75), EPS); }