Example usage for java.lang Double POSITIVE_INFINITY

List of usage examples for java.lang Double POSITIVE_INFINITY

Introduction

In this page you can find the example usage for java.lang Double POSITIVE_INFINITY.

Prototype

double POSITIVE_INFINITY

To view the source code for java.lang Double POSITIVE_INFINITY.

Click Source Link

Document

A constant holding the positive infinity of type double .

Usage

From source file:com.opengamma.analytics.financial.model.finitedifference.CoupledFiniteDifference.java

@SuppressWarnings("unused")
private int sor(final double omega, final PDEGrid1D grid, final Surface<Double, Double, Double> freeBoundary,
        final int xNodes, final double[] f, final double[] q, final double[][] m, final double t2) {
    double sum;/*from   w w w .  j av a2s.  c o  m*/
    int count = 0;
    double scale = 1.0;
    double errorSqr = Double.POSITIVE_INFINITY;
    while (errorSqr / (scale + 1e-10) > 1e-18) {
        errorSqr = 0.0;
        scale = 0.0;
        for (int j = 0; j < 2 * xNodes; j++) {
            sum = 0;
            for (int k = 0; k < 2 * xNodes; k++) {
                sum += m[j][k] * f[k];
            }
            double correction = omega / m[j][j] * (q[j] - sum);
            if (freeBoundary != null) {
                correction = Math.max(correction, freeBoundary.getZValue(t2, grid.getSpaceNode(j)) - f[j]);
            }
            errorSqr += correction * correction;
            f[j] += correction;
            scale += f[j] * f[j];
        }
        count++;
    }
    return count;
}

From source file:edu.byu.nlp.crowdsourcing.models.gibbs.BlockCollapsedMultiAnnModelMath.java

/**
 * @param gold (optional) If the GOLD diagonalization method is to 
 * be used, gold standard labels must also be passed in.
 */// w w w  . ja  v  a2 s  .  c o  m

public static MultiAnnState fixLabelSwitching(MultiAnnState sample, DiagonalizationMethod diagonalizationMethod,
        int goldInstancesForDiagonalization, boolean diagonalizationWithFullConfusionMatrix,
        RandomGenerator rnd) {
    //  public static MultiAnnSample fixLabelSwitching(MultiAnnSample sample, int[] gold, boolean labelSwitchingCheatUsesFullConfusionMatrix, Dataset data) {
    // manually re-order the labels according to y and then
    // m so that mu and alpha_j line up with their greatest entries
    // along the diagonal as much as possible.
    // This helps alleviate the problem of label switching.

    // Note that we are not changing the meaning of labels
    // globally (in the data elicited from annotators);
    // merely ensuring that the features-only-ML
    // will be most likely to assign a Y=0 assignment
    // the label 0; a Y=1 assignment the label 1, and
    // so forth (rather than learning to systematically
    // map Y=0 to 2, for example, which would be a setting
    // with just as much probability as the Y=0 to 0 setting.

    // It's important to NOT use the counts (e.g., logCountOfYAndM)
    // We need to look at actual normalized accuracies (e.g., mu).

    int[] y = sample.getY().clone();
    int[] m = sample.getM().clone();
    double[][] mu = Matrices.clone(sample.getMu());
    double[][] meanMu = Matrices.clone(sample.getMeanMu());
    double[][][] alpha = Matrices.clone(sample.getAlpha());
    double[][][] meanAlpha = Matrices.clone(sample.getMeanAlpha());
    double[] theta = sample.getTheta().clone();
    double[] meanTheta = sample.getMeanTheta().clone();
    double[][] logPhi = Matrices.clone(sample.getLogPhi());
    double[][] meanLogPhi = Matrices.clone(sample.getMeanLogPhi());

    // -------------- Fix Y ----------------------- //
    int[] yMap;
    int[] gold;
    switch (diagonalizationMethod) {
    case NONE:
        logger.info("Not Diagonalizing");
        // diagonal mapping (no change)
        yMap = IntArrays.sequence(0, mu.length);
        break;
    case RAND:
        logger.info("Diagonalizing randomly");
        // randomly shuffled mapping 
        yMap = IntArrays.shuffled(IntArrays.sequence(0, mu.length), rnd);
        break;
    case GOLD:
        logger.info("Diagonalizing based on gold 'heldout data'");
        // create a confusion matrix by comparing gold labels with model predictions (gold labels are constructed to match the model ordering) 
        Boolean useLabeledConfusionMatrix = diagonalizationWithFullConfusionMatrix ? null : true;
        gold = Datasets.concealedLabels(sample.getData(), sample.getInstanceIndices());
        int numGoldInstances = goldInstancesForDiagonalization == -1 ? gold.length
                : goldInstancesForDiagonalization;
        gold = Arrays.copyOfRange(gold, 0, numGoldInstances);
        int[] guesses = Arrays.copyOfRange(sample.getY(), 0, numGoldInstances);
        double[][] confusions = confusionMatrix(useLabeledConfusionMatrix, gold, guesses, sample.getNumLabels(),
                sample.getData());
        // in a CONFUSION matrix, columns correspond to the latent variable y. So 
        // permute columns to find a good diagonalization
        yMap = Matrices.getColReorderingForStrongDiagonal(confusions);
        break;
    case AVG_GAMMA:
        // in a gamma matrix, rows correspond to the latent variable y, so permute rows 
        // to find a good diagonalization
        logger.info("Diagonalizing based on average alpha");
        double[][] cumulativeAlphaMean = new double[sample.getNumLabels()][sample.getNumLabels()];
        for (int j = 0; j < sample.getNumAnnotators(); j++) {
            double[][] alphaMean = meanAlpha[j];
            Matrices.addToSelf(cumulativeAlphaMean, alphaMean);
        }
        yMap = Matrices.getRowReorderingForStrongDiagonal(cumulativeAlphaMean);
        break;
    case MAX_GAMMA:
        logger.info("Diagonalizing based on most confident alpha");
        // (pfelt) Find the most definitive alpha matrix
        // (the one with entries that diverge least from 0 and 1)
        // We'll map that to be diagonal and then apply its mapping
        // to all of the other alphas, since alpha matrices
        // are constrained by the data to be coherent.
        double[][] bestAlphaMean = null;
        double min = Double.POSITIVE_INFINITY;
        for (int j = 0; j < sample.getNumAnnotators(); j++) {
            double[][] alphaMean = meanAlpha[j];
            double error = getMeanSquaredDistanceFrom01(alphaMean);
            if (error < min) {
                min = error;
                bestAlphaMean = alphaMean;
            }
        }
        yMap = Matrices.getNormalizedRowReorderingForStrongDiagonal(bestAlphaMean);
        break;
    default:
        throw new IllegalArgumentException(
                "unknown diagonalization method: " + diagonalizationMethod.toString());
    }

    logger.info("Y-mapping=" + IntArrays.toString(yMap));

    // fix alpha
    for (int j = 0; j < sample.getNumAnnotators(); j++) {
        Matrices.reorderRowsToSelf(yMap, alpha[j]);
        Matrices.reorderRowsToSelf(yMap, meanAlpha[j]);
    }
    // fix y
    for (int i = 0; i < y.length; i++) {
        y[i] = yMap[y[i]];
    }
    // fix theta
    Matrices.reorderElementsToSelf(yMap, theta);
    Matrices.reorderElementsToSelf(yMap, meanTheta);
    // fix mu
    Matrices.reorderRowsToSelf(yMap, mu);
    Matrices.reorderRowsToSelf(yMap, meanMu);

    // (pfelt) we don't need to update cached values anymore since we're 
    // operating on a sample and not in the context of a model being sampled
    //    // fix logSumCountOfYAndM
    //    Matrices.reorderElementsToSelf(yMap, logSumCountOfYAndM);
    //    // fix numAnnsPerJAndY
    //    Matrices.reorderColsToSelf(yMap, numAnnsPerJAndY);

    // -------------- Fix M ----------------------- //
    // (pfelt) We used to sample from mu (by calling mu())
    // to get a mu setting. I've changed this to use the params
    // of mu for two reasons:
    // 1) a small performance savings
    // 2) it's easier to test
    int[] mMap;
    try {
        mMap = Matrices.getColReorderingForStrongDiagonal(meanMu);
    } catch (IllegalArgumentException e) {
        mMap = new int[meanMu.length];
        for (int i = 0; i < mMap.length; i++) {
            mMap[i] = i;
        }
        logger.warn("unable to diagonalize m, returning the identity mapping. "
                + "If this is itemresp or momresp, then this is fine. "
                + "If this is multiann, then there is a serious problem.");
    }

    // fix mu
    Matrices.reorderColsToSelf(mMap, mu);
    Matrices.reorderColsToSelf(mMap, meanMu);
    // fix m
    for (int i = 0; i < m.length; i++) {
        m[i] = mMap[m[i]];
    }
    // fix phi
    Matrices.reorderRowsToSelf(mMap, logPhi);
    Matrices.reorderRowsToSelf(mMap, meanLogPhi);

    // (pfelt) we don't need to update cached values anymore since we're 
    // operating on a sample and not in the context of a model being sampled
    //    // fix numFeaturesPerM
    //    Matrices.reorderElementsToSelf(mMap, numFeaturesPerM);

    return new BasicMultiAnnState(y, m, theta, meanTheta, logPhi, meanLogPhi, mu, meanMu, alpha, meanAlpha,
            sample.getData(), sample.getInstanceIndices());
}

From source file:ucar.unidata.idv.control.chart.ChartWrapper.java

/**
 * Get get list of Ranges for time subsetting. If there are none
 * then return null.//from  ww  w . j  av  a2 s .com
 *
 * @return List of time ranges or null
 */
protected List getTimeFilterRanges() {
    List ranges = null;
    if ((minDate != Double.NEGATIVE_INFINITY) || (maxDate != Double.POSITIVE_INFINITY)) {
        if ((minDate != dataMinDate) || (maxDate != dataMaxDate)) {
            ranges = Misc.newList(new ucar.unidata.util.Range(minDate, maxDate));

        }
    }

    if (timeFilterSource != null) {
        List filterRanges = timeFilterSource.getTimeRanges();
        if (filterRanges != null) {
            if (ranges == null) {
                ranges = filterRanges;
            } else {
                ranges.addAll(filterRanges);
            }
        }
    }
    return ranges;
}

From source file:io.github.gjyaiya.stetho.realm.Database.java

private List<Object> flattenRows(Table table, long limit, boolean addRowIndex) {
    Util.throwIfNot(limit >= 0);
    final List<Object> flatList = new ArrayList<>();
    long numColumns = table.getColumnCount();

    final RowFetcher rowFetcher = RowFetcher.getInstance();
    final long tableSize = table.size();
    for (long index = 0; index < limit && index < tableSize; index++) {
        final long row = ascendingOrder ? index : (tableSize - index - 1);
        final RowWrapper rowData = RowWrapper.wrap(rowFetcher.getRow(table, row));
        if (addRowIndex) {
            flatList.add(rowData.getIndex());
        }//  w ww .j  a  v a 2 s  .  c  o m
        for (int column = 0; column < numColumns; column++) {
            switch (rowData.getColumnType(column)) {
            case INTEGER:
                if (rowData.isNull(column)) {
                    flatList.add(NULL);
                } else {
                    flatList.add(rowData.getLong(column));
                }
                break;
            case BOOLEAN:
                if (rowData.isNull(column)) {
                    flatList.add(NULL);
                } else {
                    flatList.add(rowData.getBoolean(column));
                }
                break;
            case STRING:
                if (rowData.isNull(column)) {
                    flatList.add(NULL);
                } else {
                    flatList.add(rowData.getString(column));
                }
                break;
            case BINARY:
                if (rowData.isNull(column)) {
                    flatList.add(NULL);
                } else {
                    flatList.add(rowData.getBinaryByteArray(column));
                }
                break;
            case FLOAT:
                if (rowData.isNull(column)) {
                    flatList.add(NULL);
                } else {
                    final float aFloat = rowData.getFloat(column);
                    if (Float.isNaN(aFloat)) {
                        flatList.add("NaN");
                    } else if (aFloat == Float.POSITIVE_INFINITY) {
                        flatList.add("Infinity");
                    } else if (aFloat == Float.NEGATIVE_INFINITY) {
                        flatList.add("-Infinity");
                    } else {
                        flatList.add(aFloat);
                    }
                }
                break;
            case DOUBLE:
                if (rowData.isNull(column)) {
                    flatList.add(NULL);
                } else {
                    final double aDouble = rowData.getDouble(column);
                    if (Double.isNaN(aDouble)) {
                        flatList.add("NaN");
                    } else if (aDouble == Double.POSITIVE_INFINITY) {
                        flatList.add("Infinity");
                    } else if (aDouble == Double.NEGATIVE_INFINITY) {
                        flatList.add("-Infinity");
                    } else {
                        flatList.add(aDouble);
                    }
                }
                break;
            case OLD_DATE:
            case DATE:
                if (rowData.isNull(column)) {
                    flatList.add(NULL);
                } else {
                    flatList.add(formatDate(rowData.getDate(column)));
                }
                break;
            case OBJECT:
                if (rowData.isNullLink(column)) {
                    flatList.add(NULL);
                } else {
                    flatList.add(rowData.getLink(column));
                }
                break;
            case LIST:
                // LIST never be null
                flatList.add(formatList(rowData.getLinkList(column)));
                break;
            default:
                flatList.add("unknown column type: " + rowData.getColumnType(column));
                break;
            }
        }
    }

    if (limit < table.size()) {
        for (int column = 0; column < numColumns; column++) {
            flatList.add("{truncated}");
        }
    }

    return flatList;
}

From source file:de.thkwalter.et.ortskurve.Startpunktbestimmung.java

/**
 * Diese Methode bestimmt den Messpunkt, dessen x- bzw. y-Komponente am nhesten zum Mittelwert aus der grten und der 
 * kleinsten auftreteten x- bzw. y-Komponente liegt. 
 * /*ww w.  j av a 2s  .  c o  m*/
 * @param messpunkte Eine Liste der x- bzw. y-Komponenten der Messpunkte
 * @param mittelwert Der Mittelwert aus der grten und der kleinsten auftreteten x- bzw. y-Komponente
 * 
 * @return Der Messpunkt, dessen x- bzw. y-Komponente am nhesten zum Mittelwert aus der grten und der 
 * kleinsten auftreteten x- bzw. y-Komponente liegt
 */
private static Vector2D mittlerenMesspunktBestimmen(ArrayList<? extends KomponenteMesspunkt> liste,
        double mittelwert) {
    // Der gesuchte Messpunkt.
    KomponenteMesspunkt mittlereKomponenteMesspunkt = null;

    // Der kleinste bisher gefundene Abstand der x- bzw. y-Komponente eines Messpunkts zum Mittelwert.
    double minAbstandZumMittelwert = Double.POSITIVE_INFINITY;

    // Der Abstand der x- bzw. y-Komponente eines Messpunkts zum Mittelwert.
    double abstandZumMittelwert = Double.NaN;

    // Eine Schleife ber alle Messpunkte.
    for (KomponenteMesspunkt komponenteMesspunkt : liste) {
        // Der Abstand der x- bzw. y-Komponente eines Messpunkts zum Mittelwert wird berechnet.
        abstandZumMittelwert = Math.abs(komponenteMesspunkt.getWert() - mittelwert);

        // Falls der Abstand der x- bzw. y-Komponente des aktuellen Messpunkts zum Mittelwert kleiner als das bisherige 
        // Minimum ist, ...
        if (abstandZumMittelwert < minAbstandZumMittelwert) {
            // Der minimale Abstand der x- bzw. y-Komponente eines Messpunkts zum Mittelwert wird aktualisiert.
            minAbstandZumMittelwert = abstandZumMittelwert;

            // Der gesuchte Punkt wird aktualisiert.
            mittlereKomponenteMesspunkt = komponenteMesspunkt;
        }
    }

    // Der gesuchte Messpunkt wird zurckgegeben.
    return mittlereKomponenteMesspunkt.getMesspunkt();
}

From source file:org.opendatakit.ermodel.RelationTest.java

@Test
public void testCase8() throws ODKDatastoreException {

    MyRelation rel = new MyRelation(callingContext);
    rel = new MyRelation(callingContext);
    Entity e = rel.newEntity(callingContext);

    e.setAsString("secondField", "5");
    e.setAsString("thirdField", "3.3");
    e.setAsString("thirdApproxField", Double.toString(Double.NaN));
    e.setAsString("fourthField", (new Date()).toString());
    e.set("thisIsIt", "a simple long string");

    e.put(callingContext);/*from  www.j a  va 2s  .  com*/

    Entity e2 = rel.newEntity(callingContext);

    e2.setAsString("secondField", "6");
    e2.setAsString("thirdApproxField", "6.81");
    e2.setAsString("fourthField", (new Date(0)).toString());
    e2.set("thisIsIt", "another simple long string");

    e2.put(callingContext);

    Entity e3 = rel.newEntity(callingContext);

    e3.setAsString("secondField", "7");
    e3.setAsString("thirdApproxField", Double.toString(Double.POSITIVE_INFINITY));
    e3.setAsString("fourthField", (new Date(0)).toString());
    e3.set("thisIsIt", "another simple long string");

    e3.put(callingContext);

    Entity e4 = rel.newEntity(callingContext);

    e4.setAsString("secondField", "8");
    e4.setAsString("thirdField", "3.3");
    e4.setAsString("thirdApproxField", Double.toString(Double.NEGATIVE_INFINITY));
    e4.setAsString("fourthField", (new Date(0)).toString());
    e4.set("thisIsIt", "another simple long string");

    e4.put(callingContext);

    Query query;
    List<Entity> entities;

    query = rel.query("DbTable.testCase8.fieldApproxDbl-notEqual", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.NOT_EQUAL, Double.NaN);
    entities = query.execute();
    assertEquals(3, entities.size());

    query = rel.query("DbTable.testCase8.fieldApproxDbl-Equal", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.EQUAL, Double.NaN);
    entities = query.execute();
    assertEquals(1, entities.size());
    assertEquals(e.getId(), entities.get(0).getId());

    query = rel.query("DbTable.testCase8.fieldApproxDbl-notEqual", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.NOT_EQUAL, 6.81);
    entities = query.execute();
    assertEquals(3, entities.size());

    query = rel.query("DbTable.testCase8.fieldApproxDbl-Equal", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.EQUAL, 6.81);
    entities = query.execute();
    assertEquals(1, entities.size());
    assertEquals(e2.getId(), entities.get(0).getId());

    query = rel.query("DbTable.testCase8.fieldDbl-notEqual", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.NOT_EQUAL, Double.POSITIVE_INFINITY);
    entities = query.execute();
    assertEquals(3, entities.size());

    query = rel.query("DbTable.testCase8.fieldApproxDbl-Equal", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.EQUAL, Double.POSITIVE_INFINITY);
    entities = query.execute();
    assertEquals(1, entities.size());
    assertEquals(e3.getId(), entities.get(0).getId());

    query = rel.query("DbTable.testCase8.fieldApproxDbl-notEqual", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.NOT_EQUAL, Double.NEGATIVE_INFINITY);
    entities = query.execute();
    assertEquals(3, entities.size());

    query = rel.query("DbTable.testCase8.fieldApproxDbl-Equal", callingContext);
    query.addFilter(MyRelation.fieldApproxDbl.getName(), FilterOperation.EQUAL, Double.NEGATIVE_INFINITY);
    entities = query.execute();
    assertEquals(1, entities.size());
    assertEquals(e4.getId(), entities.get(0).getId());

    rel.dropRelation(callingContext);
}

From source file:de.tudarmstadt.lt.ltbot.postprocessor.DecesiveValueProducerPerplexity.java

double getPerplexity(CrawlURI uri) {
    assert _lmprvdr != null : "String provider service must not be null here. This should have been checked before.";

    String cleaned_plaintext = _textExtractorInstance.getCleanedUtf8PlainText(uri).trim();
    String cleaned_plaintext_abbr = MULTIPLE_SPACES_PATTERN
            .matcher(StringUtils.abbreviate(cleaned_plaintext, 50)).replaceAll(" ");
    addExtraInfo(uri, EXTRA_INFO_PLAINTEXT_ABBREVIATED, cleaned_plaintext_abbr);
    if (cleaned_plaintext.isEmpty())
        return Double.POSITIVE_INFINITY;
    double perplexity = Double.POSITIVE_INFINITY;
    try {/*  w  w w. j  a v  a  2s  .c  o  m*/
        String docid = "#" + Integer.toHexString(cleaned_plaintext.hashCode());
        LOG.finest(String.format("Sending text with id '%s' to StringProvider: '%s' (length %d).", docid,
                cleaned_plaintext_abbr, cleaned_plaintext.length()));
        perplexity = computePerplexity(cleaned_plaintext);
        //         if (Double.isNaN(perplexity)) {
        //            double perplexity_new = -1d;
        //            LOG.log(Level.WARNING, String.format("[%s '%s'] failed to get meaningful perplexity: %g. Setting perplexity to %g.", uri.toString(), cleaned_plaintext_abbr, perplexity, perplexity_new));
        //            perplexity = perplexity_new;
        //         }
        LOG.finest(String.format("[%s, '%s'] perplexity: %g.", uri.toString(), cleaned_plaintext_abbr,
                perplexity));
    } catch (Throwable t) {
        for (int i = 1; t != null && i < 10; i++) {
            LOG.log(Level.SEVERE,
                    String.format("Could not compute perplexity for URI '%s' and text: '%s'. (%d %s:%s)",
                            uri.toString(), cleaned_plaintext_abbr, i, t.getClass().getSimpleName(),
                            t.getMessage()),
                    t);
            t = t.getCause();
            LOG.log(Level.SEVERE, "Requesting to pause crawl.");
            getCrawlController().requestCrawlPause();
            _paused_due_to_error = true;
        }
    }
    if (!Double.isFinite(perplexity) || perplexity <= 1) {
        LOG.log(Level.FINE,
                String.format(
                        "[%s '%s'] resetting infinite perplexity to predefined maximum perplexity value (-1).",
                        uri.toString(), cleaned_plaintext_abbr));
        perplexity = -1;
    }
    return perplexity;
}

From source file:knop.psfj.BeadFrame.java

/**
 * Gets the distance with alter ego.// w ww . j  a va  2  s  .  c o  m
 *
 * @return the distance with alter ego
 */
public double getDistanceWithAlterEgo() {
    if (alterEgo != null) {
        return getDistance(alterEgo);
    }

    else {
        return Double.POSITIVE_INFINITY;
    }
}

From source file:com.clust4j.metrics.pairwise.Distance.java

private static double nanInf(double d) {
    return Double.isNaN(d) ? Double.POSITIVE_INFINITY : d;
}

From source file:NumberUtils.java

/**
 * Compares the first number to the second one numerically and 
 * returns an integer depending on the comparison result:
 * a negative value if the first number is the smaller one,
 * a zero value if they are equal, and//from   w w w.  j  ava2s  .c om
 * a positive value if the first number is the larger one.
 *
 * The main strategy goes like follows:
 * 1. If one of the arguments is <code>null</code> or 'not a number',
 *    throw an exception.
 * 2. If both values are 'long compatible', compare their <code>longValue()</code>
 *    using the usual comparison operators for primitive types (&lt;, ==, &gt;).
 * 3. If both values are 'double compatible', compare their <code>doubleValue()</code>
 *    using the usual comparison operators for primitive types (&lt;, ==, &gt;).
 * 4. If one of the values is infinite (and the other is finite),
 *    determine the result depending on the sign of the infinite value.
 * 5. Otherwise convert both values to <code>java.math.BigDecimal</code> and
 *    return the result of the <code>BigDecimal.compareTo(BigDecimal)</code> method.
 *
 * As a consequence, the method is not suitable to implement a
 * <code>java.util.Comparator</code> for numbers. To achieve this,
 * one had to accept 'not a number' arguments and place them somewhere
 * in the row of numbers (probably at the upper end, i.e. larger than
 * positive infinity, as <code>Double.compare(double, double)</code>
 * does it).
 * So the behavior of this method is like that of the comparison
 * operator for primitive types and not like that of the related
 * <code>compareTo(...)</code> methods. Besides the handling of
 * 'not a number' values this makes a difference, when comparing
 * the float or double values <code>-0.0</code> and <code>0.0</code>:
 * again, like the operators, we consider them as equal (whereas
 * according to <code>Double.compareTo(...)</code> <code>-0.0</code>
 * is less than <code>0.0</code>).
 *
 * @param first
 * @param second
 * @return int
 * @throws ArithmeticException One or both of the given numbers is <code>null</code> or 'not a number'.
 */
public static int compare(Number first, Number second) throws ArithmeticException {
    if (first == null || second == null || isNaN(first) || isNaN(second))
        throw new ArithmeticException("Arguments must not be null or NaN.");

    int result = -2;

    if (isLongCompatible(first) && isLongCompatible(second)) {
        long v1 = first.longValue(), v2 = second.longValue();
        result = v1 < v2 ? -1 : v1 == v2 ? 0 : v1 > v2 ? 1 : 2;
    } else if (isDoubleCompatible(first) && isDoubleCompatible(second)) {
        double v1 = first.doubleValue(), v2 = second.doubleValue();
        result = v1 < v2 ? -1 : v1 == v2 ? 0 : v1 > v2 ? 1 : 2;
    }

    if (result == 2) // should not happen
        throw new ArithmeticException("Arguments " + first + " and " + second + " are not comparable.");
    if (result > -2)
        return result;

    if (isInfinite(first)) // => second is finite
        return first.doubleValue() == Double.NEGATIVE_INFINITY ? -1 : 1;
    if (isInfinite(second)) // => first is finite
        return second.doubleValue() == Double.POSITIVE_INFINITY ? -1 : 1;

    return toBigDecimal(first).compareTo(toBigDecimal(second));
}