/** * Since the algorithm to calculate the CDF of a bivariate gaussian distribution fails with * infinity, we change infinity to the maximum value a Double can be. This allows the mentioned * algorithm to provide the appropriate answer. */ private static double handleInfinity(double n) { if (Double.isInfinite(n)) { n = FastMath.copySign(Double.MAX_VALUE, n); } return n; }
/** * Compute the <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> square * root</a> of this complex number. Implements the following algorithm to compute {@code sqrt(a + * bi)}: * * <ol> * <li>Let {@code t = sqrt((|a| + |a + bi|) / 2)} * <li> * <pre>if {@code a ≥ 0} return {@code t + (b/2t)i} * else return {@code |b|/2t + sign(b)t i }</pre> * </ol> * * where * * <ul> * <li>{@code |a| = }{@link Math#abs}(a) * <li>{@code |a + bi| = }{@link Complex#abs}(a + bi) * <li>{@code sign(b) = }{@link FastMath#copySign(double,double) copySign(1d, b)} * </ul> * * <br> * Returns {@link Complex#NaN} if either real or imaginary part of the input argument is {@code * NaN}. <br> * Infinite values in real or imaginary parts of the input may result in infinite or NaN values * returned in parts of the result. * * <pre> * Examples: * <code> * sqrt(1 ± INFINITY i) = INFINITY + NaN i * sqrt(INFINITY + i) = INFINITY + 0i * sqrt(-INFINITY + i) = 0 + INFINITY i * sqrt(INFINITY ± INFINITY i) = INFINITY + NaN i * sqrt(-INFINITY ± INFINITY i) = NaN ± INFINITY i * </code> * </pre> * * @return the square root of {@code this}. * @since 1.2 */ public Complex sqrt() { if (isNaN) { return NaN; } if (real == 0.0 && imaginary == 0.0) { return createComplex(0.0, 0.0); } double t = FastMath.sqrt((FastMath.abs(real) + abs()) / 2.0); if (real >= 0.0) { return createComplex(t, imaginary / (2.0 * t)); } else { return createComplex( FastMath.abs(imaginary) / (2.0 * t), FastMath.copySign(1d, imaginary) * t); } }