You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2013/02/24 20:13:17 UTC

svn commit: r1449529 [1/5] - in /commons/proper/math/trunk/src: changes/ main/java/org/apache/commons/math3/ main/java/org/apache/commons/math3/analysis/differentiation/ main/java/org/apache/commons/math3/dfp/ main/java/org/apache/commons/math3/geometr...

Author: luc
Date: Sun Feb 24 19:13:17 2013
New Revision: 1449529

URL: http://svn.apache.org/r1449529
Log:
Added a new ExtendedFieldElement interface.

This interface represents anything that is real number like. It is
implemented by Decimal64, Dfp and DerivativeStructure. The purpose of
this interface is to be able to set up general algorithms that apply on
real numbers (maybe complex too) and use genericity.

A first use case corresponds to 3D geometry objects (Vector3D and
Rotation).

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ExtendedFieldElement.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/FieldRotation.java   (contents, props changed)
      - copied, changed from r1449528, commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/RotationDS.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/FieldVector3D.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/threed/FieldRotationDSTest.java   (contents, props changed)
      - copied, changed from r1449528, commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/threed/RotationDSTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/threed/FieldRotationDfpTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/threed/FieldVector3DTest.java   (contents, props changed)
      - copied, changed from r1449528, commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/threed/Vector3DDSTest.java
Removed:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/RotationDS.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/Vector3DDS.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/threed/RotationDSTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/threed/Vector3DDSTest.java
Modified:
    commons/proper/math/trunk/src/changes/changes.xml
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/Dfp.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/DfpDec.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Decimal64.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/MathArrays.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/dfp/DfpTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/MathArraysTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/MathUtilsTest.java

Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1449529&r1=1449528&r2=1449529&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Sun Feb 24 19:13:17 2013
@@ -56,9 +56,13 @@ This is a minor release: It combines bug
   way such as to allow drop-in replacement of the v3.1[.1] JAR file.
 ">
       <action dev="luc" type="add" >
+        Added ExtendFieldElement interface to represent anything that is
+        real number like, implemented by both Decimal64, Dfp and DerivativeStructure.  
+      </action>
+      <action dev="luc" type="add" >
         Added partial derivatives computation for 3D vectors and rotations.  
       </action>
-        <action dev="luc" type="fix" issue="MATH-935" >
+      <action dev="luc" type="fix" issue="MATH-935" >
         Fixed DerivativeStructure.atan2 for special cases when both arguments are +/-0.
       </action>
       <action dev="luc" type="add" >

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ExtendedFieldElement.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ExtendedFieldElement.java?rev=1449529&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ExtendedFieldElement.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ExtendedFieldElement.java Sun Feb 24 19:13:17 2013
@@ -0,0 +1,490 @@
+package org.apache.commons.math3;
+
+import org.apache.commons.math3.exception.DimensionMismatchException;
+
+/**
+ * Interface representing a <a href="http://mathworld.wolfram.com/RealNumber.html">real</a>
+ * <a href="http://mathworld.wolfram.com/Field.html">field</a>.
+ * <p>
+ * Classes implementing this interface will often be singletons.
+ * </p>
+ * @param <T> the type of the field elements
+ * @see FieldElement
+ * @version $Id$
+ * @since 3.2
+ */
+public interface ExtendedFieldElement<T> extends FieldElement<T> {
+
+    /** Get the real value of the number.
+     * @return real value
+     */
+    double getReal();
+
+    /** '+' operator.
+     * @param a right hand side parameter of the operator
+     * @return this+a
+     */
+    T add(double a);
+
+    /** '-' operator.
+     * @param a right hand side parameter of the operator
+     * @return this-a
+     */
+    T subtract(double a);
+
+    /** '&times;' operator.
+     * @param a right hand side parameter of the operator
+     * @return this&times;a
+     */
+    T multiply(double a);
+
+    /** '&divides;' operator.
+     * @param a right hand side parameter of the operator
+     * @return this&divides;a
+     */
+    T divide(double a);
+
+    /** '%' operator.
+     * @param a right hand side parameter of the operator
+     * @return this%a
+     */
+    T remainder(double a);
+
+    /** '%' operator.
+     * @param a right hand side parameter of the operator
+     * @return this%a
+     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
+     */
+    T remainder(T a)
+        throws DimensionMismatchException;
+
+    /** absolute value.
+     * @return abs(this)
+     */
+    T abs();
+
+    /** Get the smallest whole number larger than instance.
+     * @return ceil(this)
+     */
+    T ceil();
+
+    /** Get the largest whole number smaller than instance.
+     * @return floor(this)
+     */
+    T floor();
+
+    /** Get the whole number that is the nearest to the instance, or the even one if x is exactly half way between two integers.
+     * @return a double number r such that r is an integer r - 0.5 <= this <= r + 0.5
+     */
+    T rint();
+
+    /** Get the closest long to instance value.
+     * @return closest long to {@link #getValue()}
+     */
+    long round();
+
+    /** Compute the signum of the instance.
+     * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise
+     * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
+     */
+    T signum();
+
+    /**
+     * Returns the instance with the sign of the argument.
+     * A NaN {@code sign} argument is treated as positive.
+     *
+     * @param sign the sign for the returned value
+     * @return the instance with the same sign as the {@code sign} argument
+     */
+    T copySign(double sign);
+
+    /**
+     * Multiply the instance by a power of 2.
+     * @param n power of 2
+     * @return this &times; 2<sup>n</sup>
+     */
+    T scalb(int n);
+
+    /**
+     * Returns the hypotenuse of a triangle with sides {@code this} and {@code y}
+     * - sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)<br/>
+     * avoiding intermediate overflow or underflow.
+     *
+     * <ul>
+     * <li> If either argument is infinite, then the result is positive infinity.</li>
+     * <li> else, if either argument is NaN then the result is NaN.</li>
+     * </ul>
+     *
+     * @param y a value
+     * @return sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
+     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
+     */
+    T hypot(T y)
+        throws DimensionMismatchException;
+
+    /** {@inheritDoc} */
+    T reciprocal();
+
+    /** Square root.
+     * @return square root of the instance
+     */
+    T sqrt();
+
+    /** Cubic root.
+     * @return cubic root of the instance
+     */
+    T cbrt();
+
+    /** N<sup>th</sup> root.
+     * @param n order of the root
+     * @return n<sup>th</sup> root of the instance
+     */
+    T rootN(int n);
+
+    /** Power operation.
+     * @param p power to apply
+     * @return this<sup>p</sup>
+     */
+    T pow(double p);
+
+    /** Integer power operation.
+     * @param n power to apply
+     * @return this<sup>n</sup>
+     */
+    T pow(int n);
+
+    /** Power operation.
+     * @param e exponent
+     * @return this<sup>e</sup>
+     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
+     */
+    T pow(T e)
+        throws DimensionMismatchException;
+
+    /** Exponential.
+     * @return exponential of the instance
+     */
+    T exp();
+
+    /** Exponential minus 1.
+     * @return exponential minus one of the instance
+     */
+    T expm1();
+
+    /** Natural logarithm.
+     * @return logarithm of the instance
+     */
+    T log();
+
+    /** Shifted natural logarithm.
+     * @return logarithm of one plus the instance
+     */
+    T log1p();
+
+    /** Base 10 logarithm.
+     * @return base 10 logarithm of the instance
+     */
+    T log10();
+
+    /** Cosine operation.
+     * @return cos(this)
+     */
+    T cos();
+
+    /** Sine operation.
+     * @return sin(this)
+     */
+    T sin();
+
+    /** Tangent operation.
+     * @return tan(this)
+     */
+    T tan();
+
+    /** Arc cosine operation.
+     * @return acos(this)
+     */
+    T acos();
+
+    /** Arc sine operation.
+     * @return asin(this)
+     */
+    T asin();
+
+    /** Arc tangent operation.
+     * @return atan(this)
+     */
+    T atan();
+
+    /** Two arguments arc tangent operation.
+     * @param x second argument of the arc tangent
+     * @return atan2(this, x)
+     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
+     */
+    T atan2(T x)
+        throws DimensionMismatchException;
+
+    /** Hyperbolic cosine operation.
+     * @return cosh(this)
+     */
+    T cosh();
+
+    /** Hyperbolic sine operation.
+     * @return sinh(this)
+     */
+    T sinh();
+
+    /** Hyperbolic tangent operation.
+     * @return tanh(this)
+     */
+    T tanh();
+
+    /** Inverse hyperbolic cosine operation.
+     * @return acosh(this)
+     */
+    T acosh();
+
+    /** Inverse hyperbolic sine operation.
+     * @return asin(this)
+     */
+    T asinh();
+
+    /** Inverse hyperbolic  tangent operation.
+     * @return atanh(this)
+     */
+    T atanh();
+
+    /**
+     * Compute a linear combination accurately.
+     * This method computes the sum of the products
+     * <code>a<sub>i</sub> b<sub>i</sub></code> to high accuracy.
+     * It does so by using specific multiplication and addition algorithms to
+     * preserve accuracy and reduce cancellation effects.
+     * <br/>
+     * It is based on the 2005 paper
+     * <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita, Siegfried M. Rump,
+     * and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a Factors.
+     * @param b Factors.
+     * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
+     * @throws DimensionMismatchException if arrays dimensions don't match
+     * @since 3.2
+     */
+    T linearCombination(T[] a, T[] b)
+        throws DimensionMismatchException;
+
+    /**
+     * Compute a linear combination accurately.
+     * This method computes the sum of the products
+     * <code>a<sub>i</sub> b<sub>i</sub></code> to high accuracy.
+     * It does so by using specific multiplication and addition algorithms to
+     * preserve accuracy and reduce cancellation effects.
+     * <br/>
+     * It is based on the 2005 paper
+     * <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita, Siegfried M. Rump,
+     * and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a Factors.
+     * @param b Factors.
+     * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
+     * @throws DimensionMismatchException if arrays dimensions don't match
+     */
+    public T linearCombination(double[] a, T[] b)
+        throws DimensionMismatchException;
+
+    /**
+     * Compute a linear combination accurately.
+     * <p>
+     * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub>
+     * to high accuracy. It does so by using specific multiplication and
+     * addition algorithms to preserve accuracy and reduce cancellation effects.
+     * It is based on the 2005 paper <a
+     * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita,
+     * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a1 first factor of the first term
+     * @param b1 second factor of the first term
+     * @param a2 first factor of the second term
+     * @param b2 second factor of the second term
+     * @return a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub>
+     * @see #linearCombination(T, T, T, T, T, T)
+     * @see #linearCombination(T, T, T, T, T, T, T, T)
+     * @since 3.2
+     */
+    public T linearCombination(T a1, T b1, T a2, T b2);
+
+    /**
+     * Compute a linear combination accurately.
+     * <p>
+     * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub>
+     * to high accuracy. It does so by using specific multiplication and
+     * addition algorithms to preserve accuracy and reduce cancellation effects.
+     * It is based on the 2005 paper <a
+     * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita,
+     * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a1 first factor of the first term
+     * @param b1 second factor of the first term
+     * @param a2 first factor of the second term
+     * @param b2 second factor of the second term
+     * @return a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub>
+     * @see #linearCombination(double, T, double, T, double, T)
+     * @see #linearCombination(double, T, double, T, double, T, double, T)
+     * @since 3.2
+     */
+    public T linearCombination(double a1, T b1, double a2, T b2);
+
+    /**
+     * Compute a linear combination accurately.
+     * <p>
+     * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
+     * to high accuracy. It does so by using specific multiplication and
+     * addition algorithms to preserve accuracy and reduce cancellation effects.
+     * It is based on the 2005 paper <a
+     * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita,
+     * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a1 first factor of the first term
+     * @param b1 second factor of the first term
+     * @param a2 first factor of the second term
+     * @param b2 second factor of the second term
+     * @param a3 first factor of the third term
+     * @param b3 second factor of the third term
+     * @return a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
+     * @see #linearCombination(T, T, T, T)
+     * @see #linearCombination(T, T, T, T, T, T, T, T)
+     * @since 3.2
+     */
+    public T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3);
+
+    /**
+     * Compute a linear combination accurately.
+     * <p>
+     * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
+     * to high accuracy. It does so by using specific multiplication and
+     * addition algorithms to preserve accuracy and reduce cancellation effects.
+     * It is based on the 2005 paper <a
+     * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita,
+     * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a1 first factor of the first term
+     * @param b1 second factor of the first term
+     * @param a2 first factor of the second term
+     * @param b2 second factor of the second term
+     * @param a3 first factor of the third term
+     * @param b3 second factor of the third term
+     * @return a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
+     * @see #linearCombination(double, T, double, T)
+     * @see #linearCombination(double, T, double, T, double, T, double, T)
+     * @since 3.2
+     */
+    public T linearCombination(double a1, T b1,  double a2, T b2, double a3, T b3);
+
+    /**
+     * Compute a linear combination accurately.
+     * <p>
+     * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
+     * a<sub>4</sub>&times;b<sub>4</sub>
+     * to high accuracy. It does so by using specific multiplication and
+     * addition algorithms to preserve accuracy and reduce cancellation effects.
+     * It is based on the 2005 paper <a
+     * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita,
+     * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a1 first factor of the first term
+     * @param b1 second factor of the first term
+     * @param a2 first factor of the second term
+     * @param b2 second factor of the second term
+     * @param a3 first factor of the third term
+     * @param b3 second factor of the third term
+     * @param a4 first factor of the third term
+     * @param b4 second factor of the third term
+     * @return a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
+     * a<sub>4</sub>&times;b<sub>4</sub>
+     * @see #linearCombination(T, T, T, T)
+     * @see #linearCombination(T, T, T, T, T, T)
+     * @since 3.2
+     */
+    public T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3, T a4, T b4);
+
+    /**
+     * Compute a linear combination accurately.
+     * <p>
+     * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
+     * a<sub>4</sub>&times;b<sub>4</sub>
+     * to high accuracy. It does so by using specific multiplication and
+     * addition algorithms to preserve accuracy and reduce cancellation effects.
+     * It is based on the 2005 paper <a
+     * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+     * Accurate Sum and Dot Product</a> by Takeshi Ogita,
+     * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
+     * </p>
+     * <p>
+     * Note that the instance is only used as a prototype to get proper elements dimensions.
+     * Its value is not used, only the parameters values are used.
+     * </p>
+     * @param a1 first factor of the first term
+     * @param b1 second factor of the first term
+     * @param a2 first factor of the second term
+     * @param b2 second factor of the second term
+     * @param a3 first factor of the third term
+     * @param b3 second factor of the third term
+     * @param a4 first factor of the third term
+     * @param b4 second factor of the third term
+     * @return a<sub>1</sub>&times;b<sub>1</sub> +
+     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
+     * a<sub>4</sub>&times;b<sub>4</sub>
+     * @see #linearCombination(double, T, double, T)
+     * @see #linearCombination(double, T, double, T, double, T)
+     * @since 3.2
+     */
+    public T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3, double a4, T b4);
+
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ExtendedFieldElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ExtendedFieldElement.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

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=1449529&r1=1449528&r2=1449529&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 Sun Feb 24 19:13:17 2013
@@ -18,11 +18,14 @@ package org.apache.commons.math3.analysi
 
 import java.io.Serializable;
 
+import org.apache.commons.math3.ExtendedFieldElement;
 import org.apache.commons.math3.Field;
 import org.apache.commons.math3.FieldElement;
 import org.apache.commons.math3.exception.DimensionMismatchException;
 import org.apache.commons.math3.exception.NumberIsTooLargeException;
 import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.util.MathArrays;
+import org.apache.commons.math3.util.MathUtils;
 
 /** Class representing both the value and the differentials of a function.
  * <p>This class is the workhorse of the differentiation package.</p>
@@ -55,7 +58,7 @@ import org.apache.commons.math3.util.Fas
  * @version $Id$
  * @since 3.1
  */
-public class DerivativeStructure implements FieldElement<DerivativeStructure>, Serializable {
+public class DerivativeStructure implements ExtendedFieldElement<DerivativeStructure>, Serializable {
 
     /** Serializable UID. */
     private static final long serialVersionUID = 20120730L;
@@ -223,6 +226,11 @@ public class DerivativeStructure impleme
         return compiler.getOrder();
     }
 
+    /***/
+    public double getReal() {
+        return data[0];
+    }
+
     /** Get the value part of the derivative structure.
      * @return value part of the derivative structure
      * @see #getPartialDerivative(int...)
@@ -254,21 +262,14 @@ public class DerivativeStructure impleme
         return data.clone();
     }
 
-    /** '+' operator.
-     * @param a right hand side parameter of the operator
-     * @return this+a
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure add(final double a) {
         final DerivativeStructure ds = new DerivativeStructure(this);
         ds.data[0] += a;
         return ds;
     }
 
-    /** '+' operator.
-     * @param a right hand side parameter of the operator
-     * @return this+a
-     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure add(final DerivativeStructure a)
         throws DimensionMismatchException {
         compiler.checkCompatibility(a.compiler);
@@ -277,19 +278,12 @@ public class DerivativeStructure impleme
         return ds;
     }
 
-    /** '-' operator.
-     * @param a right hand side parameter of the operator
-     * @return this-a
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure subtract(final double a) {
         return add(-a);
     }
 
-    /** '-' operator.
-     * @param a right hand side parameter of the operator
-     * @return this-a
-     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure subtract(final DerivativeStructure a)
         throws DimensionMismatchException {
         compiler.checkCompatibility(a.compiler);
@@ -303,10 +297,7 @@ public class DerivativeStructure impleme
         return multiply((double) n);
     }
 
-    /** '&times;' operator.
-     * @param a right hand side parameter of the operator
-     * @return this&times;a
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure multiply(final double a) {
         final DerivativeStructure ds = new DerivativeStructure(this);
         for (int i = 0; i < ds.data.length; ++i) {
@@ -315,11 +306,7 @@ public class DerivativeStructure impleme
         return ds;
     }
 
-    /** '&times;' operator.
-     * @param a right hand side parameter of the operator
-     * @return this&times;a
-     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure multiply(final DerivativeStructure a)
         throws DimensionMismatchException {
         compiler.checkCompatibility(a.compiler);
@@ -328,10 +315,7 @@ public class DerivativeStructure impleme
         return result;
     }
 
-    /** '&divides;' operator.
-     * @param a right hand side parameter of the operator
-     * @return this&divides;a
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure divide(final double a) {
         final DerivativeStructure ds = new DerivativeStructure(this);
         for (int i = 0; i < ds.data.length; ++i) {
@@ -340,11 +324,7 @@ public class DerivativeStructure impleme
         return ds;
     }
 
-    /** '&divides;' operator.
-     * @param a right hand side parameter of the operator
-     * @return this&divides;a
-     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure divide(final DerivativeStructure a)
         throws DimensionMismatchException {
         compiler.checkCompatibility(a.compiler);
@@ -353,21 +333,14 @@ public class DerivativeStructure impleme
         return result;
     }
 
-    /** '%' operator.
-     * @param a right hand side parameter of the operator
-     * @return this%a
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure remainder(final double a) {
         final DerivativeStructure ds = new DerivativeStructure(this);
         ds.data[0] = ds.data[0] % a;
         return ds;
     }
 
-    /** '%' operator.
-     * @param a right hand side parameter of the operator
-     * @return this%a
-     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure remainder(final DerivativeStructure a)
         throws DimensionMismatchException {
         compiler.checkCompatibility(a.compiler);
@@ -376,9 +349,7 @@ public class DerivativeStructure impleme
         return result;
     }
 
-    /** unary '-' operator.
-     * @return -this
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure negate() {
         final DerivativeStructure ds = new DerivativeStructure(compiler);
         for (int i = 0; i < ds.data.length; ++i) {
@@ -387,9 +358,7 @@ public class DerivativeStructure impleme
         return ds;
     }
 
-    /** absolute value.
-     * @return abs(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure abs() {
         if (Double.doubleToLongBits(data[0]) < 0) {
             // we use the bits representation to also handle -0.0
@@ -399,57 +368,40 @@ public class DerivativeStructure impleme
         }
     }
 
-    /** Get the smallest whole number larger than instance.
-     * @return ceil(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure ceil() {
         return new DerivativeStructure(compiler.getFreeParameters(),
                                        compiler.getOrder(),
                                        FastMath.ceil(data[0]));
     }
 
-    /** Get the largest whole number smaller than instance.
-     * @return floor(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure floor() {
         return new DerivativeStructure(compiler.getFreeParameters(),
                                        compiler.getOrder(),
                                        FastMath.floor(data[0]));
     }
 
-    /** Get the whole number that is the nearest to the instance, or the even one if x is exactly half way between two integers.
-     * @return a double number r such that r is an integer r - 0.5 <= this <= r + 0.5
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure rint() {
         return new DerivativeStructure(compiler.getFreeParameters(),
                                        compiler.getOrder(),
                                        FastMath.rint(data[0]));
     }
 
-    /** Get the closest long to instance value.
-     * @return closest long to {@link #getValue()}
-     */
+    /** {@inheritDoc} */
     public long round() {
         return FastMath.round(data[0]);
     }
 
-    /** Compute the signum of the instance.
-     * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise
-     * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure signum() {
         return new DerivativeStructure(compiler.getFreeParameters(),
                                        compiler.getOrder(),
                                        FastMath.signum(data[0]));
     }
 
-    /**
-     * Returns the instance with the sign of the argument.
-     * A NaN {@code sign} argument is treated as positive.
-     *
-     * @param sign the sign for the returned value
-     * @return the instance with the same sign as the {@code sign} argument
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure copySign(final double sign){
         long m = Double.doubleToLongBits(data[0]);
         long s = Double.doubleToLongBits(sign);
@@ -471,11 +423,7 @@ public class DerivativeStructure impleme
         return FastMath.getExponent(data[0]);
     }
 
-    /**
-     * Multiply the instance by a power of 2.
-     * @param n power of 2
-     * @return this &times; 2<sup>n</sup>
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure scalb(final int n) {
         final DerivativeStructure ds = new DerivativeStructure(compiler);
         for (int i = 0; i < ds.data.length; ++i) {
@@ -484,41 +432,27 @@ public class DerivativeStructure impleme
         return ds;
     }
 
-    /**
-     * Returns the hypotenuse of a triangle with sides {@code x} and {@code y}
-     * - sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)<br/>
-     * avoiding intermediate overflow or underflow.
-     *
-     * <ul>
-     * <li> If either argument is infinite, then the result is positive infinity.</li>
-     * <li> else, if either argument is NaN then the result is NaN.</li>
-     * </ul>
-     *
-     * @param x a value
-     * @param y a value
-     * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
-     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
-     */
-    public static DerivativeStructure hypot(final DerivativeStructure x, final DerivativeStructure y)
+    /** {@inheritDoc} */
+    public DerivativeStructure hypot(final DerivativeStructure y)
         throws DimensionMismatchException {
 
-        x.compiler.checkCompatibility(y.compiler);
+        compiler.checkCompatibility(y.compiler);
 
-        if (Double.isInfinite(x.data[0]) || Double.isInfinite(y.data[0])) {
-            return new DerivativeStructure(x.compiler.getFreeParameters(),
-                                           x.compiler.getFreeParameters(),
+        if (Double.isInfinite(data[0]) || Double.isInfinite(y.data[0])) {
+            return new DerivativeStructure(compiler.getFreeParameters(),
+                                           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(),
+        } else if (Double.isNaN(data[0]) || Double.isNaN(y.data[0])) {
+            return new DerivativeStructure(compiler.getFreeParameters(),
+                                           compiler.getFreeParameters(),
                                            Double.NaN);
         } else {
 
-            final int expX = x.getExponent();
+            final int expX = getExponent();
             final int expY = y.getExponent();
             if (expX > expY + 27) {
                 // y is neglectible with respect to x
-                return x.abs();
+                return abs();
             } else if (expY > expX + 27) {
                 // x is neglectible with respect to y
                 return y.abs();
@@ -528,7 +462,7 @@ public class DerivativeStructure impleme
                 final int middleExp = (expX + expY) / 2;
 
                 // scale parameters without losing precision
-                final DerivativeStructure scaledX = x.scalb(-middleExp);
+                final DerivativeStructure scaledX = scalb(-middleExp);
                 final DerivativeStructure scaledY = y.scalb(-middleExp);
 
                 // compute scaled hypotenuse
@@ -543,6 +477,26 @@ public class DerivativeStructure impleme
         }
     }
 
+    /**
+     * Returns the hypotenuse of a triangle with sides {@code x} and {@code y}
+     * - sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)<br/>
+     * avoiding intermediate overflow or underflow.
+     *
+     * <ul>
+     * <li> If either argument is infinite, then the result is positive infinity.</li>
+     * <li> else, if either argument is NaN then the result is NaN.</li>
+     * </ul>
+     *
+     * @param x a value
+     * @param y a value
+     * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
+     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
+     */
+    public static DerivativeStructure hypot(final DerivativeStructure x, final DerivativeStructure y)
+        throws DimensionMismatchException {
+        return x.hypot(y);
+    }
+
     /** Compute composition of the instance by a univariate function.
      * @param f array of value and derivatives of the function at
      * the current point (i.e. [f({@link #getValue()}),
@@ -567,24 +521,17 @@ public class DerivativeStructure impleme
         return result;
     }
 
-    /** Square root.
-     * @return square root of the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure sqrt() {
         return rootN(2);
     }
 
-    /** Cubic root.
-     * @return cubic root of the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure cbrt() {
         return rootN(3);
     }
 
-    /** N<sup>th</sup> root.
-     * @param n order of the root
-     * @return n<sup>th</sup> root of the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure rootN(final int n) {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.rootN(data, 0, n, result.data, 0);
@@ -613,31 +560,21 @@ public class DerivativeStructure impleme
         };
     }
 
-    /** Power operation.
-     * @param p power to apply
-     * @return this<sup>p</sup>
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure pow(final double p) {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.pow(data, 0, p, result.data, 0);
         return result;
     }
 
-    /** Integer power operation.
-     * @param n power to apply
-     * @return this<sup>n</sup>
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure pow(final int n) {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.pow(data, 0, n, result.data, 0);
         return result;
     }
 
-    /** Power operation.
-     * @param e exponent
-     * @return this<sup>e</sup>
-     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure pow(final DerivativeStructure e)
         throws DimensionMismatchException {
         compiler.checkCompatibility(e.compiler);
@@ -646,105 +583,92 @@ public class DerivativeStructure impleme
         return result;
     }
 
-    /** Exponential.
-     * @return exponential of the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure exp() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.exp(data, 0, result.data, 0);
         return result;
     }
 
-    /** Exponential minus 1.
-     * @return exponential minus one of the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure expm1() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.expm1(data, 0, result.data, 0);
         return result;
     }
 
-    /** Natural logarithm.
-     * @return logarithm of the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure log() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.log(data, 0, result.data, 0);
         return result;
     }
 
-    /** Shifted natural logarithm.
-     * @return logarithm of one plus the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure log1p() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.log1p(data, 0, result.data, 0);
         return result;
     }
 
-    /** Base 10 logarithm.
-     * @return base 10 logarithm of the instance
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure log10() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.log10(data, 0, result.data, 0);
         return result;
     }
 
-    /** Cosine operation.
-     * @return cos(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure cos() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.cos(data, 0, result.data, 0);
         return result;
     }
 
-    /** Sine operation.
-     * @return sin(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure sin() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.sin(data, 0, result.data, 0);
         return result;
     }
 
-    /** Tangent operation.
-     * @return tan(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure tan() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.tan(data, 0, result.data, 0);
         return result;
     }
 
-    /** Arc cosine operation.
-     * @return acos(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure acos() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.acos(data, 0, result.data, 0);
         return result;
     }
 
-    /** Arc sine operation.
-     * @return asin(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure asin() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.asin(data, 0, result.data, 0);
         return result;
     }
 
-    /** Arc tangent operation.
-     * @return atan(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure atan() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.atan(data, 0, result.data, 0);
         return result;
     }
 
+    /** {@inheritDoc} */
+    public DerivativeStructure atan2(final DerivativeStructure x)
+        throws DimensionMismatchException {
+        compiler.checkCompatibility(x.compiler);
+        final DerivativeStructure result = new DerivativeStructure(compiler);
+        compiler.atan2(data, 0, x.data, 0, result.data, 0);
+        return result;
+    }
+
     /** Two arguments arc tangent operation.
      * @param y first argument of the arc tangent
      * @param x second argument of the arc tangent
@@ -753,60 +677,45 @@ public class DerivativeStructure impleme
      */
     public static DerivativeStructure atan2(final DerivativeStructure y, final DerivativeStructure x)
         throws DimensionMismatchException {
-        y.compiler.checkCompatibility(x.compiler);
-        final DerivativeStructure result = new DerivativeStructure(y.compiler);
-        y.compiler.atan2(y.data, 0, x.data, 0, result.data, 0);
-        return result;
+        return y.atan2(x);
     }
 
-    /** Hyperbolic cosine operation.
-     * @return cosh(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure cosh() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.cosh(data, 0, result.data, 0);
         return result;
     }
 
-    /** Hyperbolic sine operation.
-     * @return sinh(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure sinh() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.sinh(data, 0, result.data, 0);
         return result;
     }
 
-    /** Hyperbolic tangent operation.
-     * @return tanh(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure tanh() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.tanh(data, 0, result.data, 0);
         return result;
     }
 
-    /** Inverse hyperbolic cosine operation.
-     * @return acosh(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure acosh() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.acosh(data, 0, result.data, 0);
         return result;
     }
 
-    /** Inverse hyperbolic sine operation.
-     * @return asin(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure asinh() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.asinh(data, 0, result.data, 0);
         return result;
     }
 
-    /** Inverse hyperbolic  tangent operation.
-     * @return atanh(this)
-     */
+    /** {@inheritDoc} */
     public DerivativeStructure atanh() {
         final DerivativeStructure result = new DerivativeStructure(compiler);
         compiler.atanh(data, 0, result.data, 0);
@@ -843,6 +752,216 @@ public class DerivativeStructure impleme
         return compiler.taylor(data, 0, delta);
     }
 
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final DerivativeStructure[] a, final DerivativeStructure[] b)
+        throws DimensionMismatchException {
+
+        // compute an accurate value, taking care of cancellations
+        final double[] aDouble = new double[a.length];
+        for (int i = 0; i < a.length; ++i) {
+            aDouble[i] = a[i].getValue();
+        }
+        final double[] bDouble = new double[b.length];
+        for (int i = 0; i < b.length; ++i) {
+            bDouble[i] = b[i].getValue();
+        }
+        final double accurateValue = MathArrays.linearCombination(aDouble, bDouble);
+
+        // compute a simple value, with all partial derivatives
+        DerivativeStructure simpleValue = a[0].getField().getZero();
+        for (int i = 0; i < a.length; ++i) {
+            simpleValue = simpleValue.add(a[i].multiply(b[i]));
+        }
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
+
+    }
+
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final double[] a, final DerivativeStructure[] b)
+        throws DimensionMismatchException {
+
+        // compute an accurate value, taking care of cancellations
+        final double[] bDouble = new double[b.length];
+        for (int i = 0; i < b.length; ++i) {
+            bDouble[i] = b[i].getValue();
+        }
+        final double accurateValue = MathArrays.linearCombination(a, bDouble);
+
+        // compute a simple value, with all partial derivatives
+        DerivativeStructure simpleValue = b[0].getField().getZero();
+        for (int i = 0; i < a.length; ++i) {
+            simpleValue = simpleValue.add(b[i].multiply(a[i]));
+        }
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
+
+    }
+
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final DerivativeStructure a1, final DerivativeStructure b1,
+                                                 final DerivativeStructure a2, final DerivativeStructure b2) {
+
+        // compute an accurate value, taking care of cancellations
+        final double accurateValue = MathArrays.linearCombination(a1.getValue(), b1.getValue(),
+                                                                  a2.getValue(), b2.getValue());
+
+        // compute a simple value, with all partial derivatives
+        final DerivativeStructure simpleValue = a1.multiply(b1).add(a2.multiply(b2));
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(getFreeParameters(), getOrder(), data);
+
+    }
+
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final double a1, final DerivativeStructure b1,
+                                                 final double a2, final DerivativeStructure b2) {
+
+        // compute an accurate value, taking care of cancellations
+        final double accurateValue = MathArrays.linearCombination(a1, b1.getValue(),
+                                                                  a2, b2.getValue());
+
+        // compute a simple value, with all partial derivatives
+        final DerivativeStructure simpleValue = b1.multiply(a1).add(b2.multiply(a2));
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(getFreeParameters(), getOrder(), data);
+
+    }
+
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final DerivativeStructure a1, final DerivativeStructure b1,
+                                                 final DerivativeStructure a2, final DerivativeStructure b2,
+                                                 final DerivativeStructure a3, final DerivativeStructure b3) {
+
+        // compute an accurate value, taking care of cancellations
+        final double accurateValue = MathArrays.linearCombination(a1.getValue(), b1.getValue(),
+                                                                  a2.getValue(), b2.getValue(),
+                                                                  a3.getValue(), b3.getValue());
+
+        // compute a simple value, with all partial derivatives
+        final DerivativeStructure simpleValue = a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3));
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(getFreeParameters(), getOrder(), data);
+
+    }
+
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final double a1, final DerivativeStructure b1,
+                                                 final double a2, final DerivativeStructure b2,
+                                                 final double a3, final DerivativeStructure b3) {
+
+        // compute an accurate value, taking care of cancellations
+        final double accurateValue = MathArrays.linearCombination(a1, b1.getValue(),
+                                                                  a2, b2.getValue(),
+                                                                  a3, b3.getValue());
+
+        // compute a simple value, with all partial derivatives
+        final DerivativeStructure simpleValue = b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3));
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(getFreeParameters(), getOrder(), data);
+
+    }
+
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final DerivativeStructure a1, final DerivativeStructure b1,
+                                                 final DerivativeStructure a2, final DerivativeStructure b2,
+                                                 final DerivativeStructure a3, final DerivativeStructure b3,
+                                                 final DerivativeStructure a4, final DerivativeStructure b4) {
+
+        // compute an accurate value, taking care of cancellations
+        final double accurateValue = MathArrays.linearCombination(a1.getValue(), b1.getValue(),
+                                                                  a2.getValue(), b2.getValue(),
+                                                                  a3.getValue(), b3.getValue(),
+                                                                  a4.getValue(), b4.getValue());
+
+        // compute a simple value, with all partial derivatives
+        final DerivativeStructure simpleValue = a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3)).add(a4.multiply(b4));
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(getFreeParameters(), getOrder(), data);
+
+    }
+
+    /** {@inheritDoc} */
+    public DerivativeStructure linearCombination(final double a1, final DerivativeStructure b1,
+                                                 final double a2, final DerivativeStructure b2,
+                                                 final double a3, final DerivativeStructure b3,
+                                                 final double a4, final DerivativeStructure b4) {
+
+        // compute an accurate value, taking care of cancellations
+        final double accurateValue = MathArrays.linearCombination(a1, b1.getValue(),
+                                                                  a2, b2.getValue(),
+                                                                  a3, b3.getValue(),
+                                                                  a4, b4.getValue());
+
+        // compute a simple value, with all partial derivatives
+        final DerivativeStructure simpleValue = b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3)).add(b4.multiply(a4));
+
+        // create a result with accurate value and all derivatives (not necessarily as accurate as the value)
+        final double[] data = simpleValue.getAllDerivatives();
+        data[0] = accurateValue;
+        return new DerivativeStructure(getFreeParameters(), getOrder(), data);
+
+    }
+
+    /**
+     * Test for the equality of two derivative structures.
+     * <p>
+     * Derivative structures are considered equal if they have the same number
+     * of free parameters, the same derivation order, and the same derivatives.
+     * </p>
+     * @param other Object to test for equality to this
+     * @return true if two derivative structures are equal
+     * @since 3.2
+     */
+    @Override
+    public boolean equals(Object other) {
+
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof DerivativeStructure) {
+            final DerivativeStructure rhs = (DerivativeStructure)other;
+            return (getFreeParameters() == rhs.getFreeParameters()) &&
+                   (getOrder() == rhs.getOrder()) &&
+                   MathArrays.equals(data, rhs.data);
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Get a hashCode for the derivative structure.
+     * @return a hash code value for this object
+     * @since 3.2
+     */
+    @Override
+    public int hashCode() {
+        return 227 + 229 * getFreeParameters() + 233 * getOrder() + 239 * MathUtils.hash(data);
+    }
+
     /**
      * Replace the instance with a data transfer object for serialization.
      * @return data transfer object that will be serialized

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/Dfp.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/Dfp.java?rev=1449529&r1=1449528&r2=1449529&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/Dfp.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/Dfp.java Sun Feb 24 19:13:17 2013
@@ -19,7 +19,9 @@ package org.apache.commons.math3.dfp;
 
 import java.util.Arrays;
 
-import org.apache.commons.math3.FieldElement;
+import org.apache.commons.math3.ExtendedFieldElement;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.util.FastMath;
 
 /**
  *  Decimal floating point library for Java
@@ -93,7 +95,7 @@ import org.apache.commons.math3.FieldEle
  * @version $Id$
  * @since 2.2
  */
-public class Dfp implements FieldElement<Dfp> {
+public class Dfp implements ExtendedFieldElement<Dfp> {
 
     /** The radix, or base of this system.  Set to 10000 */
     public static final int RADIX = 10000;
@@ -1178,7 +1180,7 @@ public class Dfp implements FieldElement
     /** Get the exponent of the greatest power of 10 that is less than or equal to abs(this).
      *  @return integer base 10 logarithm
      */
-    public int log10()  {
+    public int intLog10()  {
         if (mant[mant.length-1] > 1000) {
             return exp * 4 - 1;
         }
@@ -2429,7 +2431,7 @@ public class Dfp implements FieldElement
 
         /* Find the exponent, first estimate by integer log10, then adjust.
          Should be faster than doing a natural logarithm.  */
-        int exponent = (int)(y.log10() * 3.32);
+        int exponent = (int)(y.intLog10() * 3.32);
         if (exponent < 0) {
             exponent--;
         }
@@ -2503,4 +2505,348 @@ public class Dfp implements FieldElement
         return split;
     }
 
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public double getReal() {
+        return toDouble();
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp add(final double a) {
+        return add(newInstance(a));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp subtract(final double a) {
+        return subtract(newInstance(a));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp multiply(final double a) {
+        return multiply(newInstance(a));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp divide(final double a) {
+        return divide(newInstance(a));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp remainder(final double a) {
+        return remainder(newInstance(a));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public long round() {
+        return FastMath.round(toDouble());
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp signum() {
+        if (isNaN() || isZero()) {
+            return this;
+        } else {
+            return newInstance(sign > 0 ? +1 : -1);
+        }
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp copySign(final double sign) {
+        long s = Double.doubleToLongBits(sign);
+        if ((sign >= 0 && s >= 0) || (sign < 0 && s < 0)) { // Sign is currently OK
+            return this;
+        }
+        return negate(); // flip sign
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp scalb(final int n) {
+        return multiply(DfpMath.pow(getTwo(), n));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp hypot(final Dfp y) {
+        return multiply(this).add(y.multiply(y)).sqrt();
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp cbrt() {
+        return rootN(3);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp rootN(final int n) {
+        return DfpMath.pow(this, getOne().divide(n));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp pow(final double p) {
+        return DfpMath.pow(this, newInstance(p));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp pow(final int n) {
+        return DfpMath.pow(this, n);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp pow(final Dfp e) {
+        return DfpMath.pow(this, e);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp exp() {
+        return DfpMath.exp(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp expm1() {
+        return DfpMath.exp(this).subtract(getOne());
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp log() {
+        return DfpMath.log(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp log1p() {
+        return DfpMath.log(this.add(getOne()));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp log10() {
+        return DfpMath.log(this).divide(DfpMath.log(newInstance(10)));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp cos() {
+        return DfpMath.cos(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp sin() {
+        return DfpMath.sin(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp tan() {
+        return DfpMath.tan(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp acos() {
+        return DfpMath.acos(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp asin() {
+        return DfpMath.asin(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp atan() {
+        return DfpMath.atan(this);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp atan2(final Dfp x)
+        throws DimensionMismatchException {
+
+        // compute r = sqrt(x^2+y^2)
+        final Dfp r = x.multiply(x).add(multiply(this)).sqrt();
+
+        if (x.sign >= 0) {
+
+            // compute atan2(y, x) = 2 atan(y / (r + x))
+            return getTwo().multiply(divide(r.add(x)).atan());
+
+        } else {
+
+            // compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
+            final Dfp tmp = getTwo().multiply(divide(r.subtract(x)).atan());
+            final Dfp pmPi = newInstance((tmp.sign <= 0) ? -FastMath.PI : FastMath.PI);
+            return pmPi.subtract(tmp);
+
+        }
+
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp cosh() {
+        return DfpMath.exp(this).add(DfpMath.exp(negate())).divide(2);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp sinh() {
+        return DfpMath.exp(this).subtract(DfpMath.exp(negate())).divide(2);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp tanh() {
+        final Dfp ePlus  = DfpMath.exp(this);
+        final Dfp eMinus = DfpMath.exp(negate());
+        return ePlus.add(eMinus).divide(ePlus.subtract(eMinus));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp acosh() {
+        return multiply(this).subtract(getOne()).sqrt().add(this).log();
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp asinh() {
+        return multiply(this).add(getOne()).sqrt().add(this).log();
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp atanh() {
+        return getOne().add(this).divide(getOne().subtract(this)).log().divide(2);
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final Dfp[] a, final Dfp[] b)
+        throws DimensionMismatchException {
+        if (a.length != b.length) {
+            throw new DimensionMismatchException(a.length, b.length);
+        }
+        Dfp r = getZero();
+        for (int i = 0; i < a.length; ++i) {
+            r = r.add(a[i].multiply(b[i]));
+        }
+        return r;
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final double[] a, final Dfp[] b)
+        throws DimensionMismatchException {
+        if (a.length != b.length) {
+            throw new DimensionMismatchException(a.length, b.length);
+        }
+        Dfp r = getZero();
+        for (int i = 0; i < a.length; ++i) {
+            r = r.add(b[i].multiply(a[i]));
+        }
+        return r;
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2) {
+        return a1.multiply(b1).add(a2.multiply(b2));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2) {
+        return b1.multiply(a1).add(b2.multiply(a2));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final Dfp a1, final Dfp b1,
+                                 final Dfp a2, final Dfp b2,
+                                 final Dfp a3, final Dfp b3) {
+        return a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final double a1, final Dfp b1,
+                                 final double a2, final Dfp b2,
+                                 final double a3, final Dfp b3) {
+        return b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final Dfp a1, final Dfp b1, final Dfp a2, final Dfp b2,
+                                 final Dfp a3, final Dfp b3, final Dfp a4, final Dfp b4) {
+        return a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3)).add(a4.multiply(b4));
+    }
+
+    /** {@inheritDoc}
+     * @since 3.2
+     */
+    public Dfp linearCombination(final double a1, final Dfp b1, final double a2, final Dfp b2,
+                                 final double a3, final Dfp b3, final double a4, final Dfp b4) {
+        return b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3)).add(b4.multiply(a4));
+    }
+
 }

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/DfpDec.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/DfpDec.java?rev=1449529&r1=1449528&r2=1449529&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/DfpDec.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/dfp/DfpDec.java Sun Feb 24 19:13:17 2013
@@ -320,7 +320,7 @@ public class DfpDec extends Dfp {
         }
 
         if (up) {
-            inc = power10(log10() - getDecimalDigits() + 1);
+            inc = power10(intLog10() - getDecimalDigits() + 1);
             inc = copysign(inc, this);
 
             if (this.equals(getZero())) {
@@ -333,7 +333,7 @@ public class DfpDec extends Dfp {
                 result = add(inc);
             }
         } else {
-            inc = power10(log10());
+            inc = power10(intLog10());
             inc = copysign(inc, this);
 
             if (this.equals(inc)) {