/** * 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 + "]."); }
@Override protected OperationData process(IDataset input, IMonitor monitor) { double theta = 0; try { theta = ScanMetadata.getTheta(input); } catch (Exception e) { } NormalDistribution beamfootprint = new NormalDistribution( 0, (1e-3 * model.getBeamHeight() / 2 * Math.sqrt(2 * Math.log(2) - 0.5))); double areaCorrection = 2 * (beamfootprint.cumulativeProbability( (model.getFootprint() * Math.sin((theta + model.getAngularFudgeFactor()) * Math.PI / 180)))); Dataset output = DatasetUtils.cast(input, Dataset.FLOAT64); output = Maths.multiply(input, areaCorrection); Dataset outputSum = DatasetFactory.createFromObject((DatasetUtils.cast(output, Dataset.FLOAT64)).sum()); return new OperationData(output, outputSum); }
@Test /** Test of integrator for the sine function. */ public void testSinFunction() { UnivariateFunction f = new Gaussian(10, 2); UnivariateIntegrator integrator = new SimpsonIntegrator(); double a, b, expected, tolerance, result; a = 8; b = 12; expected = 0.68269; tolerance = 0.00001; tolerance = Math.abs(expected * integrator.getRelativeAccuracy()); result = integrator.integrate(MAX_EVAL, f, a, b); assertEquals(expected, result, tolerance); log.info( "Result: " + result + ", tolerance: " + tolerance + " - Relative accuracy: " + integrator.getRelativeAccuracy() + " - Absolute accuracy: " + integrator.getAbsoluteAccuracy() + " - Iterations: " + integrator.getIterations()); NormalDistribution distribution = new NormalDistribution(10, 2); result = distribution.cumulativeProbability(a, b); log.info("Distribution result: " + result); }
// Model "a" with a normal distribution, and test whether cdf(mean(b)) > pvalue public boolean significantIncrease(List<Double> a, List<Double> b, double pvalue) { double meanA = mean(a); double sd = 0; for (Double val : a) { sd += (val - meanA) * (val - meanA); } sd = Math.sqrt(sd / (a.size() - 1)); if (sd <= 0) { return true; } double meanB = mean(b); NormalDistribution dist = new NormalDistribution(meanA, sd); double p = dist.cumulativeProbability(meanB); boolean significant = (p > pvalue); System.out.println("p-value=" + p + ", " + (significant ? "increase" : "no increase")); return significant; }
public static double normalCDF(double x, double mean, double sigma) { NormalDistribution normDist = new NormalDistribution(mean, sigma); double ret = normDist.cumulativeProbability(x); return ret; }