/*
Copyright (C) 2008 Richard Gomes
This source code is release under the BSD License.
This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/
JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license. You should have received a
copy of the license along with this program; if not, please email
. The license is also available online at
.
This program 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 license for more details.
JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
*/
package org.jquantlib.math.distributions;
import org.jquantlib.math.Ops;
/**
*
* @author Dominik Holenstein
*
*/
// TODO Add test case for MoroInverseCumulativeNormal class.
public class MoroInverseCumulativeNormal extends NormalDistribution implements Ops.DoubleOp {
//
// static final fields (constants)
//
static final double a0_ = 2.50662823884;
static final double a1_ = -18.61500062529;
static final double a2_ = 41.39119773534;
static final double a3_ = -25.44106049637;
static final double b0_ = -8.47351093090;
static final double b1_ = 23.08336743743;
static final double b2_ = -21.06224101826;
static final double b3_ = 3.13082909833;
static final double c0_ = 0.3374754822726147;
static final double c1_ = 0.9761690190917186;
static final double c2_ = 0.1607979714918209;
static final double c3_ = 0.0276438810333863;
static final double c4_ = 0.0038405729373609;
static final double c5_ = 0.0003951896511919;
static final double c6_ = 0.0000321767881768;
static final double c7_ = 0.0000002888167364;
static final double c8_ = 0.0000003960315187;
//
// public constructors
//
public MoroInverseCumulativeNormal() {
super();
}
public MoroInverseCumulativeNormal(double average, double sigma) {
super(average, sigma);
}
//
// implements Ops.DoubleOp
//
@Override
public double op(final double x) /* Read-only */ {
final double temp=x-0.5;
// x has to be between 0.00 and 1.00
if (x <= 0.0) return 0.00;
if (x >=1.0) return 1.00;
double result;
if (Math.abs(temp) < 0.42) {
// Beasley and Springer, 1977
result=temp*temp;
result=temp*
(((a3_*result+a2_)*result+a1_)*result+a0_) /
((((b3_*result+b2_)*result+b1_)*result+b0_)*result+1.0);
} else {
// improved approximation for the tail (Moro 1995)
if (x<0.5)
result = x;
else
result=1.0-x;
result = Math.log(-Math.log(result));
result = c0_+result*(c1_+result*(c2_+result*(c3_+result*
(c4_+result*(c5_+result*(c6_+result*
(c7_+result*c8_)))))));
if (x<0.5)
result=-result;
}
return average + result * sigma;
}
}
Ads help maintain this website.