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