View Javadoc

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    *      http://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  package org.apache.commons.math.distribution;
19  
20  import java.io.Serializable;
21  
22  /**
23   * Default implementation of
24   * {@link org.apache.commons.math.distribution.WeibullDistribution}.
25   *
26   * @since 1.1
27   * @version $Revision: 617953 $ $Date: 2008-02-02 22:54:00 -0700 (Sat, 02 Feb 2008) $
28   */
29  public class WeibullDistributionImpl extends AbstractContinuousDistribution
30          implements WeibullDistribution, Serializable {
31      
32      /** Serializable version identifier */
33      private static final long serialVersionUID = 8589540077390120676L;
34      
35      /** The shape parameter. */
36      private double alpha;
37      
38      /** The scale parameter. */
39      private double beta;
40      
41      /**
42       * Creates weibull distribution with the given shape and scale and a
43       * location equal to zero.
44       * @param alpha the shape parameter.
45       * @param beta the scale parameter.
46       */
47      public WeibullDistributionImpl(double alpha, double beta){
48          super();
49          setShape(alpha);
50          setScale(beta);
51      }
52  
53      /**
54       * For this disbution, X, this method returns P(X &lt; <code>x</code>).
55       * @param x the value at which the CDF is evaluated.
56       * @return CDF evaluted at <code>x</code>. 
57       */
58      public double cumulativeProbability(double x) {
59          double ret;
60          if (x <= 0.0) {
61              ret = 0.0;
62          } else {
63              ret = 1.0 - Math.exp(-Math.pow(x / getScale(), getShape()));
64          }
65          return ret;
66      }
67  
68      /**
69       * Access the shape parameter.
70       * @return the shape parameter.
71       */
72      public double getShape() {
73          return alpha;
74      }
75      
76      /**
77       * Access the scale parameter.
78       * @return the scale parameter.
79       */
80      public double getScale() {
81          return beta;
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.</p>
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 = 0.0;
103         } else  if (p == 1) {
104             ret = Double.POSITIVE_INFINITY;
105         } else {
106             ret = getScale() * Math.pow(-Math.log(1.0 - p), 1.0 / getShape());
107         }
108         return ret;
109     }
110     
111     /**
112      * Modify the shape parameter.
113      * @param alpha the new shape parameter value.
114      */
115     public void setShape(double alpha) {
116         if (alpha <= 0.0) {
117             throw new IllegalArgumentException(
118                 "Shape must be positive.");
119         }       
120         this.alpha = alpha;
121     }
122     
123     /**
124      * Modify the scale parameter.
125      * @param beta the new scale parameter value.
126      */
127     public void setScale(double beta) {
128         if (beta <= 0.0) {
129             throw new IllegalArgumentException(
130                 "Scale must be positive.");
131         }       
132         this.beta = beta;
133     }
134 
135     /**
136      * Access the domain value lower bound, based on <code>p</code>, used to
137      * bracket a CDF root.  This method is used by
138      * {@link #inverseCumulativeProbability(double)} to find critical values.
139      * 
140      * @param p the desired probability for the critical value
141      * @return domain value lower bound, i.e.
142      *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code> 
143      */
144     protected double getDomainLowerBound(double p) {
145         return 0.0;
146     }
147 
148     /**
149      * Access the domain value upper bound, based on <code>p</code>, used to
150      * bracket a CDF root.  This method is used by
151      * {@link #inverseCumulativeProbability(double)} to find critical values.
152      * 
153      * @param p the desired probability for the critical value
154      * @return domain value upper bound, i.e.
155      *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code> 
156      */
157     protected double getDomainUpperBound(double p) {
158         return Double.MAX_VALUE;
159     }
160 
161     /**
162      * Access the initial domain value, based on <code>p</code>, used to
163      * bracket a CDF root.  This method is used by
164      * {@link #inverseCumulativeProbability(double)} to find critical values.
165      * 
166      * @param p the desired probability for the critical value
167      * @return initial domain value
168      */
169     protected double getInitialDomain(double p) {
170         // use median
171         return Math.pow(getScale() * Math.log(2.0), 1.0 / getShape());
172     }
173 }