/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.statistics.distribution.fnlib;
/**
* DERF(X) provides the ability to calculate the error function at position 'x'.
* It does this using Chebychev approximation mixed with calls to erfc() provided by {@link DERF}.
* This code is an approximate translation of the equivalent function in the "Public Domain" code from SLATEC, see:
* See http://www.netlib.org/slatec/fnlib/derf.f
*/
public class DERF {
static final double[] ERFCS = {//CSOFF
-0.49046121234691808039984544033376e-1,
-0.14226120510371364237824741899631e+0,
+0.10035582187599795575754676712933e-1,
-0.57687646997674847650827025509167e-3,
+0.27419931252196061034422160791471e-4,
-0.11043175507344507604135381295905e-5,
+0.38488755420345036949961311498174e-7,
-0.11808582533875466969631751801581e-8,
+0.32334215826050909646402930953354e-10,
-0.79910159470045487581607374708595e-12,
+0.17990725113961455611967245486634e-13,
-0.37186354878186926382316828209493e-15,
+0.71035990037142529711689908394666e-17,
-0.12612455119155225832495424853333e-18,
+0.20916406941769294369170500266666e-20,
-0.32539731029314072982364160000000e-22,
+0.47668672097976748332373333333333e-24,
-0.65980120782851343155199999999999e-26,
+0.86550114699637626197333333333333e-28,
-0.10788925177498064213333333333333e-29,
+0.12811883993017002666666666666666e-31
//CSON
};
static final double SQRTPI = 1.77245385090551602729816748334115;
private static double s_xbig;
private static double s_sqeps;
private static int s_nterf;
static {
s_nterf = INITDS.getInitds(ERFCS, 21, 0.1 * D1MACH.three());
s_xbig = Math.sqrt(-Math.log(SQRTPI * D1MACH.three()));
s_sqeps = Math.sqrt(2.0d * D1MACH.three());
}
/**
* Gets the error function at position 'x'
* @param x the position at which to evaluate the error function
* @return the error function value at position 'x'
*/
public static double getErf(final double x) {
double y = Math.abs(x);
double derf = 0;
if (y <= 1) {
if (y <= s_sqeps) {
derf = 2 * x * x / SQRTPI;
}
if (y > s_sqeps) {
derf = x * (1 + DCSEVL.getDCSEVL(2 * x * x - 1d, ERFCS, s_nterf));
}
} else {
if (y <= s_xbig) {
derf = Math.copySign(1 - DERFC.getErfc(y), x);
}
if (y > s_xbig) {
derf = Math.copySign(1, x);
}
}
return derf;
}
} //end class