All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.opengamma.strata.math.impl.statistics.descriptive.DiscreteQuantileMethod Maven / Gradle / Ivy

/*
 * 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 com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.DoubleArrayMath;
import com.opengamma.strata.collect.array.DoubleArray;

/**
 * Implementation of a quantile estimator.
 * 

* The estimation is one of the sorted sample data. *

* Reference: Value-At-Risk, OpenGamma Documentation 31, Version 0.1, April 2015. */ public abstract class DiscreteQuantileMethod extends QuantileCalculationMethod { @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)); } @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)); } //------------------------------------------------------------------------- /** * Internal method computing the index for a give quantile multiply by sample size. *

* The quantile size is given by quantile * sample size. * * @param quantileSize the quantile size * @return the index in the sample */ abstract int index(double quantileSize); /** * Internal method returning the sample size correction for the specific implementation. * * @param sampleSize the sample size * @return the correction */ abstract int sampleCorrection(int sampleSize); /** * Shift added to/subtracted from index during intermediate steps in the expected shortfall computation. * * @return the index shift */ abstract double indexShift(); /** * Generate an index of doubles. *

* Creates an index of doubles from 0.0 to a stipulated number, in increments of 1. * * @param indexArrayLength length of index array to be created * @return array of indices */ private double[] createIndexArray(int indexArrayLength) { double[] indexArray = new double[indexArrayLength]; for (int i = 0; i < indexArrayLength; i++) { indexArray[i] = i; } return indexArray; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy