/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.math.impl.statistics.descriptive;
import static com.opengamma.strata.collect.TestHelper.assertThrowsIllegalArg;
import static org.testng.Assert.assertEquals;
import java.util.function.Function;
import org.testng.annotations.Test;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.math.impl.integration.RungeKuttaIntegrator1D;
/**
* Test {@link QuantileCalculationMethod} and its implementations.
*/
@Test
public class QuantileCalculationMethodTest {
private static final IndexAboveQuantileMethod QUANTILE_INDEX_ABOVE = IndexAboveQuantileMethod.DEFAULT;
private static final NearestIndexQuantileMethod QUANTILE_NEAREST_INDEX = NearestIndexQuantileMethod.DEFAULT;
private static final SamplePlusOneNearestIndexQuantileMethod QUANTILE_SAMPLE1_NEAREST_INDEX =
SamplePlusOneNearestIndexQuantileMethod.DEFAULT;
private static final SampleInterpolationQuantileMethod QUANTILE_SAMPLE_INTERPOLATION =
SampleInterpolationQuantileMethod.DEFAULT;
private static final SamplePlusOneInterpolationQuantileMethod QUANTILE_SAMPLE1_INTERPOLATION =
SamplePlusOneInterpolationQuantileMethod.DEFAULT;
private static final MidwayInterpolationQuantileMethod QUANTILE_MIDWAY_INTERPOLATION =
MidwayInterpolationQuantileMethod.DEFAULT;
private static final DoubleArray SORTED_100 = DoubleArray.copyOf(new double[] {
0.0286, 0.0363, 0.0379, 0.0582, 0.0611, 0.0622, 0.0776, 0.0779, 0.0849, 0.0916, 0.1055, 0.1358, 0.1474, 0.1544,
0.1674, 0.1740, 0.1746, 0.1841, 0.1963, 0.1982, 0.2020, 0.2222, 0.2401, 0.2582, 0.2666, 0.2979, 0.2998, 0.3000,
0.3028, 0.3057, 0.3508, 0.3734, 0.3781, 0.4011, 0.4197, 0.4463, 0.4481, 0.4863, 0.4878, 0.4908, 0.4942, 0.5029,
0.5212, 0.5224, 0.5290, 0.5780, 0.5803, 0.5807, 0.5921, 0.6174, 0.6243, 0.6278, 0.6325, 0.6343, 0.6416, 0.6423,
0.6460, 0.6504, 0.6570, 0.6666, 0.6748, 0.6763, 0.6804, 0.6859, 0.6862, 0.7136, 0.7145, 0.7289, 0.7291, 0.7360,
0.7444, 0.7532, 0.7543, 0.7602, 0.7714, 0.8024, 0.8053, 0.8075, 0.8190, 0.8190, 0.8216, 0.8234, 0.8399, 0.8483,
0.8511, 0.8557, 0.8631, 0.8814, 0.8870, 0.8963, 0.9150, 0.9157, 0.9198, 0.9275, 0.9524, 0.9570, 0.9620, 0.9716,
0.9731, 0.9813 });
private static final int SAMPLE_SIZE_100 = SORTED_100.size();
private static final DoubleArray SORTED_123 = DoubleArray.copyOf(new double[] {
0.0286, 0.0363, 0.0379, 0.0582, 0.0611, 0.0622, 0.0776, 0.0779, 0.0822, 0.0849, 0.0916, 0.1055, 0.1358, 0.1474,
0.1544, 0.1674, 0.1740, 0.1746, 0.1841, 0.1963, 0.1982, 0.2020, 0.2155, 0.2222, 0.2401, 0.2413, 0.2582, 0.2666,
0.2936, 0.2979, 0.2998, 0.3000, 0.3028, 0.3057, 0.3076, 0.3461, 0.3508, 0.3717, 0.3734, 0.3781, 0.4011, 0.4157,
0.4197, 0.4285, 0.4463, 0.4481, 0.4534, 0.4690, 0.4863, 0.4878, 0.4908, 0.4942, 0.5029, 0.5083, 0.5108, 0.5212,
0.5224, 0.5290, 0.5578, 0.5780, 0.5803, 0.5807, 0.5921, 0.6174, 0.6243, 0.6278, 0.6325, 0.6343, 0.6416, 0.6423,
0.6460, 0.6495, 0.6504, 0.6570, 0.6666, 0.6694, 0.6748, 0.6763, 0.6793, 0.6804, 0.6859, 0.6862, 0.7136, 0.7145,
0.7289, 0.7291, 0.7360, 0.7444, 0.7532, 0.7543, 0.7602, 0.7714, 0.7768, 0.8024, 0.8053, 0.8075, 0.8190, 0.8190,
0.8216, 0.8234, 0.8399, 0.8421, 0.8483, 0.8511, 0.8557, 0.8631, 0.8814, 0.8870, 0.8914, 0.8963, 0.9077, 0.9150,
0.9157, 0.9198, 0.9275, 0.9368, 0.9524, 0.9570, 0.9600, 0.9620, 0.9716, 0.9731, 0.9813 });
private static final int SAMPLE_SIZE_123 = SORTED_123.size();
private static final double TOL = 1.0E-10;
private static final double LEVEL1 = 0.935;
private static final double LEVEL2 = 0.764;
private static final double LEVEL3 = 0.95;
private static final double LEVEL4 = 0.0001;
private static final double LEVEL5 = 0.9999;
//-------------------------------------------------------------------------
public void discrete_wrong_quantile_large() {
assertThrowsIllegalArg(() -> QUANTILE_INDEX_ABOVE.quantileFromSorted(1.01, SORTED_100));
}
public void discrete_wrong_quantile_0() {
assertThrowsIllegalArg(() -> QUANTILE_INDEX_ABOVE.quantileFromSorted(0.0, SORTED_100));
}
public void interpolation_wrong_quantile_1() {
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(1.01, SORTED_100));
}
public void interpolation_wrong_quantile_0() {
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(0.0, SORTED_100));
}
public void interpolation_wrong_quantile_small() {
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL4, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL4, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_MIDWAY_INTERPOLATION.quantileFromSorted(LEVEL4, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL4, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL4, SORTED_100));
}
public void interpolation_wrong_quantile_large() {
assertThrowsIllegalArg(() -> QUANTILE_MIDWAY_INTERPOLATION.quantileFromSorted(LEVEL5, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL5, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL5, SORTED_100));
}
//-------------------------------------------------------------------------
public void discrete_wrong_expectedShortfall_large() {
assertThrowsIllegalArg(() -> QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(1.01, SORTED_100));
}
public void discrete_wrong_expectedShortfall_0() {
assertThrowsIllegalArg(() -> QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(0.0, SORTED_100));
}
public void interpolation_wrong_expectedShortfall_1() {
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE_INTERPOLATION.expectedShortfallFromSorted(1.01, SORTED_100));
}
public void interpolation_wrong_expectedShortfall_0() {
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE_INTERPOLATION.expectedShortfallFromSorted(0.0, SORTED_100));
}
//-------------------------------------------------------------------------
public void index_above_095_100() {
double indexDouble = LEVEL3 * SAMPLE_SIZE_100;
int indexCeil = (int) Math.ceil(indexDouble);
double quantileExpected = SORTED_100.get(indexCeil - 1); // Java index start at 0.
double quantileComputed = QUANTILE_INDEX_ABOVE.quantileFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
double quantileExtrapComputed = QUANTILE_INDEX_ABOVE.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileExtrapComputed, quantileComputed);
}
public void index_above_095_123() {
double indexDouble = LEVEL3 * SAMPLE_SIZE_123;
int indexCeil = (int) Math.ceil(indexDouble);
double quantileExpected = SORTED_123.get(indexCeil - 1); // Java index start at 0.
double quantileComputed = QUANTILE_INDEX_ABOVE.quantileFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileComputed, quantileExpected);
double quantileExtrapComputed = QUANTILE_INDEX_ABOVE.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileExtrapComputed, quantileComputed);
}
/* On sample points, different methods match. */
public void index_nearest_095_100() {
double quantileExpected = QUANTILE_INDEX_ABOVE.quantileFromSorted(LEVEL3, SORTED_100);
double quantileComputed = QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void index_nearest_0951_100() {
double indexDouble = (LEVEL3 + 0.001) * SAMPLE_SIZE_100;
int indexRound = (int) Math.round(indexDouble);
double quantileExpected = SORTED_100.get(indexRound - 1); // Java index start at 0.
double quantileComputed = QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
double quantileExtrapComputed = QUANTILE_NEAREST_INDEX.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileExtrapComputed, quantileComputed);
}
public void index_nearest_0001_100() {
double quantileExpected = SORTED_100.get(0); // Java index start at 0.
double quantileComputed = QUANTILE_NEAREST_INDEX.quantileWithExtrapolationFromSorted(LEVEL4, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void index_nearest_9999_100() {
double quantileExpected = SORTED_100.get(SAMPLE_SIZE_100 - 1); // Java index start at 0.
double quantileComputed = QUANTILE_NEAREST_INDEX.quantileWithExtrapolationFromSorted(LEVEL5, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void index_nearest_one_0951_100() {
double indexDouble = (LEVEL3 + 0.001) * (SAMPLE_SIZE_100 + 1d);
int indexRound = (int) Math.round(indexDouble);
double quantileExpected = SORTED_100.get(indexRound - 1); // Java index start at 0.
double quantileComputed = QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
double quantileExtrapComputed = QUANTILE_SAMPLE1_NEAREST_INDEX.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileExtrapComputed, quantileComputed);
}
public void index_nearest_one_0001_100() {
double quantileExpected = SORTED_100.get(0); // Java index start at 0.
double quantileComputed = QUANTILE_SAMPLE1_NEAREST_INDEX.quantileWithExtrapolationFromSorted(LEVEL4, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void index_nearest_one_9999_100() {
double quantileExpected = SORTED_100.get(SAMPLE_SIZE_100 - 1); // Java index start at 0.
double quantileComputed = QUANTILE_SAMPLE1_NEAREST_INDEX.quantileWithExtrapolationFromSorted(LEVEL5, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
/* On sample points, different methods match. */
@Test
public void interpolation_sample_095_100() {
double quantileExpected = QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL3, SORTED_100);
double quantileComputed = QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL3, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void interpolation_sample_0001_100() {
double quantileExpected = SORTED_100.get(0); // Java index start at 0.
double quantileComputed = QUANTILE_SAMPLE_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL4, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void interpolation_sample_095_123() {
double indexDouble = LEVEL3 * SAMPLE_SIZE_123;
int indexCeil = (int) Math.ceil(indexDouble);
int indexFloor = (int) Math.floor(indexDouble);
double quantileCeil = SORTED_123.get(indexCeil - 1); // Java index start at 0.
double quantileFloor = SORTED_123.get(indexFloor - 1);
double pi = (double) indexFloor / (double) SAMPLE_SIZE_123;
double pi1 = (double) indexCeil / (double) SAMPLE_SIZE_123;
double quantileExpected = quantileFloor + (LEVEL3 - pi) / (pi1 - pi) * (quantileCeil - quantileFloor);
double quantileComputed = QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileComputed, quantileExpected, TOL);
double quantileExtrapComputed = QUANTILE_SAMPLE_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileExtrapComputed, quantileComputed);
}
public void interpolation_samplePlusOne_095_123() {
double indexDouble = LEVEL3 * (SAMPLE_SIZE_123 + 1);
int indexCeil = (int) Math.ceil(indexDouble);
int indexFloor = (int) Math.floor(indexDouble);
double quantileCeil = SORTED_123.get(indexCeil - 1); // Java index start at 0.
double quantileFloor = SORTED_123.get(indexFloor - 1);
double pi = (double) indexFloor / (double) (SAMPLE_SIZE_123 + 1);
double pi1 = (double) indexCeil / (double) (SAMPLE_SIZE_123 + 1);
double quantileExpected = quantileFloor + (LEVEL3 - pi) / (pi1 - pi) * (quantileCeil - quantileFloor);
double quantileComputed = QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileComputed, quantileExpected, TOL);
double quantileExtrapComputed = QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileExtrapComputed, quantileComputed);
}
public void interpolation_samplePlusOne_0001_100() {
double quantileExpected = SORTED_100.get(0); // Java index start at 0.
double quantileComputed = QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL4, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void interpolation_samplePlusOne_9999_100() {
double quantileExpected = SORTED_100.get(SAMPLE_SIZE_100 - 1); // Java index start at 0.
double quantileComputed = QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL5, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void interpolation_midway_095_123() {
double correction = 0.5;
double indexDouble = LEVEL3 * SAMPLE_SIZE_123 + correction;
int indexCeil = (int) Math.ceil(indexDouble);
int indexFloor = (int) Math.floor(indexDouble);
double quantileCeil = SORTED_123.get(indexCeil - 1); // Java index start at 0.
double quantileFloor = SORTED_123.get(indexFloor - 1);
double pi = (indexFloor - correction) / (double) SAMPLE_SIZE_123;
double pi1 = (indexCeil - correction) / (double) SAMPLE_SIZE_123;
double quantileExpected = quantileFloor + (LEVEL3 - pi) / (pi1 - pi) * (quantileCeil - quantileFloor);
double quantileComputed = QUANTILE_MIDWAY_INTERPOLATION.quantileFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileComputed, quantileExpected, TOL);
double quantileExtrapComputed = QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_123);
assertEquals(quantileExtrapComputed, quantileComputed);
}
public void interpolation_midway_0001_100() {
double quantileExpected = SORTED_100.get(0); // Java index start at 0.
double quantileComputed = QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL4, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void interpolation_midway_9999_100() {
double quantileExpected = SORTED_100.get(SAMPLE_SIZE_100 - 1); // Java index start at 0.
double quantileComputed = QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL5, SORTED_100);
assertEquals(quantileComputed, quantileExpected, TOL);
}
public void excel() {
DoubleArray data = DoubleArray.of(1.0, 3.0, 2.0, 4.0);
double level = 0.3;
double quantileComputed = ExcelInterpolationQuantileMethod.DEFAULT.quantileFromUnsorted(level, data);
double quantileExpected = 1.9; // From Excel doc
assertEquals(quantileComputed, quantileExpected, TOL);
double quantileExtrapComputed = ExcelInterpolationQuantileMethod.DEFAULT
.quantileWithExtrapolationFromUnsorted(level, data);
assertEquals(quantileExtrapComputed, quantileComputed);
}
//-------------------------------------------------------------------------
public void index_above_095_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_INDEX_ABOVE.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL3, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
private static final RungeKuttaIntegrator1D INTEG = new RungeKuttaIntegrator1D();
private static final double TOL_INTEGRAL = 1.0e-8;
public void index_above_095_123_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_INDEX_ABOVE.quantileWithExtrapolationFromSorted(level, SORTED_123);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL3, SORTED_123);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void index_above_0001_100_expected_shortfall() {
double expectedShortfallComputed = QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL4, SORTED_100);
assertEquals(expectedShortfallComputed, SORTED_100.get(0), TOL_INTEGRAL);
}
public void index_above_9999_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_INDEX_ABOVE.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL5) / LEVEL5;
double expectedShortfallComputed = QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL5, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void index_nearest_095_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_NEAREST_INDEX.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_NEAREST_INDEX.expectedShortfallFromSorted(LEVEL3, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void index_nearest_095_123_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_NEAREST_INDEX.quantileWithExtrapolationFromSorted(level, SORTED_123);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_NEAREST_INDEX.expectedShortfallFromSorted(LEVEL3, SORTED_123);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void index_nearest_0001_100_expected_shortfall() {
double expectedShortfallComputed =
QUANTILE_NEAREST_INDEX.expectedShortfallFromSorted(LEVEL4, SORTED_100);
assertEquals(expectedShortfallComputed, SORTED_100.get(0), TOL_INTEGRAL);
}
public void index_nearest_9999_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_NEAREST_INDEX.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL5) / LEVEL5;
double expectedShortfallComputed = QUANTILE_NEAREST_INDEX.expectedShortfallFromSorted(LEVEL5, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void index_nearest_one_095_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_SAMPLE1_NEAREST_INDEX.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_SAMPLE1_NEAREST_INDEX.expectedShortfallFromSorted(LEVEL3, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void index_nearest_one_0001_100_expected_shortfall() {
double expectedShortfallExpected = SORTED_100.get(0);
double expectedShortfallComputed =
QUANTILE_SAMPLE1_NEAREST_INDEX.expectedShortfallFromSorted(LEVEL4, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL);
}
public void index_nearest_one_9999_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_SAMPLE1_NEAREST_INDEX.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL5) / LEVEL5;
double expectedShortfallComputed =
QUANTILE_SAMPLE1_NEAREST_INDEX.expectedShortfallFromSorted(LEVEL5, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_sample_095_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_SAMPLE_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_SAMPLE_INTERPOLATION.expectedShortfallFromSorted(LEVEL3, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_sample_095_123_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_SAMPLE_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_123);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_SAMPLE_INTERPOLATION.expectedShortfallFromSorted(LEVEL3, SORTED_123);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_sample_0001_100_expected_shortfall() {
double expectedShortfallExpected = SORTED_100.get(0);
double expectedShortfallComputed =
QUANTILE_SAMPLE_INTERPOLATION.expectedShortfallFromSorted(LEVEL4, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL);
}
public void interpolation_sample_9999_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_SAMPLE_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL5) / LEVEL5;
double expectedShortfallComputed =
QUANTILE_SAMPLE_INTERPOLATION.expectedShortfallFromSorted(LEVEL5, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_samplePlusOne_095_123_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_123);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_SAMPLE1_INTERPOLATION.expectedShortfallFromSorted(LEVEL3, SORTED_123);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_samplePlusOne_0001_100_expected_shortfall() {
double expectedShortfallExpected = SORTED_100.get(0);
double expectedShortfallComputed =
QUANTILE_SAMPLE1_INTERPOLATION.expectedShortfallFromSorted(LEVEL4, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL);
}
public void interpolation_samplePlusOne_9999_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL5) / LEVEL5;
double expectedShortfallComputed =
QUANTILE_SAMPLE1_INTERPOLATION.expectedShortfallFromSorted(LEVEL5, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_midway_095_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_MIDWAY_INTERPOLATION.expectedShortfallFromSorted(LEVEL3, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_midway_095_123_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_123);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL3) / LEVEL3;
double expectedShortfallComputed = QUANTILE_MIDWAY_INTERPOLATION.expectedShortfallFromSorted(LEVEL3, SORTED_123);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void interpolation_midway_0001_100_expected_shortfall() {
double expectedShortfallExpected = SORTED_100.get(0);
double expectedShortfallComputed =
QUANTILE_MIDWAY_INTERPOLATION.expectedShortfallFromSorted(LEVEL4, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL);
}
public void interpolation_midway_9999_100_expected_shortfall() {
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(level, SORTED_100);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL, LEVEL5) / LEVEL5;
double expectedShortfallComputed =
QUANTILE_MIDWAY_INTERPOLATION.expectedShortfallFromSorted(LEVEL5, SORTED_100);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void excel_expected_shortfall() {
DoubleArray data = DoubleArray.of(1.0, 3.0, 2.0, 4.0);
double level = 0.3;
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return ExcelInterpolationQuantileMethod.DEFAULT.quantileWithExtrapolationFromUnsorted(level, data);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL / 1000d, level) / level;
double expectedShortfallComputed =
ExcelInterpolationQuantileMethod.DEFAULT.expectedShortfallFromUnsorted(level, data);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
public void excel_expected_shortfall_0001() {
DoubleArray data = DoubleArray.of(1.0, 3.0, 2.0, 4.0);
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return ExcelInterpolationQuantileMethod.DEFAULT.quantileWithExtrapolationFromUnsorted(level, data);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL / 1000d, LEVEL4) / LEVEL4;
double expectedShortfallComputed =
ExcelInterpolationQuantileMethod.DEFAULT.expectedShortfallFromUnsorted(LEVEL4, data);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL * 10d); // high sensitivity to lower bound
}
public void excel_expected_shortfall_9999() {
DoubleArray data = DoubleArray.of(1.0, 3.0, 2.0, 4.0);
Function<Double, Double> func = new Function<Double, Double>() {
@Override
public Double apply(Double level) {
return ExcelInterpolationQuantileMethod.DEFAULT.quantileWithExtrapolationFromUnsorted(level, data);
}
};
double expectedShortfallExpected = INTEG.integrate(func, TOL_INTEGRAL / 1000d, LEVEL5) / LEVEL5;
double expectedShortfallComputed =
ExcelInterpolationQuantileMethod.DEFAULT.expectedShortfallFromUnsorted(LEVEL5, data);
assertEquals(expectedShortfallComputed, expectedShortfallExpected, TOL_INTEGRAL);
}
//-------------------------------------------------------------------------
public void regression_test1() {
assertEquals(QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL1, SORTED_100), 0.92365, TOL);
assertEquals(QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL1, SORTED_100), 0.9275, TOL);
assertEquals(QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL1, SORTED_100), 0.5114133689839573, TOL);
assertEquals(QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL2, SORTED_100), 0.80356, TOL);
assertEquals(QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL2, SORTED_100), 0.8024, TOL);
assertEquals(QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL2, SORTED_100), 0.4333301047120419, TOL);
assertEquals(QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL3, SORTED_100), 0.9524, TOL);
assertEquals(QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL3, SORTED_100), 0.9524, TOL);
assertEquals(QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL3, SORTED_100), 0.5182452631578948, TOL);
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL4, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL4, SORTED_100));
assertEquals(QUANTILE_SAMPLE_INTERPOLATION.quantileFromSorted(LEVEL5, SORTED_100), 0.981218, TOL);
assertEquals(QUANTILE_NEAREST_INDEX.quantileFromSorted(LEVEL5, SORTED_100), 0.9813, TOL);
assertEquals(QUANTILE_INDEX_ABOVE.expectedShortfallFromSorted(LEVEL5, SORTED_100), 0.5407389438943896, TOL);
}
public void regression_test2() {
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL1, SORTED_100), 0.9383315, TOL);
assertEquals(QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL1, SORTED_100), 0.9275, TOL);
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL2, SORTED_100), 0.8056608, TOL);
assertEquals(QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL2, SORTED_100), 0.8053, TOL);
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL3, SORTED_100), 0.95677, TOL);
assertEquals(QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL3, SORTED_100), 0.957, TOL);
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL4, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL4, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_INTERPOLATION.quantileFromSorted(LEVEL5, SORTED_100));
assertThrowsIllegalArg(() -> QUANTILE_SAMPLE1_NEAREST_INDEX.quantileFromSorted(LEVEL5, SORTED_100));
}
public void regression_test3() {
assertEquals(QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL1, SORTED_100), 0.9275, TOL);
assertEquals(QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL2, SORTED_100), 0.80501, TOL);
assertEquals(QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_100), 0.9547, TOL);
assertEquals(QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL4, SORTED_100), 0.0286, TOL);
assertEquals(QUANTILE_MIDWAY_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL5, SORTED_100), 0.9813, TOL);
}
public void regression_test4() {
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL1, SORTED_100), 0.9383315, TOL);
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL2, SORTED_100), 0.8056608, TOL);
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL3, SORTED_100), 0.95677, TOL);
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL4, SORTED_100), 0.0286, TOL);
assertEquals(QUANTILE_SAMPLE1_INTERPOLATION.quantileWithExtrapolationFromSorted(LEVEL5, SORTED_100), 0.9813, TOL);
}
}