@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case 111972721: // value return ((QuantileResult) bean).getValue(); case 1943391143: // indices return ((QuantileResult) bean).getIndices(); case 1230441723: // weights return ((QuantileResult) bean).getWeights(); } return super.propertyGet(bean, propertyName, quiet); }
@Override public QuantileResult build() { return new QuantileResult( value, indices, weights); }
@Override public double quantileFromUnsorted(double level, DoubleArray sample) { return quantileResultFromUnsorted(level, sample).getValue(); }
@Override public double quantileWithExtrapolationFromUnsorted(double level, DoubleArray sample) { return quantileResultWithExtrapolationFromUnsorted(level, sample).getValue(); }
if ((index == nbData - 1) || (index == nbData)) { ArgChecker.isTrue(isExtrapolated, "Quantile can not be computed above the highest probability level."); return QuantileResult.of(s[nbData - 1], new int[]{(int) Math.round(order[nbData - 1])}, DoubleArray.of(1.0d)); return QuantileResult.of((1 - alpha) * s[index] + alpha * s[index + 1], indices, DoubleArray.ofUnsafe(impacts));
public void es_details() { double[] level = {0.98, 0.981, 0.9811, 0.97}; for (int i = 0; i < level.length; i++) { double es = METHOD.expectedShortfallFromUnsorted(level[i], DATA_123); QuantileResult r = METHOD.expectedShortfallDetailsFromUnsorted(level[i], DATA_123); assertEquals(r.getValue(), es, TOLERANCE_QUANTILE); assertEquals(r.getIndices().length, r.getWeights().size()); double qExpected = 0.0; for (int j = 0; j < r.getIndices().length; j++) { // Recompute ES from details qExpected += DATA_123.get(r.getIndices()[j]) * r.getWeights().get(j); } assertEquals(qExpected, es, TOLERANCE_QUANTILE); } }
@Override public double expectedShortfallFromUnsorted(double level, DoubleArray sample) { return expectedShortfallResultFromUnsorted(level, sample).getValue(); }
@Override protected QuantileResult quantile(double level, DoubleArray sample, boolean isExtrapolated) { ArgChecker.isTrue(level > 0, "Quantile should be above 0."); ArgChecker.isTrue(level < 1, "Quantile should be below 1."); int sampleSize = sampleCorrection(sample.size()); double adjustedLevel = checkIndex(level * sampleSize + indexCorrection(), sample.size(), isExtrapolated); double[] order = createIndexArray(sample.size()); double[] s = sample.toArray(); DoubleArrayMath.sortPairs(s, order); int lowerIndex = (int) Math.floor(adjustedLevel); int upperIndex = (int) Math.ceil(adjustedLevel); double lowerWeight = upperIndex - adjustedLevel; double upperWeight = 1d - lowerWeight; return QuantileResult.of( lowerWeight * s[lowerIndex - 1] + upperWeight * s[upperIndex - 1], new int[]{(int) order[lowerIndex - 1], (int) order[upperIndex - 1]}, DoubleArray.of(lowerWeight, upperWeight)); }
/** * Creates an {@code QuantileResult} from the value, the indices and the weights. * <p> * The amounts must be of the correct type, one pay and one receive. * The currencies of the payments must differ. * * @param value the quantile value * @param indices the indices of the samples used in the quantile computation * @param weights the weights of the samples used in the quantile computation * @return the quantile result */ public static QuantileResult of(double value, int[] indices, DoubleArray weights) { return new QuantileResult(value, indices, weights); }
public void quantile_details() { double[] level = {0.98, 0.981, 0.9811, 0.97}; for (int i = 0; i < level.length; i++) { double q = METHOD.quantileFromUnsorted(level[i], DATA_123); QuantileResult r = METHOD.quantileDetailsFromUnsorted(level[i], DATA_123); assertEquals(r.getValue(), q, TOLERANCE_QUANTILE); assertEquals(r.getIndices().length, r.getWeights().size()); double qExpected = 0.0; for (int j = 0; j < r.getIndices().length; j++) { // Recompute quantile from details qExpected += DATA_123.get(r.getIndices()[j]) * r.getWeights().get(j); } assertEquals(qExpected, q, TOLERANCE_QUANTILE); } }
/** * Compute the quantile estimation. * <p> * The quantile level is in decimal, i.e. 99% = 0.99 and 0 < level < 1 should be satisfied. * This is measured from the bottom, that is, Thus the quantile estimation with the level 99% corresponds to * the smallest 99% observations. * <p> * If index value computed from the level is outside of the sample data range, the nearest data point is used, i.e., * quantile is computed with flat extrapolation. * <p> * The sample observations are sorted from the smallest to the largest. * * @param level the quantile level * @param sortedSample the sample observations * @return the quantile estimation */ public double quantileWithExtrapolationFromSorted(double level, DoubleArray sortedSample) { return quantileResultWithExtrapolationFromUnsorted(level, sortedSample).getValue(); }
@Override protected QuantileResult quantile(double level, DoubleArray sample, boolean isExtrapolated) { ArgChecker.isTrue(level > 0, "Quantile should be above 0."); ArgChecker.isTrue(level < 1, "Quantile should be below 1."); int sampleSize = sampleCorrection(sample.size()); double[] order = createIndexArray(sample.size()); double[] s = sample.toArray(); DoubleArrayMath.sortPairs(s, order); int index = (int) checkIndex(index(level * sampleSize), sample.size(), isExtrapolated); int[] ind = new int[1]; ind[0] = (int) order[index - 1]; return QuantileResult.of(s[index - 1], ind, DoubleArray.of(1)); }
double expectedValueAbove = 0d; double sumWeightsAbove = 0d; for (int i = 0; i < esAbove.getIndices().length; i++) { expectedValueAbove += UNSORTED_100.get(esAbove.getIndices()[i]) * esAbove.getWeights().get(i); sumWeightsAbove += esAbove.getWeights().get(i); assertEquals(esAbove.getIndices().length, esAbove.getWeights().size()); assertEquals(sumWeightsAbove, 1d, TOL); assertEquals(esAbove.getValue(), expectedValueAbove, TOL); for (int i = 0; i < esNearest.getIndices().length; i++) { expectedValueNearest += UNSORTED_100.get(esNearest.getIndices()[i]) * esNearest.getWeights().get(i); sumWeightsNearest += esNearest.getWeights().get(i); assertEquals(esNearest.getIndices().length, esNearest.getWeights().size()); assertEquals(sumWeightsNearest, 1d, TOL); assertEquals(esNearest.getValue(), expectedValueNearest, TOL); for (int i = 0; i < esSample.getIndices().length; i++) { expectedValueSample += UNSORTED_100.get(esSample.getIndices()[i]) * esSample.getWeights().get(i); sumWeightsSample += esSample.getWeights().get(i); assertEquals(esSample.getIndices().length, esSample.getWeights().size()); assertEquals(sumWeightsSample, 1d, TOL); assertEquals(esSample.getValue(), expectedValueSample, TOL); for (int i = 0; i < esSampleInterp.getIndices().length; i++) { expectedValueSampleInterp += UNSORTED_100.get(esSampleInterp.getIndices()[i]) * esSampleInterp.getWeights().get(i); sumWeightsSampleInterp += esSampleInterp.getWeights().get(i);
/** * Compute the quantile estimation. * <p> * The quantile level is in decimal, i.e. 99% = 0.99 and 0 < level < 1 should be satisfied. * This is measured from the bottom, that is, Thus the quantile estimation with the level 99% corresponds to * the smallest 99% observations. * <p> * If index value computed from the level is outside of the sample data range, * {@code IllegalArgumentException} is thrown. * <p> * The sample observations are sorted from the smallest to the largest. * * @param level the quantile level * @param sortedSample the sample observations * @return the quantile estimation */ public double quantileFromSorted(double level, DoubleArray sortedSample) { return quantileResultFromUnsorted(level, sortedSample).getValue(); }
weights[sample.size() - 1] += (fractionalIndex - sample.size()) * interval; return QuantileResult.of(losses / level, indices, DoubleArray.ofUnsafe(weights).dividedBy(level));
double expectedValueAbove = 0d; double sumWeightsAbove = 0d; for (int i = 0; i < quantileAbove.getIndices().length; i++) { expectedValueAbove += UNSORTED_100.get(quantileAbove.getIndices()[i]) * quantileAbove.getWeights().get(i); sumWeightsAbove += quantileAbove.getWeights().get(i); assertEquals(quantileAbove.getIndices().length, quantileAbove.getWeights().size()); assertEquals(sumWeightsAbove, 1d, TOL); assertEquals(quantileAbove.getValue(), expectedValueAbove, TOL); for (int i = 0; i < quantileNearest.getIndices().length; i++) { expectedValueNearest += UNSORTED_100.get(quantileNearest.getIndices()[i]) * quantileNearest.getWeights().get(i); sumWeightsNearest += quantileNearest.getWeights().get(i); assertEquals(quantileNearest.getIndices().length, quantileNearest.getWeights().size()); assertEquals(sumWeightsNearest, 1d, TOL); assertEquals(quantileNearest.getValue(), expectedValueNearest, TOL); for (int i = 0; i < quantileSample.getIndices().length; i++) { expectedValueSample += UNSORTED_100.get(quantileSample.getIndices()[i]) * quantileSample.getWeights().get(i); sumWeightsSample += quantileSample.getWeights().get(i); assertEquals(quantileSample.getIndices().length, quantileSample.getWeights().size()); assertEquals(sumWeightsSample, 1d, TOL); assertEquals(quantileSample.getValue(), expectedValueSample, TOL); for (int i = 0; i < quantileSampleInterp.getIndices().length; i++) { expectedValueSampleInterp += UNSORTED_100.get(quantileSampleInterp.getIndices()[i]) * quantileSampleInterp.getWeights().get( i);
/** * Compute the expected shortfall. * <p> * The quantile level is in decimal, i.e. 99% = 0.99 and 0 < level < 1 should be satisfied. * This is measured from the bottom, that is, Thus the expected shortfall with the level 99% corresponds to * the smallest 99% observations. * <p> * If index value computed from the level is outside of the sample data range, the nearest data point is used, i.e., * expected short fall is computed with flat extrapolation. * Thus this is coherent to {@link #quantileWithExtrapolationFromSorted(double, DoubleArray)}. * <p> * The sample observations are sorted from the smallest to the largest. * * @param level the quantile level * @param sortedSample the sample observations * @return the quantile estimation */ public double expectedShortfallFromSorted(double level, DoubleArray sortedSample) { return expectedShortfallResultFromUnsorted(level, sortedSample).getValue(); }
@Override protected QuantileResult expectedShortfall(double level, DoubleArray sample) { ArgChecker.isTrue(level > 0, "Quantile should be above 0."); ArgChecker.isTrue(level < 1, "Quantile should be below 1."); int sampleSize = sampleCorrection(sample.size()); double[] order = createIndexArray(sample.size()); double[] s = sample.toArray(); DoubleArrayMath.sortPairs(s, order); double fractionalIndex = level * sampleSize; int index = (int) checkIndex(index(fractionalIndex), sample.size(), true); int[] indices = new int[index]; double[] weights = new double[index]; double interval = 1d / (double) sampleSize; double losses = s[0] * interval * indexShift(); for (int i = 0; i < index - 1; i++) { losses += s[i] * interval; indices[i] = (int) order[i]; weights[i] = interval; } losses += s[index - 1] * (fractionalIndex - index + 1 - indexShift()) * interval; indices[index - 1] = (int) order[index - 1]; weights[0] += interval * indexShift(); weights[index - 1] = (fractionalIndex - index + 1 - indexShift()) * interval; return QuantileResult.of(losses / level, indices, DoubleArray.ofUnsafe(weights).dividedBy(level)); }