Example usage for com.google.common.math DoubleMath fuzzyEquals

List of usage examples for com.google.common.math DoubleMath fuzzyEquals

Introduction

In this page you can find the example usage for com.google.common.math DoubleMath fuzzyEquals.

Prototype

public static boolean fuzzyEquals(double a, double b, double tolerance) 

Source Link

Document

Returns true if a and b are within tolerance of each other.

Usage

From source file:org.eclipse.elk.alg.layered.components.ComponentsCompactor.java

/**
 * @param graphs/*from w w  w.  j  a v a 2s .  c om*/
 *            the components to be compacted
 * @param originalGraphsSize
 *            the size of the overall graph as it is currently
 * @param spacing
 *            the desired spacing to be preserved between any pair of components
 */
public void compact(final List<LGraph> graphs, final KVector originalGraphsSize, final double spacing) {

    // determine the extreme points of the current diagram, 
    // we will reuse this 'frame' to cut external extensions at appropriate lengths
    graphTopLeft = new KVector(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    graphBottomRight = new KVector(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
    for (LGraph graph : graphs) {
        for (LNode node : graph.getLayerlessNodes()) {
            graphTopLeft.x = Math.min(graphTopLeft.x, node.getPosition().x - node.getMargin().left);
            graphTopLeft.y = Math.min(graphTopLeft.y, node.getPosition().y - node.getMargin().top);
            graphBottomRight.x = Math.max(graphBottomRight.x,
                    node.getPosition().x + node.getSize().x + node.getMargin().right);
            graphBottomRight.y = Math.max(graphBottomRight.y,
                    node.getPosition().y + node.getSize().y + node.getMargin().bottom);
        }
    }

    // from the lgraphs, create connected components
    IConnectedComponents<LNode, Set<LEdge>> ccs = new InternalConnectedComponents();
    for (LGraph graph : graphs) {
        IComponent<LNode, Set<LEdge>> c = transformLGraph(graph);
        ccs.getComponents().add(c);
        ((InternalComponent) c).containsRegularNodes |= !c.getExternalExtensionSides().isEmpty();
    }

    // for every component we create an element in the compactor
    compactor = OneDimensionalComponentsCompaction.init(ccs, spacing);

    // execute compaction
    compactor.compact(new BasicProgressMonitor());

    yetAnotherOffset = new KVector();
    compactedGraphSize = compactor.getGraphSize();

    // apply the positions
    for (IComponent<LNode, Set<LEdge>> cc : ccs.getComponents()) {

        // retrieve the common offset for the currently handled connected component
        KVector offset = compactor.getOffset(cc);

        // move it
        LGraphUtil.offsetGraph(((InternalComponent) cc).graph, offset.x, offset.y);

        // adjust positions of external ports
        for (LNode n : ((InternalComponent) cc).getNodes()) {

            if (n.getType() == NodeType.EXTERNAL_PORT) {

                KVector newPos = getExternalPortPosition(n.getPosition(),
                        n.getProperty(InternalProperties.EXT_PORT_SIDE));

                n.getPosition().reset().add(newPos);
            }
        }
    }

    // external edges contribute to the graph's size ... however, only certain segments do.
    for (IComponent<LNode, Set<LEdge>> cc : ccs.getComponents()) {
        for (LEdge e : ((InternalComponent) cc).getExternalEdges()) {
            KVectorChain vc = new KVectorChain(e.getBendPoints());
            vc.add(0, e.getSource().getAbsoluteAnchor());
            vc.add(e.getTarget().getAbsoluteAnchor());

            KVector last = null;
            for (KVector v : vc) {
                if (last == null) {
                    last = v;
                    continue;
                }
                if (DoubleMath.fuzzyEquals(last.x, v.x, EPSILON)) {
                    yetAnotherOffset.x = Math.min(yetAnotherOffset.x, last.x);
                    compactedGraphSize.x = Math.max(compactedGraphSize.x, last.x);
                } else if (DoubleMath.fuzzyEquals(last.y, v.y, EPSILON)) {
                    yetAnotherOffset.y = Math.min(yetAnotherOffset.y, last.y);
                    compactedGraphSize.y = Math.max(compactedGraphSize.y, last.y);
                }
                last = v;
            }
        }
    }

    yetAnotherOffset.negate();
    compactedGraphSize.add(yetAnotherOffset);
}

From source file:org.eclipse.tracecompass.internal.pcap.core.stream.PacketStream.java

/**
 * Get the the average byte per second from B to A.
 *
 * @return the average byte per second from B to A.
 *///from  w  ww  .ja  v  a2  s  . co  m
public synchronized double getBPSBtoA() {
    if (DoubleMath.fuzzyEquals(getDuration(), 0, DELTA)) {
        return 0;
    }
    return fNbBytesBtoA / getDuration();
}

From source file:com.opengamma.strata.math.impl.function.RealPolynomialFunction1D.java

/**
 * Converts the polynomial to its monic form. If 
 * $$// w w w  .  jav  a 2 s  .co  m
 * \begin{align*}
 * P(x) = a_0 + a_1 x + a_2 x^2 + a_3 x^3 \dots + a_n x^n
 * \end{align*}
 * $$
 * then the monic form is
 * $$
 * \begin{align*}
 * P(x) = \lambda_0 + \lambda_1 x + \lambda_2 x^2 + \lambda_3 x^3 \dots + x^n
 * \end{align*}
 * $$
 * where 
 * $$
 * \begin{align*}
 * \lambda_i = \frac{a_i}{a_n}
 * \end{align*}
 * $$
 * 
 * @return the polynomial in monic form
 */
public RealPolynomialFunction1D toMonic() {
    double an = _coefficients[_n - 1];
    if (DoubleMath.fuzzyEquals(an, (double) 1, 1e-15)) {
        return new RealPolynomialFunction1D(Arrays.copyOf(_coefficients, _n));
    }
    double[] rescaled = new double[_n];
    for (int i = 0; i < _n; i++) {
        rescaled[i] = _coefficients[i] / an;
    }
    return new RealPolynomialFunction1D(rescaled);
}

From source file:com.google.api.control.model.Distributions.java

private static boolean bucketsNearlyEquals(ExplicitBuckets a, ExplicitBuckets b) {
    if (a.getBoundsCount() != b.getBoundsCount()) {
        return false;
    }/*w  w w  .j a  v a  2s . c o m*/
    for (int i = 0; i < b.getBoundsCount(); i++) {
        if (!DoubleMath.fuzzyEquals(a.getBounds(i), b.getBounds(i), TOLERANCE)) {
            return false;
        }
    }
    return true;
}

From source file:com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProvider.java

/**
 * Computes the implied volatility in the SABR model and its derivatives.
 * <p>//from   w ww  . j a v a  2 s. c om
 * The derivatives are stored in an array with:
 * <ul>
 * <li>[0] derivative with respect to the forward
 * <li>[1] derivative with respect to the strike
 * <li>[2] derivative with respect to the alpha
 * <li>[3] derivative with respect to the beta
 * <li>[4] derivative with respect to the rho
 * <li>[5] derivative with respect to the nu
 * </ul>
 * 
 * @param forward  the forward value of the underlying
 * @param strike  the strike value of the option
 * @param timeToExpiry  the time to expiry of the option
 * @param alpha  the SABR alpha value
 * @param beta  the SABR beta value
 * @param rho  the SABR rho value
 * @param nu  the SABR nu value
 * @return the volatility and associated derivatives
 */
@Override
public ValueDerivatives volatilityAdjoint(double forward, double strike, double timeToExpiry, double alpha,
        double beta, double rho, double nu) {

    ArgChecker.isTrue(forward > 0.0, "forward must be greater than zero");
    ArgChecker.isTrue(strike >= 0.0, "strike must be greater than zero");
    ArgChecker.isTrue(timeToExpiry >= 0.0, "timeToExpiry must be greater than zero");
    double cutoff = forward * CUTOFF_MONEYNESS;
    double k = strike;
    if (k < cutoff) {
        Logger s_logger = LoggerFactory.getLogger(SabrHaganVolatilityFunctionProvider.class);
        s_logger.info("Given strike of {} is less than cutoff at {}, therefore the strike is taken as {}",
                new Object[] { k, cutoff, cutoff });
        k = cutoff;
    }
    double betaStar = 1 - beta;
    double rhoStar = 1.0 - rho;

    if (alpha == 0.0) {
        double alphaBar;
        if (DoubleMath.fuzzyEquals(forward, k, ATM_EPS)) { //TODO should this is relative
            alphaBar = (1 + (2 - 3 * rho * rho) * nu * nu / 24 * timeToExpiry) / Math.pow(forward, betaStar);
        } else {
            //for non-atm options the alpha sensitivity at alpha = 0 is infinite. Returning this will most likely break calibrations,
            // so we return an arbitrary large number
            alphaBar = 1e7;
        }
        return ValueDerivatives.of(0d, DoubleArray.of(0, 0, alphaBar, 0, 0, 0));
    }

    // Implementation note: Forward sweep.
    double sfK = Math.pow(forward * k, betaStar / 2);
    double lnrfK = Math.log(forward / k);
    double z = nu / alpha * sfK * lnrfK;
    double rzxz;
    double xz = 0;
    if (DoubleMath.fuzzyEquals(z, 0.0, SMALL_Z)) {
        rzxz = 1.0 - 0.5 * z * rho; //small z expansion to z^2 terms
    } else {
        if (DoubleMath.fuzzyEquals(rhoStar, 0.0, RHO_EPS)) {
            if (z < 1.0) {
                xz = -Math.log(1.0d - z);
                rzxz = z / xz;
            } else {
                throw new IllegalArgumentException("can't handle z>=1, rho=1");
            }
        } else {
            double arg;
            if (z < LARGE_NEG_Z) {
                arg = (rho * rho - 1) / 2 / z; //get rounding errors due to fine balanced cancellation for very large negative z
            } else if (z > LARGE_POS_Z) {
                arg = 2 * (z - rho);
            } else {
                arg = (Math.sqrt(1 - 2 * rho * z + z * z) + z - rho);
            }
            if (arg <= 0.0) { //Mathematically this cannot be less than zero, but you know what computers are like.
                rzxz = 0.0;
            } else {
                xz = Math.log(arg / (1 - rho));
                rzxz = z / xz;
            }
        }
    }
    double sf1 = sfK * (1 + betaStar * betaStar / 24 * (lnrfK * lnrfK)
            + Math.pow(betaStar, 4) / 1920 * Math.pow(lnrfK, 4));
    double sf2 = (1 + (Math.pow(betaStar * alpha / sfK, 2) / 24 + (rho * beta * nu * alpha) / (4 * sfK)
            + (2 - 3 * rho * rho) * nu * nu / 24) * timeToExpiry);
    double volatility = Math.max(MIN_VOL, alpha / sf1 * rzxz * sf2);

    // Implementation note: Backward sweep.
    double vBar = 1;
    double sf2Bar = alpha / sf1 * rzxz * vBar;
    double sf1Bar = -alpha / (sf1 * sf1) * rzxz * sf2 * vBar;
    double rzxzBar = alpha / sf1 * sf2 * vBar;
    double zBar;
    double xzBar = 0.0;
    if (DoubleMath.fuzzyEquals(z, 0.0, SMALL_Z)) {
        zBar = -rho / 2 * rzxzBar;
    } else {
        if (DoubleMath.fuzzyEquals(rhoStar, 0.0, RHO_EPS)) {
            if (z < 1.0) {
                xzBar = -z / (xz * xz) * rzxzBar;
                zBar = 1.0d / xz * rzxzBar + 1.0d / (1.0d - z) * xzBar;
            } else {
                throw new IllegalArgumentException("can't handle z>=1, rho=1");
            }
        } else {
            if (z < LARGE_NEG_Z) {
                zBar = 1 / xz * rzxzBar + xzBar / (xz * xz) * rzxzBar;
            } else if (z > LARGE_POS_Z) {
                zBar = 1 / xz * rzxzBar - xzBar / (xz * xz) * rzxzBar;
            } else {
                xzBar = -z / (xz * xz) * rzxzBar;
                zBar = 1 / xz * rzxzBar + 1 / ((Math.sqrt(1 - 2 * rho * z + z * z) + z - rho))
                        * (0.5 * Math.pow(1 - 2 * rho * z + z * z, -0.5) * (-2 * rho + 2 * z) + 1) * xzBar;
            }
        }
    }

    double lnrfKBar = sfK
            * (betaStar * betaStar / 12 * lnrfK + Math.pow(betaStar, 4) / 1920 * 4 * Math.pow(lnrfK, 3))
            * sf1Bar + nu / alpha * sfK * zBar;
    double sfKBar = nu / alpha * lnrfK * zBar + sf1 / sfK * sf1Bar
            - (Math.pow(betaStar * alpha, 2) / Math.pow(sfK, 3) / 12
                    + (rho * beta * nu * alpha) / 4 / (sfK * sfK)) * timeToExpiry * sf2Bar;
    double strikeBar = -1 / k * lnrfKBar + betaStar * sfK / (2 * k) * sfKBar;
    double forwardBar = 1 / forward * lnrfKBar + betaStar * sfK / (2 * forward) * sfKBar;
    double nuBar = 1 / alpha * sfK * lnrfK * zBar
            + ((rho * beta * alpha) / (4 * sfK) + (2 - 3 * rho * rho) * nu / 12) * timeToExpiry * sf2Bar;

    double rhoBar;
    if (Math.abs(forward - k) < ATM_EPS) {
        rhoBar = -z / 2 * rzxzBar;
    } else {
        if (DoubleMath.fuzzyEquals(rhoStar, 0.0, RHO_EPS)) {
            if (z >= 1) {
                if (rhoStar == 0.0) {
                    rhoBar = Double.NEGATIVE_INFINITY; //the derivative at rho = 1 is infinite  - this sets it to some arbitrary large number
                } else {
                    rhoBar = xzBar * (1.0 / rhoStar + (0.5 - z) / (z - 1.0) / (z - 1.0));
                }
            } else {
                rhoBar = (0.5 * Math.pow(z / (1 - z), 2)
                        + 0.25 * (z - 4.0) * Math.pow(z / (1.0 - z), 3) / (1.0 - z) * rhoStar) * xzBar;
            }
        } else {
            rhoBar = (1 / (Math.sqrt(1 - 2 * rho * z + z * z) + z - rho)
                    * (-Math.pow(1 - 2 * rho * z + z * z, -0.5) * z - 1) + 1 / rhoStar) * xzBar;
        }
    }
    rhoBar += ((beta * nu * alpha) / (4 * sfK) - rho * nu * nu / 4) * timeToExpiry * sf2Bar;

    double alphaBar = -nu / (alpha * alpha) * sfK * lnrfK * zBar
            + ((betaStar * alpha / sfK) * (betaStar / sfK) / 12 + (rho * beta * nu) / (4 * sfK)) * timeToExpiry
                    * sf2Bar
            + 1 / sf1 * rzxz * sf2 * vBar;
    double betaBar = -0.5 * Math.log(forward * k) * sfK * sfKBar
            - sfK * (betaStar / 12 * (lnrfK * lnrfK) + Math.pow(betaStar, 3) / 480 * Math.pow(lnrfK, 4))
                    * sf1Bar
            + (-betaStar * alpha * alpha / sfK / sfK / 12 + rho * nu * alpha / 4 / sfK) * timeToExpiry * sf2Bar;

    return ValueDerivatives.of(volatility,
            DoubleArray.of(forwardBar, strikeBar, alphaBar, betaBar, rhoBar, nuBar));
}

From source file:com.google.api.control.model.Distributions.java

private static boolean bucketsNearlyEquals(ExponentialBuckets a, ExponentialBuckets b) {
    return ((a.getNumFiniteBuckets() == b.getNumFiniteBuckets())
            && (DoubleMath.fuzzyEquals(a.getGrowthFactor(), b.getGrowthFactor(), TOLERANCE)
                    && (DoubleMath.fuzzyEquals(a.getScale(), b.getScale(), TOLERANCE))));
}

From source file:com.google.api.control.model.Distributions.java

private static boolean bucketsNearlyEquals(LinearBuckets a, LinearBuckets b) {
    return ((a.getNumFiniteBuckets() == b.getNumFiniteBuckets())
            && (DoubleMath.fuzzyEquals(a.getWidth(), b.getWidth(), TOLERANCE)
                    && (DoubleMath.fuzzyEquals(a.getOffset(), b.getOffset(), TOLERANCE))));
}

From source file:com.opengamma.strata.pricer.impl.option.NormalFormulaRepository.java

/**
 * Computes the implied volatility./*from   w  w  w. j  ava  2  s.  c  om*/
 * <p>
 * If the volatility data is not zero, it is used as a starting point for the volatility search.
 * <p>
 * Note that the 'numeraire' is a simple multiplier and is the responsibility of the caller.
 * 
 * @param optionPrice  the price of the option
 * @param forward  the forward value of the underlying
 * @param strike  the strike
 * @param timeToExpiry  the time to expiry
 * @param initialNormalVol  the normal volatility used to start the search
 * @param numeraire  the numeraire
 * @param putCall  whether it is put or call
 * @return the implied volatility
 */
public static double impliedVolatility(double optionPrice, double forward, double strike, double timeToExpiry,
        double initialNormalVol, double numeraire, PutCall putCall) {

    double intrinsicPrice = numeraire * Math.max(0, (putCall.isCall() ? 1 : -1) * (forward - strike));
    ArgChecker.isTrue(optionPrice > intrinsicPrice || DoubleMath.fuzzyEquals(optionPrice, intrinsicPrice, 1e-6),
            "Option price (" + optionPrice + ") less than intrinsic value (" + intrinsicPrice + ")");
    if (Double.doubleToLongBits(optionPrice) == Double.doubleToLongBits(intrinsicPrice)) {
        return 0d;
    }
    double sigma = (Math.abs(initialNormalVol) < 1e-10 ? 0.3 * forward : initialNormalVol);
    double maxChange = 0.5 * forward;
    ValueDerivatives price = priceAdjoint(forward, strike, timeToExpiry, sigma, numeraire, putCall);
    double vega = price.getDerivative(1);
    double change = (price.getValue() - optionPrice) / vega;
    double sign = Math.signum(change);
    change = sign * Math.min(maxChange, Math.abs(change));
    if (change > 0 && change > sigma) {
        change = sigma;
    }
    int count = 0;
    while (Math.abs(change) > EPS) {
        sigma -= change;
        price = priceAdjoint(forward, strike, timeToExpiry, sigma, numeraire, putCall);
        vega = price.getDerivative(1);
        change = (price.getValue() - optionPrice) / vega;
        sign = Math.signum(change);
        change = sign * Math.min(maxChange, Math.abs(change));
        if (change > 0 && change > sigma) {
            change = sigma;
        }
        if (count++ > MAX_ITERATIONS) {
            BracketRoot bracketer = new BracketRoot();
            BisectionSingleRootFinder rootFinder = new BisectionSingleRootFinder(EPS);
            Function<Double, Double> func = new Function<Double, Double>() {
                @Override
                public Double apply(Double volatility) {
                    return numeraire * price(forward, strike, timeToExpiry, volatility, putCall) - optionPrice;
                }
            };
            double[] range = bracketer.getBracketedPoints(func, 0d, 10d);
            return rootFinder.getRoot(func, range[0], range[1]);
        }
    }
    return sigma;
}

From source file:com.opengamma.strata.collect.DoubleArrayMath.java

/**
 * Compares each element in the array to zero within a tolerance.
 * <p>/*from  ww w.j  a  v  a 2 s. c o m*/
 * An empty array returns true;
 * <p>
 * The input array is not mutated.
 * 
 * @param array  the array to check
 * @param tolerance  the tolerance to use
 * @return true if the array is effectively equal to zero
 */
public static boolean fuzzyEqualsZero(double[] array, double tolerance) {
    for (int i = 0; i < array.length; i++) {
        if (!DoubleMath.fuzzyEquals(array[i], 0, tolerance)) {
            return false;
        }
    }
    return true;
}

From source file:com.analog.lyric.collect.ArrayUtil.java

/**
 * True if all values in {@code array} whose indices are in {@code arraySubindices}
 * are {@link DoubleMath#fuzzyEquals} to each other with given {@code tolerance}. Returns true if
 * length of {@code arraySubindices} is less than length 2.
 * //from w  w w . j  av a 2  s .c o m
 * @param arraySubindices must be no larger than {@code array} and should contain indexes in the
 * range [0,array.length-1].
 * 
 * @see #allFuzzyEqual(double[], double)
 */
public static boolean subsetFuzzyEqual(double[] array, int[] arraySubindices, double tolerance) {
    if (arraySubindices.length > 1) {
        double min, max;
        min = max = array[arraySubindices[0]];

        for (int i = 1, end = arraySubindices.length; i < end; ++i) {
            final double d = array[arraySubindices[i]];
            min = Math.min(min, d);
            max = Math.max(max, d);
        }
        if (!DoubleMath.fuzzyEquals(min, max, tolerance)) {
            return false;
        }
    }

    return true;
}