View Javadoc

    1   /*
    2    * Copyright 2005 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package org.apache.commons.math.distribution;
    18
    19  import java.io.Serializable;
    20
    21  /***
    22   * Default implementation of
    23   * {@link org.apache.commons.math.distribution.CauchyDistribution}.
    24   *
    25   * @since 1.1
    26   * @version $Revision: 348519 $ $Date: 2005-11-23 12:12:18 -0700 (Wed, 23 Nov 2005) $
    27   */
    28  public class CauchyDistributionImpl extends AbstractContinuousDistribution
    29          implements CauchyDistribution, Serializable {
    30
    31      /*** Serializable version identifier */
    32      private static final long serialVersionUID = 8589540077390120676L;
    33
    34      /*** The median of this distribution. */
    35      private double median = 0;
    36
    37      /*** The scale of this distribution. */
    38      private double scale = 1;
    39
    40      /***
    41       * Creates cauchy distribution with the medain equal to zero and scale
    42       * equal to one.
    43       */
    44      public CauchyDistributionImpl(){
    45          this(0.0, 1.0);
    46      }
    47
    48      /***
    49       * Create a cauchy distribution using the given median and scale.
    50       * @param median median for this distribution
    51       * @param s scale parameter for this distribution
    52       */
    53      public CauchyDistributionImpl(double median, double s){
    54          super();
    55          setMedian(median);
    56          setScale(s);
    57      }
    58
    59      /***
    60       * For this disbution, X, this method returns P(X &lt; <code>x</code>).
    61       * @param x the value at which the CDF is evaluated.
    62       * @return CDF evaluted at <code>x</code>.
    63       */
    64      public double cumulativeProbability(double x) {
    65          return 0.5 + (Math.atan((x - median) / scale) / Math.PI);
    66      }
    67
    68      /***
    69       * Access the median.
    70       * @return median for this distribution
    71       */
    72      public double getMedian() {
    73          return median;
    74      }
    75
    76      /***
    77       * Access the scale parameter.
    78       * @return scale parameter for this distribution
    79       */
    80      public double getScale() {
    81          return scale;
    82      }
    83
    84      /***
    85       * For this distribution, X, this method returns the critical point x, such
    86       * that P(X &lt; x) = <code>p</code>.
    87       * <p>
    88       * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
    89       * <code>Double.POSITIVE_INFINITY</code> for p=1.
    90       *
    91       * @param p the desired probability
    92       * @return x, such that P(X &lt; x) = <code>p</code>
    93       * @throws IllegalArgumentException if <code>p</code> is not a valid
    94       *         probability.
    95       */
    96      public double inverseCumulativeProbability(double p) {
    97          double ret;
    98          if (p < 0.0 || p > 1.0) {
    99              throw new IllegalArgumentException
    100                 ("probability argument must be between 0 and 1 (inclusive)");
    101         } else if (p == 0) {
    102             ret = Double.NEGATIVE_INFINITY;
    103         } else  if (p == 1) {
    104             ret = Double.POSITIVE_INFINITY;
    105         } else {
    106             ret = median + scale * Math.tan(Math.PI * (p - .5));
    107         }
    108         return ret;
    109     }
    110
    111     /***
    112      * Modify the median.
    113      * @param median for this distribution
    114      */
    115     public void setMedian(double median) {
    116         this.median = median;
    117     }
    118
    119     /***
    120      * Modify the scale parameter.
    121      * @param s scale parameter for this distribution
    122      * @throws IllegalArgumentException if <code>sd</code> is not positive.
    123      */
    124     public void setScale(double s) {
    125         if (s <= 0.0) {
    126             throw new IllegalArgumentException(
    127                 "Scale must be positive.");
    128         }
    129         scale = s;
    130     }
    131
    132     /***
    133      * Access the domain value lower bound, based on <code>p</code>, used to
    134      * bracket a CDF root.  This method is used by
    135      * {@link #inverseCumulativeProbability(double)} to find critical values.
    136      *
    137      * @param p the desired probability for the critical value
    138      * @return domain value lower bound, i.e.
    139      *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
    140      */
    141     protected double getDomainLowerBound(double p) {
    142         double ret;
    143
    144         if (p < .5) {
    145             ret = -Double.MAX_VALUE;
    146         } else {
    147             ret = getMedian();
    148         }
    149
    150         return ret;
    151     }
    152
    153     /***
    154      * Access the domain value upper bound, based on <code>p</code>, used to
    155      * bracket a CDF root.  This method is used by
    156      * {@link #inverseCumulativeProbability(double)} to find critical values.
    157      *
    158      * @param p the desired probability for the critical value
    159      * @return domain value upper bound, i.e.
    160      *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
    161      */
    162     protected double getDomainUpperBound(double p) {
    163         double ret;
    164
    165         if (p < .5) {
    166             ret = getMedian();
    167         } else {
    168             ret = Double.MAX_VALUE;
    169         }
    170
    171         return ret;
    172     }
    173
    174     /***
    175      * Access the initial domain value, based on <code>p</code>, used to
    176      * bracket a CDF root.  This method is used by
    177      * {@link #inverseCumulativeProbability(double)} to find critical values.
    178      *
    179      * @param p the desired probability for the critical value
    180      * @return initial domain value
    181      */
    182     protected double getInitialDomain(double p) {
    183         double ret;
    184
    185         if (p < .5) {
    186             ret = getMedian() - getScale();
    187         } else if (p > .5) {
    188             ret = getMedian() + getScale();
    189         } else {
    190             ret = getMedian();
    191         }
    192
    193         return ret;
    194     }
    195 }