Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C98EFDFF7 for ; Thu, 16 Aug 2012 10:08:14 +0000 (UTC) Received: (qmail 23026 invoked by uid 500); 16 Aug 2012 10:08:14 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 22966 invoked by uid 500); 16 Aug 2012 10:08:14 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 22956 invoked by uid 99); 16 Aug 2012 10:08:13 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 16 Aug 2012 10:08:13 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 16 Aug 2012 10:08:10 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 91EB22388900 for ; Thu, 16 Aug 2012 10:07:26 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1373779 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java Date: Thu, 16 Aug 2012 10:07:26 -0000 To: commits@commons.apache.org From: luc@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120816100726.91EB22388900@eris.apache.org> Author: luc Date: Thu Aug 16 10:07:26 2012 New Revision: 1373779 URL: http://svn.apache.org/viewvc?rev=1373779&view=rev Log: Added getExponent, scalb and hypot to DerivativeStructure. Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java?rev=1373779&r1=1373778&r2=1373779&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java Thu Aug 16 10:07:26 2012 @@ -402,6 +402,90 @@ public class DerivativeStructure impleme return negate(); // flip sign } + /** + * Return the exponent of the instance value, removing the bias. + *

+ * For double numbers of the form 2x, the unbiased + * exponent is exactly x. + *

+ * @return exponent for instance in IEEE754 representation, without bias + */ + public int getExponent() { + return FastMath.getExponent(data[0]); + } + + /** + * Multiply the instance by a power of 2. + * @param n power of 2 + * @return this × 2n + */ + public DerivativeStructure scalb(final int n) { + final DerivativeStructure ds = new DerivativeStructure(compiler); + for (int i = 0; i < ds.data.length; ++i) { + ds.data[i] = FastMath.scalb(data[i], n); + } + return ds; + } + + /** + * Returns the hypotenuse of a triangle with sides {@code x} and {@code y} + * - sqrt(x2 +y2)
+ * avoiding intermediate overflow or underflow. + * + *
    + *
  • If either argument is infinite, then the result is positive infinity.
  • + *
  • else, if either argument is NaN then the result is NaN.
  • + *
+ * + * @param x a value + * @param y a value + * @return sqrt(x2 +y2) + * @exception DimensionMismatchException if number of free parameters or orders are inconsistent + */ + public static DerivativeStructure hypot(final DerivativeStructure x, final DerivativeStructure y) + throws DimensionMismatchException { + + x.compiler.checkCompatibility(y.compiler); + + if (Double.isInfinite(x.data[0]) || Double.isInfinite(y.data[0])) { + return new DerivativeStructure(x.compiler.getFreeParameters(), + x.compiler.getFreeParameters(), + Double.POSITIVE_INFINITY); + } else if (Double.isNaN(x.data[0]) || Double.isNaN(y.data[0])) { + return new DerivativeStructure(x.compiler.getFreeParameters(), + x.compiler.getFreeParameters(), + Double.NaN); + } else { + + final int expX = x.getExponent(); + final int expY = y.getExponent(); + if (expX > expY + 27) { + // y is neglectible with respect to x + return x.abs(); + } else if (expY > expX + 27) { + // x is neglectible with respect to y + return y.abs(); + } else { + + // find an intermediate scale to avoid both overflow and underflow + final int middleExp = (expX + expY) / 2; + + // scale parameters without losing precision + final DerivativeStructure scaledX = x.scalb(-middleExp); + final DerivativeStructure scaledY = y.scalb(-middleExp); + + // compute scaled hypotenuse + final DerivativeStructure scaledH = + scaledX.multiply(scaledX).add(scaledY.multiply(scaledY)).sqrt(); + + // remove scaling + return scaledH.scalb(middleExp); + + } + + } + } + /** {@inheritDoc} */ public DerivativeStructure reciprocal() { final DerivativeStructure result = new DerivativeStructure(compiler); Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java?rev=1373779&r1=1373778&r2=1373779&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java Thu Aug 16 10:07:26 2012 @@ -404,6 +404,44 @@ public class DerivativeStructureTest { } @Test + public void testHypotDefinition() { + double epsilon = 1.0e-20; + for (int maxOrder = 0; maxOrder < 5; ++maxOrder) { + for (double x = -1.7; x < 2; x += 0.2) { + DerivativeStructure dsX = new DerivativeStructure(2, maxOrder, 0, x); + for (double y = -1.7; y < 2; y += 0.2) { + DerivativeStructure dsY = new DerivativeStructure(2, maxOrder, 1, y); + DerivativeStructure hypot = DerivativeStructure.hypot(dsY, dsX); + DerivativeStructure ref = dsX.multiply(dsX).add(dsY.multiply(dsY)).sqrt(); + DerivativeStructure zero = hypot.subtract(ref); + for (int n = 0; n <= maxOrder; ++n) { + for (int m = 0; m <= maxOrder; ++m) { + if (n + m <= maxOrder) { + Assert.assertEquals(0, zero.getPartialDerivative(n, m), epsilon); + } + } + } + } + } + } + } + + @Test + public void testHypotNoOverflow() { + + DerivativeStructure dsX = new DerivativeStructure(2, 5, 0, +3.0e250); + DerivativeStructure dsY = new DerivativeStructure(2, 5, 1, -4.0e250); + DerivativeStructure hypot = DerivativeStructure.hypot(dsX, dsY); + Assert.assertEquals(5.0e250, hypot.getValue(), 1.0e235); + Assert.assertEquals(dsX.getValue() / hypot.getValue(), hypot.getPartialDerivative(1, 0), 1.0e-10); + Assert.assertEquals(dsY.getValue() / hypot.getValue(), hypot.getPartialDerivative(0, 1), 1.0e-10); + + DerivativeStructure sqrt = dsX.multiply(dsX).add(dsY.multiply(dsY)).sqrt(); + Assert.assertTrue(Double.isInfinite(sqrt.getValue())); + + } + + @Test public void testExp() { double[] epsilon = new double[] { 1.0e-16, 1.0e-16, 1.0e-16, 1.0e-16, 1.0e-16 }; for (int maxOrder = 0; maxOrder < 5; ++maxOrder) {