/** * As described by Bernt Arne Ødegaard in Financial Numerical Recipes in C++. * * <p>Returns P(X < a, Y < b) where X, Y are gaussian random variables N(0, 1) of the bivariate * normal distribution with correlation c in [-1, 1] between X and Y. */ public static double cdf(double a, double b, double c) { if (a == Double.NaN || b == Double.NaN || c == Double.NaN) { throw new IllegalArgumentException("Arguments must be a number."); } if (a == Double.NaN) { System.out.println(""); } a = handleInfinity(a); b = handleInfinity(b); c = handleInfinity(c); if (a == Double.NaN) { System.out.println(""); } if (a <= 0 && b <= 0 && c <= 0) { final double aprime = a / FastMath.sqrt(2d * (1d - c * c)); final double bprime = b / FastMath.sqrt(2d * (1d - c * c)); double sum = 0; for (int i = 0; i < A.length; i++) { for (int j = 0; j < A.length; j++) { sum += A[i] * A[j] * f(B[i], B[j], aprime, bprime, c); } } sum *= FastMath.sqrt(1d - c * c) / FastMath.PI; return sum; } // a or b may be too big and their multiplication may result in NaN. if (c * a * b <= 0) { // c is smaller (between [-1, 1]) and will help to avoid NaNs. So we multiply c // first. if ((a <= 0) && (b >= 0) && (c >= 0)) { return normal.cumulativeProbability(a) - cdf(a, -b, -c); } else if ((a >= 0) && (b <= 0) && (c >= 0)) { return normal.cumulativeProbability(b) - cdf(-a, b, -c); } else if ((a >= 0) && (b >= 0) && (c <= 0)) { return normal.cumulativeProbability(a) + normal.cumulativeProbability(b) - 1 + cdf(-a, -b, c); } } else if (c * a * b >= 0) { final double denum = FastMath.sqrt(a * a - 2d * c * a * b + b * b); final double rho1 = ((c * a - b) * FastMath.signum(a)) / denum; final double rho2 = ((c * b - a) * FastMath.signum(b)) / denum; final double delta = (1d - FastMath.signum(a) * FastMath.signum(b)) / 4d; return cdf(a, 0, rho1) + cdf(b, 0, rho2) - delta; } throw new RuntimeException( "Should never get here. Values of [a; b ; c] = [" + a + "; " + b + "; " + c + "]."); }
public double execute(double in) throws DMLRuntimeException { switch (bFunc) { case SIN: return FASTMATH ? FastMath.sin(in) : Math.sin(in); case COS: return FASTMATH ? FastMath.cos(in) : Math.cos(in); case TAN: return FASTMATH ? FastMath.tan(in) : Math.tan(in); case ASIN: return FASTMATH ? FastMath.asin(in) : Math.asin(in); case ACOS: return FASTMATH ? FastMath.acos(in) : Math.acos(in); case ATAN: return Math.atan(in); // faster in Math case CEIL: return FASTMATH ? FastMath.ceil(in) : Math.ceil(in); case FLOOR: return FASTMATH ? FastMath.floor(in) : Math.floor(in); case LOG: return FASTMATH ? FastMath.log(in) : Math.log(in); case LOG_NZ: return (in == 0) ? 0 : FASTMATH ? FastMath.log(in) : Math.log(in); case ABS: return Math.abs(in); // no need for FastMath case SIGN: return FASTMATH ? FastMath.signum(in) : Math.signum(in); case SQRT: return Math.sqrt(in); // faster in Math case EXP: return FASTMATH ? FastMath.exp(in) : Math.exp(in); case ROUND: return Math.round(in); // no need for FastMath case PLOGP: if (in == 0.0) return 0.0; else if (in < 0) return Double.NaN; else return (in * (FASTMATH ? FastMath.log(in) : Math.log(in))); case SPROP: // sample proportion: P*(1-P) return in * (1 - in); case SIGMOID: // sigmoid: 1/(1+exp(-x)) return FASTMATH ? 1 / (1 + FastMath.exp(-in)) : 1 / (1 + Math.exp(-in)); case SELP: // select positive: x*(x>0) return (in > 0) ? in : 0; default: throw new DMLRuntimeException("Builtin.execute(): Unknown operation: " + bFunc); } }