ParetoDistribution.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */

  21. package org.hipparchus.distribution.continuous;

  22. import org.hipparchus.exception.LocalizedCoreFormats;
  23. import org.hipparchus.exception.MathIllegalArgumentException;
  24. import org.hipparchus.util.FastMath;

  25. /**
  26.  * Implementation of the Pareto distribution.
  27.  * <p>
  28.  * <strong>Parameters:</strong>
  29.  * The probability distribution function of {@code X} is given by (for {@code x >= k}):
  30.  * </p>
  31.  * <pre>
  32.  *  α * k^α / x^(α + 1)
  33.  * </pre>
  34.  * <ul>
  35.  * <li>{@code k} is the <em>scale</em> parameter: this is the minimum possible value of {@code X},</li>
  36.  * <li>{@code α} is the <em>shape</em> parameter: this is the Pareto index</li>
  37.  * </ul>
  38.  *
  39.  * @see <a href="http://en.wikipedia.org/wiki/Pareto_distribution">
  40.  * Pareto distribution (Wikipedia)</a>
  41.  * @see <a href="http://mathworld.wolfram.com/ParetoDistribution.html">
  42.  * Pareto distribution (MathWorld)</a>
  43.  */
  44. public class ParetoDistribution extends AbstractRealDistribution {

  45.     /** Serializable version identifier. */
  46.     private static final long serialVersionUID = 20130424L;

  47.     /** The scale parameter of this distribution. */
  48.     private final double scale;
  49.     /** The shape parameter of this distribution. */
  50.     private final double shape;

  51.     /**
  52.      * Create a Pareto distribution with a scale of {@code 1} and a shape of {@code 1}.
  53.      */
  54.     public ParetoDistribution() {
  55.         this(1, 1);
  56.     }

  57.     /**
  58.      * Create a Pareto distribution using the specified scale and shape.
  59.      *
  60.      * @param scale the scale parameter of this distribution
  61.      * @param shape the shape parameter of this distribution
  62.      * @throws MathIllegalArgumentException if {@code scale <= 0} or {@code shape <= 0}.
  63.      */
  64.     public ParetoDistribution(double scale, double shape)
  65.         throws MathIllegalArgumentException {
  66.         this(scale, shape, DEFAULT_SOLVER_ABSOLUTE_ACCURACY);
  67.     }

  68.     /**
  69.      * Creates a Pareto distribution.
  70.      *
  71.      * @param scale Scale parameter of this distribution.
  72.      * @param shape Shape parameter of this distribution.
  73.      * @param inverseCumAccuracy Inverse cumulative probability accuracy.
  74.      * @throws MathIllegalArgumentException if {@code scale <= 0} or {@code shape <= 0}.
  75.      */
  76.     public ParetoDistribution(double scale,
  77.                               double shape,
  78.                               double inverseCumAccuracy)
  79.         throws MathIllegalArgumentException {
  80.         super(inverseCumAccuracy);

  81.         if (scale <= 0) {
  82.             throw new MathIllegalArgumentException(LocalizedCoreFormats.SCALE, scale);
  83.         }

  84.         if (shape <= 0) {
  85.             throw new MathIllegalArgumentException(LocalizedCoreFormats.SHAPE, shape);
  86.         }

  87.         this.scale = scale;
  88.         this.shape = shape;
  89.     }

  90.     /**
  91.      * Returns the scale parameter of this distribution.
  92.      *
  93.      * @return the scale parameter
  94.      */
  95.     public double getScale() {
  96.         return scale;
  97.     }

  98.     /**
  99.      * Returns the shape parameter of this distribution.
  100.      *
  101.      * @return the shape parameter
  102.      */
  103.     public double getShape() {
  104.         return shape;
  105.     }

  106.     /**
  107.      * {@inheritDoc}
  108.      * <p>
  109.      * For scale {@code k}, and shape {@code α} of this distribution, the PDF
  110.      * is given by
  111.      * <ul>
  112.      * <li>{@code 0} if {@code x < k},</li>
  113.      * <li>{@code α * k^α / x^(α + 1)} otherwise.</li>
  114.      * </ul>
  115.      */
  116.     @Override
  117.     public double density(double x) {
  118.         if (x < scale) {
  119.             return 0;
  120.         }
  121.         return FastMath.pow(scale, shape) / FastMath.pow(x, shape + 1) * shape;
  122.     }

  123.     /** {@inheritDoc}
  124.      *
  125.      * See documentation of {@link #density(double)} for computation details.
  126.      */
  127.     @Override
  128.     public double logDensity(double x) {
  129.         if (x < scale) {
  130.             return Double.NEGATIVE_INFINITY;
  131.         }
  132.         return FastMath.log(scale) * shape - FastMath.log(x) * (shape + 1) + FastMath.log(shape);
  133.     }

  134.     /**
  135.      * {@inheritDoc}
  136.      * <p>
  137.      * For scale {@code k}, and shape {@code α} of this distribution, the CDF is given by
  138.      * <ul>
  139.      * <li>{@code 0} if {@code x < k},</li>
  140.      * <li>{@code 1 - (k / x)^α} otherwise.</li>
  141.      * </ul>
  142.      */
  143.     @Override
  144.     public double cumulativeProbability(double x)  {
  145.         if (x <= scale) {
  146.             return 0;
  147.         }
  148.         return 1 - FastMath.pow(scale / x, shape);
  149.     }

  150.     /**
  151.      * {@inheritDoc}
  152.      * <p>
  153.      * For scale {@code k} and shape {@code α}, the mean is given by
  154.      * <ul>
  155.      * <li>{@code ∞} if {@code α <= 1},</li>
  156.      * <li>{@code α * k / (α - 1)} otherwise.</li>
  157.      * </ul>
  158.      */
  159.     @Override
  160.     public double getNumericalMean() {
  161.         if (shape <= 1) {
  162.             return Double.POSITIVE_INFINITY;
  163.         }
  164.         return shape * scale / (shape - 1);
  165.     }

  166.     /**
  167.      * {@inheritDoc}
  168.      * <p>
  169.      * For scale {@code k} and shape {@code α}, the variance is given by
  170.      * <ul>
  171.      * <li>{@code ∞} if {@code 1 < α <= 2},</li>
  172.      * <li>{@code k^2 * α / ((α - 1)^2 * (α - 2))} otherwise.</li>
  173.      * </ul>
  174.      */
  175.     @Override
  176.     public double getNumericalVariance() {
  177.         if (shape <= 2) {
  178.             return Double.POSITIVE_INFINITY;
  179.         }
  180.         double s = shape - 1;
  181.         return scale * scale * shape / (s * s) / (shape - 2);
  182.     }

  183.     /**
  184.      * {@inheritDoc}
  185.      * <p>
  186.      * The lower bound of the support is equal to the scale parameter {@code k}.
  187.      *
  188.      * @return lower bound of the support
  189.      */
  190.     @Override
  191.     public double getSupportLowerBound() {
  192.         return scale;
  193.     }

  194.     /**
  195.      * {@inheritDoc}
  196.      * <p>
  197.      * The upper bound of the support is always positive infinity no matter the parameters.
  198.      *
  199.      * @return upper bound of the support (always {@code Double.POSITIVE_INFINITY})
  200.      */
  201.     @Override
  202.     public double getSupportUpperBound() {
  203.         return Double.POSITIVE_INFINITY;
  204.     }

  205.     /**
  206.      * {@inheritDoc}
  207.      * <p>
  208.      * The support of this distribution is connected.
  209.      *
  210.      * @return {@code true}
  211.      */
  212.     @Override
  213.     public boolean isSupportConnected() {
  214.         return true;
  215.     }
  216. }