NakagamiDistribution.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.special.Gamma;
  25. import org.hipparchus.util.FastMath;

  26. /**
  27.  * This class implements the Nakagami distribution.
  28.  *
  29.  * @see <a href="http://en.wikipedia.org/wiki/Nakagami_distribution">Nakagami Distribution (Wikipedia)</a>
  30.  */
  31. public class NakagamiDistribution extends AbstractRealDistribution {

  32.     /** Serializable version identifier. */
  33.     private static final long serialVersionUID = 20141003;

  34.     /** The shape parameter. */
  35.     private final double mu;
  36.     /** The scale parameter. */
  37.     private final double omega;

  38.     /**
  39.      * Build a new instance.
  40.      *
  41.      * @param mu shape parameter
  42.      * @param omega scale parameter (must be positive)
  43.      * @throws MathIllegalArgumentException if {@code mu < 0.5}
  44.      * @throws MathIllegalArgumentException if {@code omega <= 0}
  45.      */
  46.     public NakagamiDistribution(double mu, double omega)
  47.         throws MathIllegalArgumentException {
  48.         this(mu, omega, DEFAULT_SOLVER_ABSOLUTE_ACCURACY);
  49.     }

  50.     /**
  51.      * Build a new instance.
  52.      *
  53.      * @param mu shape parameter
  54.      * @param omega scale parameter (must be positive)
  55.      * @param inverseAbsoluteAccuracy the maximum absolute error in inverse
  56.      * cumulative probability estimates (defaults to {@link #DEFAULT_SOLVER_ABSOLUTE_ACCURACY}).
  57.      * @throws MathIllegalArgumentException if {@code mu < 0.5}
  58.      * @throws MathIllegalArgumentException if {@code omega <= 0}
  59.      */
  60.     public NakagamiDistribution(double mu,
  61.                                 double omega,
  62.                                 double inverseAbsoluteAccuracy)
  63.         throws MathIllegalArgumentException {
  64.         super(inverseAbsoluteAccuracy);

  65.         if (mu < 0.5) {
  66.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_SMALL,
  67.                                                    mu, 0.5);
  68.         }
  69.         if (omega <= 0) {
  70.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NOT_POSITIVE_SCALE, omega);
  71.         }

  72.         this.mu = mu;
  73.         this.omega = omega;
  74.     }

  75.     /**
  76.      * Access the shape parameter, {@code mu}.
  77.      *
  78.      * @return the shape parameter.
  79.      */
  80.     public double getShape() {
  81.         return mu;
  82.     }

  83.     /**
  84.      * Access the scale parameter, {@code omega}.
  85.      *
  86.      * @return the scale parameter.
  87.      */
  88.     public double getScale() {
  89.         return omega;
  90.     }

  91.     /** {@inheritDoc} */
  92.     @Override
  93.     public double density(double x) {
  94.         if (x <= 0) {
  95.             return 0.0;
  96.         }
  97.         return 2.0 * FastMath.pow(mu, mu) / (Gamma.gamma(mu) * FastMath.pow(omega, mu)) *
  98.                      FastMath.pow(x, 2 * mu - 1) * FastMath.exp(-mu * x * x / omega);
  99.     }

  100.     /** {@inheritDoc} */
  101.     @Override
  102.     public double cumulativeProbability(double x) {
  103.         return Gamma.regularizedGammaP(mu, mu * x * x / omega);
  104.     }

  105.     /** {@inheritDoc} */
  106.     @Override
  107.     public double getNumericalMean() {
  108.         return Gamma.gamma(mu + 0.5) / Gamma.gamma(mu) * FastMath.sqrt(omega / mu);
  109.     }

  110.     /** {@inheritDoc} */
  111.     @Override
  112.     public double getNumericalVariance() {
  113.         double v = Gamma.gamma(mu + 0.5) / Gamma.gamma(mu);
  114.         return omega * (1 - 1 / mu * v * v);
  115.     }

  116.     /** {@inheritDoc} */
  117.     @Override
  118.     public double getSupportLowerBound() {
  119.         return 0;
  120.     }

  121.     /** {@inheritDoc} */
  122.     @Override
  123.     public double getSupportUpperBound() {
  124.         return Double.POSITIVE_INFINITY;
  125.     }

  126.     /** {@inheritDoc} */
  127.     @Override
  128.     public boolean isSupportConnected() {
  129.         return true;
  130.     }

  131. }