Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -66,6 +66,9 @@ strictfp class MapProjectionTestCase ext final Ellipsoid ellipsoid = (ellipse ? GeodeticDatumMock.WGS84 : GeodeticDatumMock.SPHERE).getEllipsoid(); parameters.parameter(Constants.SEMI_MAJOR).setValue(ellipsoid.getSemiMajorAxis()); parameters.parameter(Constants.SEMI_MINOR).setValue(ellipsoid.getSemiMinorAxis()); + if (ellipse) { + parameters.parameter(Constants.INVERSE_FLATTENING).setValue(ellipsoid.getInverseFlattening()); + } return parameters; }
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -65,16 +65,17 @@ public final strictfp class MercatorTest /** * Tests the WKT formatting of {@link NormalizedProjection}. For the Mercator projection, we expect only - * the semi-major and semi-minor axis length. We expect nothing else because all other parameters are used + * the ellipsoid excentricity. We expect nothing else because all other parameters are used * by the (de)normalization affine transforms instead than the {@link Mercator} class itself. + * + * @see LambertConicConformalTest#testNormalizedWKT() */ @Test public void testNormalizedWKT() { createNormalizedProjection(true); assertWktEquals( - "PARAM_MT[“Mercator_2SP”,\n" + - " PARAMETER[“semi_major”, 1.0],\n" + - " PARAMETER[“semi_minor”, 0.9966471893352525]]"); + "PARAM_MT[“Mercator”,\n" + + " PARAMETER[“excentricity”, 0.0818191908426215]]"); } /** Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NoOp.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -46,7 +46,17 @@ final strictfp class NoOp extends Confor * @param ellipsoidal {@code true} for an ellipsoidal case, or {@code false} for a spherical case. */ NoOp(final boolean ellipsoidal) { - this(parameters((ellipsoidal ? GeodeticDatumMock.WGS84 : GeodeticDatumMock.SPHERE).getEllipsoid())); + this(ellipsoidal, ellipsoidal); + } + + /** + * Creates a new "no-operation". + * + * @param ellipsoidal {@code true} for an ellipsoidal case, or {@code false} for a spherical case. + * @param declareIvf {@code true} for declaring the inverse flattening factor. + */ + NoOp(final boolean ellipsoidal, final boolean declareIvf) { + this(parameters((ellipsoidal ? GeodeticDatumMock.WGS84 : GeodeticDatumMock.SPHERE).getEllipsoid(), declareIvf)); } /** @@ -62,10 +72,9 @@ final strictfp class NoOp extends Confor */ @Workaround(library="JDK", version="1.7") private NoOp(final Parameters parameters) { - super(new DefaultOperationMethod( + super(new Initializer(new DefaultOperationMethod( Collections.singletonMap(DefaultOperationMethod.NAME_KEY, parameters.getDescriptor().getName()), - 2, 2, parameters.getDescriptor()), parameters, - Collections.<ParameterRole, ParameterDescriptor<Double>>emptyMap()); + 2, 2, parameters.getDescriptor()), parameters, Collections.<ParameterRole, ParameterDescriptor<Double>>emptyMap(), (byte) 0)); } /** @@ -73,9 +82,14 @@ final strictfp class NoOp extends Confor * ("Relax constraint on placement of this()/super() call in constructors"). */ @Workaround(library="JDK", version="1.7") - private static Parameters parameters(final Ellipsoid ellipsoid) { - return parameters(ellipsoid.getSemiMajorAxis(), - ellipsoid.getSemiMinorAxis()); + private static Parameters parameters(final Ellipsoid ellipsoid, final boolean declareIvf) { + final Parameters parameters = parameters( + ellipsoid.getSemiMajorAxis(), + ellipsoid.getSemiMinorAxis()); + if (declareIvf) { + parameters.parameter(Constants.INVERSE_FLATTENING).setValue(ellipsoid.getInverseFlattening()); + } + return parameters; } /** Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -68,8 +68,17 @@ public final strictfp class NormalizedPr NormalizedProjection projection; transform = projection = new NoOp(false); assertEquals("excentricity", 0.0, projection.excentricity, 0.0); + /* + * Tested methods. Note the similarity between (1) and (3). + * + * (1) Using double arithmetic and axis lengths: 0.08181919084262157 + * (2) Using double-double arithmetic and axis lengths: 0.08181919084262244 + * (3) Using double-double arithmetic and flattening: 0.0818191908426215 + */ + transform = projection = new NoOp(true, false); + assertEquals("excentricity", 0.08181919084262244, projection.excentricity, 0.0); - transform = projection = new NoOp(true); - assertEquals("excentricity", 0.08181919084262157, projection.excentricity, TOLERANCE); + transform = projection = new NoOp(true, true); + assertEquals("excentricity", 0.0818191908426215, projection.excentricity, 0.0); } } Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera import java.util.Arrays; import java.util.List; import org.opengis.parameter.ParameterValueGroup; +import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.Matrix; import org.apache.sis.internal.referencing.Formulas; @@ -170,6 +171,15 @@ final strictfp class ProjectionResultCom } /** + * Delegates to the {@link #tested} implementation. + */ + @Debug + @Override + public ParameterDescriptorGroup getParameterDescriptors() { + return tested.getParameterDescriptors(); + } + + /** * Delegates to the {@link #tested} implementation. */ @Debug Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -370,6 +370,20 @@ public abstract strictfp class MathTrans } /** + * Asserts that the current {@linkplain #transform transform} produces a WKT matching the given regular expression. + * + * @param expected A regular expression for the expected WKT. + * + * @see #printInternalWKT() + * + * @since 0.6 + */ + protected final void assertWktEqualsRegex(final String expected) { + assertNotNull("The 'transform' field shall be assigned a value.", transform); + ReferencingAssert.assertWktEqualsRegex(Convention.WKT1, expected, transform); + } + + /** * Prints the current {@linkplain #transform transform} as normal and internal WKT. * This method is for debugging purpose only. * @@ -377,6 +391,7 @@ public abstract strictfp class MathTrans */ @Debug protected final void printInternalWKT() { + @SuppressWarnings("UseOfSystemOutOrSystemErr") final TableAppender table = new TableAppender(System.out); table.setMultiLinesCells(true); table.appendHorizontalSeparator(); Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -103,7 +103,7 @@ import org.junit.BeforeClass; org.apache.sis.referencing.operation.projection.EquirectangularTest.class, org.apache.sis.referencing.operation.projection.ConformalProjectionTest.class, org.apache.sis.referencing.operation.projection.MercatorTest.class, - org.apache.sis.referencing.operation.projection.LambertConformalTest.class, + org.apache.sis.referencing.operation.projection.LambertConicConformalTest.class, org.apache.sis.referencing.operation.projection.TransverseMercatorTest.class, org.apache.sis.referencing.operation.projection.PolarStereographicTest.class, Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -203,10 +203,10 @@ public class SimpleIdentifiedObject impl } if (object instanceof IdentifiedObject) { if (mode != ComparisonMode.STRICT || object.getClass() == getClass()) { - final IdentifiedObject that = (IdentifiedObject) object; - if (mode.ordinal() >= ComparisonMode.IGNORE_METADATA.ordinal()) { + if (mode.isIgnoringMetadata()) { return true; } + final IdentifiedObject that = (IdentifiedObject) object; return Objects.equals(getName(), that.getName()) && isNullOrEmpty(that.getIdentifiers()) && isNullOrEmpty(that.getAlias()) && Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -20,6 +20,7 @@ import java.util.Map; import java.util.IdentityHashMap; import java.util.ServiceLoader; import java.util.ServiceConfigurationError; +import org.apache.sis.internal.util.Utilities; /** @@ -86,8 +87,7 @@ public final class DefaultFactories exte if (factory == null && !FACTORIES.containsKey(type)) { T fallback = null; for (final T candidate : ServiceLoader.load(type)) { - final Class<?> ct = candidate.getClass(); - if (ct.getName().startsWith("org.apache.sis.")) { + if (Utilities.isSIS(candidate.getClass())) { if (factory != null) { throw new ServiceConfigurationError("Found two implementations of " + type); } Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -78,17 +78,34 @@ public final class Constants extends Sta public static final byte CRS84 = 84; /** + * The NetCDF parameter name for the Earth radius. + */ + public static final String EARTH_RADIUS = "earth_radius"; + + /** * Name of the {@value} projection parameter, which is handled specially during WKT formatting. */ public static final String SEMI_MAJOR = "semi_major", SEMI_MINOR = "semi_minor"; /** + * The NetCDF parameter name for inverse flattening, and whether that parameter is definitive. + * The later is specific to SIS. + */ + public static final String INVERSE_FLATTENING = "inverse_flattening", + IS_IVF_DEFINITIVE = "is_ivf_definitive"; + + /** * The OGC parameter name for the central meridian. */ public static final String CENTRAL_MERIDIAN = "central_meridian"; /** + * The NetCDF parameter name for the standard parallels. + */ + public static final String STANDARD_PARALLEL = "standard_parallel"; + + /** * The OGC parameter name for the standard parallels. */ public static final String STANDARD_PARALLEL_1 = "standard_parallel_1", @@ -125,6 +142,7 @@ public final class Constants extends Sta */ public static final String FALSE_EASTING = "false_easting", FALSE_NORTHING = "false_northing"; + /** * Name of the {@value} matrix parameters. */ Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -237,6 +237,20 @@ public final class DoubleDouble extends } /** + * Uses the given value verbatim, without inferring an error term for double-double arithmetic. + * We use this method when the value has been computed using transcendental functions (cosine, + * logarithm, <i>etc.</i>) in which case there is no way we can infer a meaningful error term. + * + * <p>We use this method both for readability and for making easier to search where such thing occur.</p> + * + * @param value The value to wrap in a {@code DoubleDouble} instance. + * @return A {@code DoubleDouble} containing exactly the given value, without error term. + */ + public static DoubleDouble verbatim(final double value) { + return new DoubleDouble(value, 0); + } + + /** * Returns a new {@code DoubleDouble} instance initialized to the conversion factor * from radians to angular degrees. * @@ -921,6 +935,24 @@ public final class DoubleDouble extends } /** + * Computes (1-x)/(1+x) where <var>x</var> is {@code this}. + * This pattern occurs in map projections. + */ + public void ratio_1m_1p() { + final DoubleDouble numerator = new DoubleDouble(1, 0); + numerator.subtract(this); + add(1, 0); + inverseDivide(numerator); + } + + /** + * Computes the square of this value. + */ + public void square() { + multiply(value, error); + } + + /** * Sets this double-double value to its square root. * * <div class="section">Implementation</div> @@ -943,13 +975,41 @@ public final class DoubleDouble extends * <blockquote>ε ≈ (value + error - r²) / (2r)</blockquote> */ public void sqrt() { - final double thisValue = this.value; - final double thisError = this.error; - double r = Math.sqrt(thisValue); - setToProduct(r, r); - subtract(thisValue, thisError); - divide(-2*r, 0); // Multiplication by 2 does not cause any precision lost. - setToQuickSum(r, value); + if (value != 0) { + final double thisValue = this.value; + final double thisError = this.error; + double r = Math.sqrt(thisValue); + setToProduct(r, r); + subtract(thisValue, thisError); + divide(-2*r, 0); // Multiplication by 2 does not cause any precision lost. + setToQuickSum(r, value); + } + } + + /** + * Computes c₀ + c₁x + c₂x² + c₃x³ + c₄x⁴ + … where <var>x</var> is {@code this}. + * The given <var>c</var> coefficients are presumed accurate in base 2 + * (i.e. this method does not try to apply a correction for base 10). + * + * @param coefficients The {@code c} coefficients. The array length must be at least 1. + */ + public void series(final double... coefficients) { + final DoubleDouble x = new DoubleDouble(this); + value = coefficients[0]; + error = 0; + final int last = coefficients.length - 1; + if (last >= 1) { + final DoubleDouble xn = new DoubleDouble(x); + final DoubleDouble t = new DoubleDouble(xn); + for (int i=1; i<last; i++) { + t.multiply(coefficients[i], 0); + add(t); + xn.multiply(x); + t.setFrom(xn); + } + t.multiply(coefficients[last], 0); + add(t); + } } /** Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -18,6 +18,7 @@ package org.apache.sis.internal.util; import java.util.Map; import java.util.HashMap; +import org.apache.sis.util.Debug; import org.apache.sis.util.Static; import org.apache.sis.util.ComparisonMode; @@ -30,7 +31,7 @@ import static java.lang.Math.abs; * * @author Martin Desruisseaux (Geomatys) * @since 0.3 - * @version 0.4 + * @version 0.6 * @module */ public final class Numerics extends Static { @@ -58,9 +59,9 @@ public final class Numerics extends Stat * Helper method for the construction of the {@link #CACHE} map. */ private static void cache(final double value) { - Double key; - key = Double.valueOf( value); CACHE.put(key, key); - key = Double.valueOf(-value); CACHE.put(key, key); + Double boxed; + boxed = value; CACHE.put(boxed, boxed); + boxed = -value; CACHE.put(boxed, boxed); } /** @@ -146,9 +147,9 @@ public final class Numerics extends Stat * @return The given value as a {@code Double}. */ public static Double valueOf(final double value) { - final Double n = Double.valueOf(value); - final Object candidate = CACHE.get(value); - return (candidate != null) ? (Double) candidate : n; + final Double boxed = value; + final Object candidate = CACHE.get(boxed); + return (candidate != null) ? (Double) candidate : boxed; } /** @@ -188,14 +189,14 @@ public final class Numerics extends Stat * Returns {@code true} if the given floats are equals. Positive and negative zero are * considered different, while a NaN value is considered equal to all other NaN values. * - * @param o1 The first value to compare. - * @param o2 The second value to compare. + * @param v1 The first value to compare. + * @param v2 The second value to compare. * @return {@code true} if both values are equal. * * @see Float#equals(Object) */ - public static boolean equals(final float o1, final float o2) { - return Float.floatToIntBits(o1) == Float.floatToIntBits(o2); + public static boolean equals(final float v1, final float v2) { + return Float.floatToIntBits(v1) == Float.floatToIntBits(v2); } /** @@ -203,78 +204,86 @@ public final class Numerics extends Stat * Positive and negative zeros are considered different. * NaN values are considered equal to all other NaN values. * - * @param o1 The first value to compare. - * @param o2 The second value to compare. + * @param v1 The first value to compare. + * @param v2 The second value to compare. * @return {@code true} if both values are equal. * * @see Double#equals(Object) */ - public static boolean equals(final double o1, final double o2) { - return Double.doubleToLongBits(o1) == Double.doubleToLongBits(o2); + public static boolean equals(final double v1, final double v2) { + return Double.doubleToLongBits(v1) == Double.doubleToLongBits(v2); } /** * Returns {@code true} if the given doubles are equal, ignoring the sign of zero values. * NaN values are considered equal to all other NaN values. * - * @param o1 The first value to compare. - * @param o2 The second value to compare. + * @param v1 The first value to compare. + * @param v2 The second value to compare. * @return {@code true} if both values are equal. */ - public static boolean equalsIgnoreZeroSign(final double o1, final double o2) { - return (o1 == o2) || Double.doubleToLongBits(o1) == Double.doubleToLongBits(o2); + public static boolean equalsIgnoreZeroSign(final double v1, final double v2) { + return (v1 == v2) || Double.doubleToLongBits(v1) == Double.doubleToLongBits(v2); } /** - * Returns {@code true} if the given values are approximatively equal, - * up to the {@linkplain #COMPARISON_THRESHOLD comparison threshold}. + * Returns {@code true} if the given values are approximatively equal, up to the given comparison threshold. * * @param v1 The first value to compare. * @param v2 The second value to compare. - * @return {@code true} If both values are approximatively equal. + * @param threshold The comparison threshold. + * @return {@code true} if both values are approximatively equal. */ - public static boolean epsilonEqual(final double v1, final double v2) { - final double threshold = COMPARISON_THRESHOLD * max(abs(v1), abs(v2)); - if (threshold == Double.POSITIVE_INFINITY || Double.isNaN(threshold)) { - return Double.doubleToLongBits(v1) == Double.doubleToLongBits(v2); - } - return abs(v1 - v2) <= threshold; + public static boolean epsilonEqual(final double v1, final double v2, final double threshold) { + return (abs(v1 - v2) <= threshold) || equals(v1, v2); } /** * Returns {@code true} if the given values are approximatively equal given the comparison mode. + * In mode {@code APPROXIMATIVE} or {@code DEBUG}, this method will compute a relative comparison + * threshold from the {@link #COMPARISON_THRESHOLD} constant. * - * @param v1 The first value to compare. - * @param v2 The second value to compare. + * <p>This method does not thrown {@link AssertionError} in {@link ComparisonMode#DEBUG}. + * It is caller responsibility to handle the {@code DEBUG} case.</p> + * + * @param v1 The first value to compare. + * @param v2 The second value to compare. * @param mode The comparison mode to use for comparing the numbers. - * @return {@code true} If both values are approximatively equal. + * @return {@code true} if both values are considered equal for the given comparison mode. */ public static boolean epsilonEqual(final double v1, final double v2, final ComparisonMode mode) { - switch (mode) { - default: return equals(v1, v2); - case APPROXIMATIVE: return epsilonEqual(v1, v2); - case DEBUG: { - final boolean equal = epsilonEqual(v1, v2); - assert equal : "v1=" + v1 + " v2=" + v2 + " Δv=" + abs(v1-v2); - return equal; + if (mode.isApproximative()) { + final double mg = max(abs(v1), abs(v2)); + if (mg != Double.POSITIVE_INFINITY) { + return epsilonEqual(v1, v2, COMPARISON_THRESHOLD * mg); } } + return equals(v1, v2); } /** - * Returns {@code true} if the following objects are floating point numbers ({@link Float} or - * {@link Double} types) and approximatively equal. If the given object are not floating point - * numbers, then this method returns {@code false} unconditionally on the assumption that - * strict equality has already been checked before this method call. + * Creates a messages to put in {@link AssertionError} when two values differ in an unexpected way. + * This is a helper method for debugging purpose only, typically used with {@code assert} statements. * - * @param v1 The first value to compare. - * @param v2 The second value to compare. - * @return {@code true} If both values are real number and approximatively equal. + * @param name The name of the property which differ, or {@code null} if unknown. + * @param v1 The first value. + * @param v2 The second value. + * @return The message to put in {@code AssertionError}. + * + * @since 0.6 */ - public static boolean floatEpsilonEqual(final Object v1, final Object v2) { - return (v1 instanceof Float || v1 instanceof Double) && - (v2 instanceof Float || v2 instanceof Double) && - epsilonEqual(((Number) v1).doubleValue(), ((Number) v2).doubleValue()); + @Debug + public static String messageForDifference(final String name, final double v1, final double v2) { + final StringBuilder builder = new StringBuilder(); + if (name != null) { + builder.append(name).append(": "); + } + builder.append("values ").append(v1).append(" and ").append(v2).append(" differ"); + final float delta = (float) abs(v1 - v2); + if (delta < Float.POSITIVE_INFINITY) { + builder.append(" by ").append(delta); + } + return builder.toString(); } /** Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -39,6 +39,16 @@ public final class Utilities extends Sta } /** + * Returns {@code true} if the given class is an Apache SIS class. + * + * @param type The class to verify. + * @return {@code true} if the given class is an Apache SIS class. + */ + public static boolean isSIS(final Class<?> type) { + return type.getName().startsWith("org.apache.sis."); + } + + /** * Appends to the given buffer only the characters that are valid for a Unicode identifier. * The given separator character is append before the given {@code text} only if the buffer * is not empty and at least one {@code text} character is valid. Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -41,7 +41,7 @@ package org.apache.sis.util; * * @author Martin Desruisseaux (Geomatys) * @since 0.3 - * @version 0.3 + * @version 0.6 * @module * * @see LenientComparable#equals(Object, ComparisonMode) @@ -152,6 +152,32 @@ public enum ComparisonMode { DEBUG; /** + * Returns {@code true} if this comparison ignores metadata. + * This method currently returns {@code true} for {@code IGNORE_METADATA}, {@code APPROXIMATIVE} + * or {@code DEBUG} only, but this list may be extended in future SIS versions. + * + * @return Whether this comparison ignore metadata. + * + * @since 0.6 + */ + public boolean isIgnoringMetadata() { + return ordinal() >= IGNORE_METADATA.ordinal(); + } + + /** + * Returns {@code true} if this comparison uses a tolerance threshold. + * This method currently returns {@code true} for {@code APPROXIMATIVE} or {@code DEBUG} only, + * but this list may be extended in future SIS versions. + * + * @return Whether this comparison uses a tolerance threshold. + * + * @since 0.6 + */ + public boolean isApproximative() { + return ordinal() >= APPROXIMATIVE.ordinal(); + } + + /** * If the two given objects are equals according one of the modes enumerated in this class, * then returns that mode. Otherwise returns {@code null}. This method is used mostly for * diagnostic purpose. Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -43,6 +43,10 @@ import static java.lang.Double.doubleToL * * @see org.apache.sis.math.MathFunctions */ +@SuppressWarnings({ + "UnnecessaryBoxing", + "ResultOfObjectAllocationIgnored" +}) public final class Numbers extends Static { /** * Constant of value {@value} used in {@code switch} statements or as index in arrays. @@ -88,6 +92,7 @@ public final class Numbers extends Stati /** * Creates an entry for a type which is not a primitive type. */ + @SuppressWarnings("ThisEscapedInObjectConstruction") private Numbers(final Class<?> type, final boolean isFloat, final boolean isInteger, final byte ordinal) { primitive = wrapper = type; this.isFloat = isFloat; @@ -104,6 +109,7 @@ public final class Numbers extends Stati /** * Creates a mapping between a primitive type and its wrapper. */ + @SuppressWarnings("ThisEscapedInObjectConstruction") private Numbers(final Class<?> primitive, final Class<?> wrapper, final boolean isFloat, final boolean isInteger, final byte size, final byte ordinal, Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -179,7 +179,7 @@ final class NilObjectHandler implements if (other == proxy) return true; if (other == null) return false; if (proxy.getClass() == other.getClass()) { - if (mode.ordinal() >= ComparisonMode.IGNORE_METADATA.ordinal()) { + if (mode.isIgnoringMetadata()) { return true; } final NilObjectHandler h = (NilObjectHandler) Proxy.getInvocationHandler(other); Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -250,6 +250,17 @@ public final strictfp class DoubleDouble } /** + * Tests {@link DoubleDouble#ratio_1m_1p()}. + */ + @Test + @DependsOnMethod("testDivide") + public void testRatio_1m_1p() { + final DoubleDouble t = new DoubleDouble(0.25, 0); + t.ratio_1m_1p(); + assertEquals((1 - 0.25) / (1 + 0.25), t.doubleValue(), STRICT); + } + + /** * Tests {@link DoubleDouble#sqrt()} first with the square root of 2, then with random values. * In the {@code sqrt(2)} case: * @@ -278,11 +289,25 @@ public final strictfp class DoubleDouble } final double value = dd.value; final double error = dd.error; - dd.multiply(dd); + dd.square(); dd.sqrt(); dd.subtract(value, error); assertEquals(0, dd.doubleValue(), 1E-29); } + dd.clear(); + dd.sqrt(); + assertTrue(dd.isZero()); + } + + /** + * Tests the {@link DoubleDouble#series(double...)} method. + */ + @Test + @DependsOnMethod({"testMultiply", "testAdd"}) + public void testSeries() { + final DoubleDouble t = new DoubleDouble(2); + t.series(1, 1./3, 1./9, 1./7, 1./13); // Random coefficient. + assertEquals(1 + 2./3 + 4./9 + 8./7 + 16./13, t.doubleValue(), STRICT); } /** Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -20,6 +20,7 @@ import java.util.Random; import org.apache.sis.math.MathFunctions; import org.apache.sis.test.TestUtilities; import org.apache.sis.test.TestCase; +import org.apache.sis.util.ComparisonMode; import org.junit.Test; import static java.lang.Double.NaN; @@ -34,9 +35,10 @@ import static org.junit.Assert.*; * * @author Martin Desruisseaux (Geomatys) * @since 0.3 - * @version 0.4 + * @version 0.6 * @module */ +@SuppressWarnings("UnnecessaryBoxing") public final strictfp class NumericsTest extends TestCase { /** * Tests the {@link Numerics#cached(Object)} method. @@ -67,20 +69,20 @@ public final strictfp class NumericsTest } /** - * Tests the {@link Numerics#epsilonEqual(double, double)} method. + * Tests the {@link Numerics#epsilonEqual(double, double, ComparisonMode)} method. */ @Test public void testEpsilonEqual() { - assertTrue (epsilonEqual(POSITIVE_INFINITY, POSITIVE_INFINITY)); - assertTrue (epsilonEqual(NEGATIVE_INFINITY, NEGATIVE_INFINITY)); - assertFalse(epsilonEqual(POSITIVE_INFINITY, NEGATIVE_INFINITY)); - assertFalse(epsilonEqual(POSITIVE_INFINITY, NaN)); - assertTrue (epsilonEqual(NaN, NaN)); - assertFalse(epsilonEqual( 0, COMPARISON_THRESHOLD / 2)); - assertTrue (epsilonEqual( 1, 1 + COMPARISON_THRESHOLD / 2)); - assertFalse(epsilonEqual( 1, 1 + COMPARISON_THRESHOLD * 2)); - assertTrue (epsilonEqual(-100, -100 + COMPARISON_THRESHOLD * 50)); - assertFalse(epsilonEqual( 100, 100 + COMPARISON_THRESHOLD * 150)); + assertTrue (epsilonEqual(POSITIVE_INFINITY, POSITIVE_INFINITY, ComparisonMode.APPROXIMATIVE)); + assertTrue (epsilonEqual(NEGATIVE_INFINITY, NEGATIVE_INFINITY, ComparisonMode.APPROXIMATIVE)); + assertFalse(epsilonEqual(POSITIVE_INFINITY, NEGATIVE_INFINITY, ComparisonMode.APPROXIMATIVE)); + assertFalse(epsilonEqual(POSITIVE_INFINITY, NaN, ComparisonMode.APPROXIMATIVE)); + assertTrue (epsilonEqual(NaN, NaN, ComparisonMode.APPROXIMATIVE)); + assertFalse(epsilonEqual( 0, COMPARISON_THRESHOLD / 2, ComparisonMode.APPROXIMATIVE)); + assertTrue (epsilonEqual( 1, 1 + COMPARISON_THRESHOLD / 2, ComparisonMode.APPROXIMATIVE)); + assertFalse(epsilonEqual( 1, 1 + COMPARISON_THRESHOLD * 2, ComparisonMode.APPROXIMATIVE)); + assertTrue (epsilonEqual(-100, -100 + COMPARISON_THRESHOLD * 50, ComparisonMode.APPROXIMATIVE)); + assertFalse(epsilonEqual( 100, 100 + COMPARISON_THRESHOLD * 150, ComparisonMode.APPROXIMATIVE)); } /** Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestCase.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestCase.java?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestCase.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestCase.java [UTF-8] Mon Aug 3 14:25:01 2015 @@ -24,7 +24,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; -import org.apache.sis.internal.system.Modules; import org.apache.sis.util.logging.Logging; import org.junit.runner.RunWith; @@ -182,6 +181,7 @@ public abstract strictfp class TestCase * * @param success {@code true} if this method is invoked on build success, */ + @SuppressWarnings("UseOfSystemOutOrSystemErr") static void flushOutput() { System.out.flush(); System.err.flush(); Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties?rev=1693908&r1=1693907&r2=1693908&view=diff ============================================================================== --- sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] (original) +++ sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] Mon Aug 3 14:25:01 2015 @@ -80,7 +80,7 @@ project.GeoAPI = ../../../../GeoAP unit-api.version = 0.6.1 jsr275.version = 0.9.3 jama.version = 1.0.3 -geometry.version = 1.1.1 +geometry.version = 1.2 georss.version = 0.9.8 rome.version = 0.9 jdom1.version = 1.0
