com.opengamma.analytics.math.statistics.descriptive.PercentileCalculator.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.math.statistics.descriptive.PercentileCalculator.java

Source

/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.analytics.math.statistics.descriptive;

import java.util.Arrays;

import org.apache.commons.lang.Validate;

import com.opengamma.analytics.math.function.Function1D;

/**
 * For a series of data $x_1, x_2, \dots, x_n$, the percentile is the value $x$
 * below which a certain percentage of the data fall. 
 */
public class PercentileCalculator extends Function1D<double[], Double> {
    private double _percentile;

    /**
     * @param percentile The percentile, must be between 0 and 1
     */
    public PercentileCalculator(final double percentile) {
        Validate.isTrue(percentile > 0 && percentile < 1, "Percentile must be between 0 and 1");
        _percentile = percentile;
    }

    /**
     * @param percentile The percentile, must be between 0 and 1
     */
    public void setPercentile(final double percentile) {
        Validate.isTrue(percentile > 0 && percentile < 1, "Percentile must be between 0 and 1");
        _percentile = percentile;
    }

    /**
     * @param x The data, not null or empty
     * @return The percentile
     */
    @Override
    public Double evaluate(final double[] x) {
        Validate.notNull(x, "x");
        Validate.isTrue(x.length > 0, "x cannot be empty");
        final int length = x.length;
        final double[] copy = Arrays.copyOf(x, length);
        Arrays.sort(copy);
        final double n = _percentile * (length - 1) + 1;
        if (Math.round(n) == 1) {
            return copy[0];
        }
        if (Math.round(n) == length) {
            return copy[length - 1];
        }
        final double d = n % 1;
        final int k = (int) Math.round(n - d);
        return copy[k - 1] + d * (copy[k] - copy[k - 1]);
    }
}