umontreal.iro.lecuyer.probdist.FatigueLifeDist Maven / Gradle / Ivy
Show all versions of ssj Show documentation
/*
* Class: FatigueLifeDist
* Description: fatigue life distribution
* Environment: Java
* Software: SSJ
* Copyright (C) 2001 Pierre L'Ecuyer and Université de Montréal
* Organization: DIRO, Université de Montréal
* @author
* @since
* SSJ is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License (GPL) as published by the
* Free Software Foundation, either version 3 of the License, or
* any later version.
* SSJ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* A copy of the GNU General Public License is available at
GPL licence site.
*/
package umontreal.iro.lecuyer.probdist;
import umontreal.iro.lecuyer.probdist.NormalDist;
import optimization.*;
/**
* Extends the class {@link ContinuousDistribution} for
* the fatigue life distribution with location
* parameter μ, scale parameter β and shape
* parameter γ.
* Its density is
*
*
*
* f (x) = [(((x - μ)/β)1/2 + (β/(x - μ))1/2)/(2γ(x - μ))]φ((((x - μ)/β)1/2 - (β/(x - μ))1/2)/γ), for x > μ,
*
* where φ is the probability density of the standard normal distribution.
* The distribution function is given by
*
*
*
* F(x) = Φ((((x - μ)/β)1/2 - (β/(x - μ))1/2)/γ), for x > μ,
*
* where Φ is the standard normal distribution function.
* Restrictions: β > 0,
* γ > 0.
*
*
* The non-static versions of the methods cdf, barF,
* and inverseF call the static version of the same name.
*
*/
public class FatigueLifeDist extends ContinuousDistribution {
protected double mu;
protected double beta;
protected double gamma;
private static class Optim implements Uncmin_methods
{
private int n;
private double[] xi;
private double mu;
public Optim (double[] x, int n, double min)
{
this.n = n;
this.mu = min;
this.xi = new double[n];
System.arraycopy (x, 0, this.xi, 0, n);
}
public double f_to_minimize (double[] p)
{
double sum = 0.0;
if ((p[1] <= 0.0) || (p[2] <= 0.0))
return 1e200;
for (int i = 0; i < n; i++)
sum -= Math.log (density (mu, p[1], p[2], xi[i]));
return sum;
}
public void gradient (double[] x, double[] g)
{
}
public void hessian (double[] x, double[][] h)
{
}
}
/**
* Constructs a fatigue life distribution with parameters
* μ, β and γ.
*
*/
public FatigueLifeDist (double mu, double beta, double gamma) {
setParams (mu, beta, gamma);
}
public double density (double x) {
return FatigueLifeDist.density (mu, beta, gamma, x);
}
public double cdf (double x) {
return FatigueLifeDist.cdf (mu, beta, gamma, x);
}
public double barF (double x) {
return FatigueLifeDist.barF (mu, beta, gamma, x);
}
public double inverseF (double u) {
return FatigueLifeDist.inverseF (mu, beta, gamma, u);
}
public double getMean() {
return FatigueLifeDist.getMean (mu, beta, gamma);
}
public double getVariance() {
return FatigueLifeDist.getVariance (mu, beta, gamma);
}
public double getStandardDeviation() {
return FatigueLifeDist.getStandardDeviation (mu, beta, gamma);
}
/**
* Computes the density for the
* fatigue life distribution with parameters μ, β and γ.
*
*/
public static double density (double mu, double beta, double gamma,
double x) {
if (beta <= 0.0)
throw new IllegalArgumentException ("beta <= 0");
if (gamma <= 0.0)
throw new IllegalArgumentException ("gamma <= 0");
if (x <= mu)
return 0.0;
double y;
y = (Math.sqrt ((x - mu) / beta) - Math.sqrt (beta / (x - mu))) / gamma;
return (((Math.sqrt ((x - mu) / beta) + Math.sqrt (beta / (x - mu))) /
(2 * gamma * (x - mu))) * NormalDist.density (0.0, 1.0, y));
}
/**
* Computes the fatigue life distribution
* function with parameters μ, β and γ.
*
*/
public static double cdf (double mu, double beta, double gamma, double x) {
if (beta <= 0.0)
throw new IllegalArgumentException ("beta <= 0");
if (gamma <= 0.0)
throw new IllegalArgumentException ("gamma <= 0");
if (x <= mu)
return 0.0;
return NormalDist.cdf01 ((Math.sqrt ((x - mu) / beta) - Math.sqrt (beta / (x - mu))) / gamma);
}
/**
* Computes the complementary distribution function of the
* fatigue life distribution with parameters μ, β and γ.
*
*/
public static double barF (double mu, double beta, double gamma,
double x) {
if (beta <= 0.0)
throw new IllegalArgumentException ("beta <= 0");
if (gamma <= 0.0)
throw new IllegalArgumentException ("gamma <= 0");
if (x <= mu)
return 1.0;
return NormalDist.barF01 ((Math.sqrt ((x - mu) / beta) - Math.sqrt (beta / (x - mu))) / gamma);
}
/**
* Computes the inverse of the fatigue life distribution
* with parameters μ, β and γ.
*
*/
public static double inverseF (double mu, double beta, double gamma,
double u) {
if (beta <= 0.0)
throw new IllegalArgumentException ("beta <= 0");
if (gamma <= 0.0)
throw new IllegalArgumentException ("gamma <= 0");
if (u > 1.0 || u < 0.0)
throw new IllegalArgumentException ("u not in [0,1]");
if (u <= 0.0) // if u == 0, in fact
return mu;
if (u >= 1.0) // if u == 1, in fact
return Double.POSITIVE_INFINITY;
double w = gamma * NormalDist.inverseF01 (u);
double sqrtZ = 0.5 * (w + Math.sqrt (w * w + 4.0));
return (mu + sqrtZ * sqrtZ * beta);
}
/**
* Estimates the parameters (μ, β, γ) of the fatigue life
* distribution using the maximum likelihood method, from the n observations
* x[i],
* i = 0, 1,…, n - 1. The estimates are returned in a three-element
* array, in regular order: [μ, β, γ].
*
* @param x the list of observations to use to evaluate parameters
*
* @param n the number of observations to use to evaluate parameters
*
* @param mu the location parameter
*
* @return returns the parameters [
* hat(β),
* hat(γ)]
*
*/
public static double[] getMLE (double[] x, int n, double mu) {
double sum = 0.0;
if (n <= 0)
throw new IllegalArgumentException ("n <= 0");
double[] parameters = new double[3];
double[] xpls = new double[3];
double[] param = new double[3];
double[] fpls = new double[3];
double[] gpls = new double[3];
int[] itrcmd = new int[2];
double[][] h = new double[3][3];
double[] udiag = new double[3];
Optim system = new Optim (x, n, mu);
double mean = 0.0;
for (int i = 0; i < n; i++)
mean += x[i];
mean /= (double) n;
double var = 0.0;
for (int i = 0; i < n; i++)
var += (x[i] - mean) * (x[i] - mean);
var /= (double) n;
double loc2 = (mean - mu) * (mean - mu);
double a = 0.25 * (var - 5 * loc2);
double b = (var - loc2);
double c = var;
double delta = b * b - 4.0 * a * c;
double gamma2 = (- b - Math.sqrt (delta)) / (2.0 * a);
param[2] = Math.sqrt (gamma2);
param[1] = (mean - mu) / (1.0 + gamma2 / 2.0);
Uncmin_f77.optif0_f77 (2, param, system, xpls, fpls, gpls, itrcmd, h, udiag);
for (int i = 1; i < 3; i++)
parameters[i] = xpls[i];
parameters[0] = mu;
return parameters;
}
/**
* Computes and returns the mean
*
* E[X] = μ + β(1 + γ2/2)
* of the fatigue life distribution with parameters μ, β and γ.
* @return the mean of the fatigue life distribution
*
*/
public static double getMean (double mu, double beta, double gamma) {
if (beta <= 0.0)
throw new IllegalArgumentException ("beta <= 0");
if (gamma <= 0.0)
throw new IllegalArgumentException ("gamma <= 0");
return (mu + beta * (1 + 0.5 * gamma * gamma));
}
/**
* Computes and returns the variance
*
* Var[X] = β2γ2(1 + 5γ2/4) of the fatigue life distribution
* with parameters μ, β and γ.
* @return the variance of the fatigue life distribution
*
*/
public static double getVariance (double mu, double beta, double gamma) {
if (beta <= 0.0)
throw new IllegalArgumentException ("beta <= 0");
if (gamma <= 0.0)
throw new IllegalArgumentException ("gamma <= 0");
return (beta * beta * gamma * gamma * (1.0 + 5.0/4.0 * gamma * gamma));
}
/**
* Computes and returns the standard deviation
* of the fatigue life distribution
* with parameters μ, β and γ.
*
* @return the standard deviation of the fatigue life distribution
*
*/
public static double getStandardDeviation (double mu, double beta,
double gamma) {
return Math.sqrt (FatigueLifeDist.getVariance (mu, beta, gamma));
}
/**
* Returns the parameter β of this object.
*
*/
public double getBeta() {
return beta;
}
/**
* Returns the parameter γ of this object.
*
*/
public double getGamma() {
return gamma;
}
/**
* Returns the parameter μ of this object.
*
*/
public double getMu() {
return mu;
}
/**
* Sets the parameters μ, β and γ of this object.
*
*/
public void setParams (double mu, double beta, double gamma) {
if (beta <= 0.0)
throw new IllegalArgumentException ("beta <= 0");
if (gamma <= 0.0)
throw new IllegalArgumentException ("gamma <= 0");
this.mu = mu;
this.beta = beta;
this.gamma = gamma;
supportA = mu;
}
/**
* Return a table containing the parameters of the current distribution.
* This table is put in regular order: [μ, β, γ].
*
*
*/
public double[] getParams () {
double[] retour = {mu, beta, gamma};
return retour;
}
public String toString () {
return getClass().getSimpleName() + " : mu = " + mu + ", beta = " + beta + ", gamma = " + gamma;
}
}