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 [3/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...

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/FieldVector3D.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/FieldVector3D.java?rev=1449529&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/FieldVector3D.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/threed/FieldVector3D.java Sun Feb 24 19:13:17 2013
@@ -0,0 +1,891 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.geometry.euclidean.threed;
+
+import java.io.Serializable;
+import java.text.NumberFormat;
+
+import org.apache.commons.math3.ExtendedFieldElement;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.MathArithmeticException;
+import org.apache.commons.math3.exception.util.LocalizedFormats;
+import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.util.MathArrays;
+
+/**
+ * This class is a re-implementation of {@link Vector3D} using {@link ExtendedFieldElement}.
+ * <p>Instance of this class are guaranteed to be immutable.</p>
+ * @param <T> the type of the field elements
+ * @version $Id$
+ * @since 3.2
+ */
+public class FieldVector3D<T extends ExtendedFieldElement<T>> implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 20130224L;
+
+    /** Abscissa. */
+    private final T x;
+
+    /** Ordinate. */
+    private final T y;
+
+    /** Height. */
+    private final T z;
+
+    /** Simple constructor.
+     * Build a vector from its coordinates
+     * @param x abscissa
+     * @param y ordinate
+     * @param z height
+     * @see #getX()
+     * @see #getY()
+     * @see #getZ()
+     */
+    public FieldVector3D(final T x, final T y, final T z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /** Simple constructor.
+     * Build a vector from its coordinates
+     * @param v coordinates array
+     * @exception DimensionMismatchException if array does not have 3 elements
+     * @see #toArray()
+     */
+    public FieldVector3D(final T[] v) throws DimensionMismatchException {
+        if (v.length != 3) {
+            throw new DimensionMismatchException(v.length, 3);
+        }
+        this.x = v[0];
+        this.y = v[1];
+        this.z = v[2];
+    }
+
+    /** Simple constructor.
+     * Build a vector from its azimuthal coordinates
+     * @param alpha azimuth (&alpha;) around Z
+     *              (0 is +X, &pi;/2 is +Y, &pi; is -X and 3&pi;/2 is -Y)
+     * @param delta elevation (&delta;) above (XY) plane, from -&pi;/2 to +&pi;/2
+     * @see #getAlpha()
+     * @see #getDelta()
+     */
+    public FieldVector3D(final T alpha, final T delta) {
+        T cosDelta = delta.cos();
+        this.x = alpha.cos().multiply(cosDelta);
+        this.y = alpha.sin().multiply(cosDelta);
+        this.z = delta.sin();
+    }
+
+    /** Multiplicative constructor
+     * Build a vector from another one and a scale factor.
+     * The vector built will be a * u
+     * @param a scale factor
+     * @param u base (unscaled) vector
+     */
+    public FieldVector3D(final T a, final FieldVector3D<T>u) {
+        this.x = a.multiply(u.x);
+        this.y = a.multiply(u.y);
+        this.z = a.multiply(u.z);
+    }
+
+    /** Multiplicative constructor
+     * Build a vector from another one and a scale factor.
+     * The vector built will be a * u
+     * @param a scale factor
+     * @param u base (unscaled) vector
+     */
+    public FieldVector3D(final T a, final Vector3D u) {
+        this.x = a.multiply(u.getX());
+        this.y = a.multiply(u.getY());
+        this.z = a.multiply(u.getZ());
+    }
+
+    /** Multiplicative constructor
+     * Build a vector from another one and a scale factor.
+     * The vector built will be a * u
+     * @param a scale factor
+     * @param u base (unscaled) vector
+     */
+    public FieldVector3D(final double a, final FieldVector3D<T> u) {
+        this.x = u.x.multiply(a);
+        this.y = u.y.multiply(a);
+        this.z = u.z.multiply(a);
+    }
+
+    /** Linear constructor
+     * Build a vector from two other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     */
+    public FieldVector3D(final T a1, final FieldVector3D<T> u1,
+                         final T a2, final FieldVector3D<T> u2) {
+        final T prototype = a1;
+        this.x = prototype.linearCombination(a1, u1.getX(), a2, u2.getX());
+        this.y = prototype.linearCombination(a1, u1.getY(), a2, u2.getY());
+        this.z = prototype.linearCombination(a1, u1.getZ(), a2, u2.getZ());
+    }
+
+    /** Linear constructor
+     * Build a vector from two other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     */
+    public FieldVector3D(final T a1, final Vector3D u1,
+                         final T a2, final Vector3D u2) {
+        final T prototype = a1;
+        this.x = prototype.linearCombination(u1.getX(), a1, u2.getX(), a2);
+        this.y = prototype.linearCombination(u1.getY(), a1, u2.getY(), a2);
+        this.z = prototype.linearCombination(u1.getZ(), a1, u2.getZ(), a2);
+    }
+
+    /** Linear constructor
+     * Build a vector from two other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     */
+    public FieldVector3D(final double a1, final FieldVector3D<T> u1,
+                         final double a2, final FieldVector3D<T> u2) {
+        final T prototype = u1.getX();
+        this.x = prototype.linearCombination(a1, u1.getX(), a2, u2.getX());
+        this.y = prototype.linearCombination(a1, u1.getY(), a2, u2.getY());
+        this.z = prototype.linearCombination(a1, u1.getZ(), a2, u2.getZ());
+    }
+
+    /** Linear constructor
+     * Build a vector from three other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     */
+    public FieldVector3D(final T a1, final FieldVector3D<T> u1,
+                         final T a2, final FieldVector3D<T> u2,
+                         final T a3, final FieldVector3D<T> u3) {
+        final T prototype = a1;
+        this.x = prototype.linearCombination(a1, u1.getX(), a2, u2.getX(), a3, u3.getX());
+        this.y = prototype.linearCombination(a1, u1.getY(), a2, u2.getY(), a3, u3.getY());
+        this.z = prototype.linearCombination(a1, u1.getZ(), a2, u2.getZ(), a3, u3.getZ());
+    }
+
+    /** Linear constructor
+     * Build a vector from three other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     */
+    public FieldVector3D(final T a1, final Vector3D u1,
+                         final T a2, final Vector3D u2,
+                         final T a3, final Vector3D u3) {
+        final T prototype = a1;
+        this.x = prototype.linearCombination(u1.getX(), a1, u2.getX(), a2, u3.getX(), a3);
+        this.y = prototype.linearCombination(u1.getY(), a1, u2.getY(), a2, u3.getY(), a3);
+        this.z = prototype.linearCombination(u1.getZ(), a1, u2.getZ(), a2, u3.getZ(), a3);
+    }
+
+    /** Linear constructor
+     * Build a vector from three other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     */
+    public FieldVector3D(final double a1, final FieldVector3D<T> u1,
+                         final double a2, final FieldVector3D<T> u2,
+                         final double a3, final FieldVector3D<T> u3) {
+        final T prototype = u1.getX();
+        this.x = prototype.linearCombination(a1, u1.getX(), a2, u2.getX(), a3, u3.getX());
+        this.y = prototype.linearCombination(a1, u1.getY(), a2, u2.getY(), a3, u3.getY());
+        this.z = prototype.linearCombination(a1, u1.getZ(), a2, u2.getZ(), a3, u3.getZ());
+    }
+
+    /** Linear constructor
+     * Build a vector from four other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     * @param a4 fourth scale factor
+     * @param u4 fourth base (unscaled) vector
+     */
+    public FieldVector3D(final T a1, final FieldVector3D<T> u1,
+                         final T a2, final FieldVector3D<T> u2,
+                         final T a3, final FieldVector3D<T> u3,
+                         final T a4, final FieldVector3D<T> u4) {
+        final T prototype = a1;
+        this.x = prototype.linearCombination(a1, u1.getX(), a2, u2.getX(), a3, u3.getX(), a4, u4.getX());
+        this.y = prototype.linearCombination(a1, u1.getY(), a2, u2.getY(), a3, u3.getY(), a4, u4.getY());
+        this.z = prototype.linearCombination(a1, u1.getZ(), a2, u2.getZ(), a3, u3.getZ(), a4, u4.getZ());
+    }
+
+    /** Linear constructor
+     * Build a vector from four other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     * @param a4 fourth scale factor
+     * @param u4 fourth base (unscaled) vector
+     */
+    public FieldVector3D(final T a1, final Vector3D u1,
+                         final T a2, final Vector3D u2,
+                         final T a3, final Vector3D u3,
+                         final T a4, final Vector3D u4) {
+        final T prototype = a1;
+        this.x = prototype.linearCombination(u1.getX(), a1, u2.getX(), a2, u3.getX(), a3, u4.getX(), a4);
+        this.y = prototype.linearCombination(u1.getY(), a1, u2.getY(), a2, u3.getY(), a3, u4.getY(), a4);
+        this.z = prototype.linearCombination(u1.getZ(), a1, u2.getZ(), a2, u3.getZ(), a3, u4.getZ(), a4);
+    }
+
+    /** Linear constructor
+     * Build a vector from four other ones and corresponding scale factors.
+     * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
+     * @param a1 first scale factor
+     * @param u1 first base (unscaled) vector
+     * @param a2 second scale factor
+     * @param u2 second base (unscaled) vector
+     * @param a3 third scale factor
+     * @param u3 third base (unscaled) vector
+     * @param a4 fourth scale factor
+     * @param u4 fourth base (unscaled) vector
+     */
+    public FieldVector3D(final double a1, final FieldVector3D<T> u1,
+                         final double a2, final FieldVector3D<T> u2,
+                         final double a3, final FieldVector3D<T> u3,
+                         final double a4, final FieldVector3D<T> u4) {
+        final T prototype = u1.getX();
+        this.x = prototype.linearCombination(a1, u1.getX(), a2, u2.getX(), a3, u3.getX(), a4, u4.getX());
+        this.y = prototype.linearCombination(a1, u1.getY(), a2, u2.getY(), a3, u3.getY(), a4, u4.getY());
+        this.z = prototype.linearCombination(a1, u1.getZ(), a2, u2.getZ(), a3, u3.getZ(), a4, u4.getZ());
+    }
+
+    /** Get the abscissa of the vector.
+     * @return abscissa of the vector
+     * @see #Vector3D(T, T, T)
+     */
+    public T getX() {
+        return x;
+    }
+
+    /** Get the ordinate of the vector.
+     * @return ordinate of the vector
+     * @see #Vector3D(T, T, T)
+     */
+    public T getY() {
+        return y;
+    }
+
+    /** Get the height of the vector.
+     * @return height of the vector
+     * @see #Vector3D(T, T, T)
+     */
+    public T getZ() {
+        return z;
+    }
+
+    /** Get the vector coordinates as a dimension 3 array.
+     * @return vector coordinates
+     * @see #Vector3D(T[])
+     */
+    public T[] toArray() {
+        final T[] array = MathArrays.buildArray(x.getField(), 3);
+        array[0] = x;
+        array[1] = y;
+        array[2] = z;
+        return array;
+    }
+
+    /** Convert to a constant vector without derivatives.
+     * @return a constant vector
+     */
+    public Vector3D toVector3D() {
+        return new Vector3D(x.getReal(), y.getReal(), z.getReal());
+    }
+
+    /** Get the L<sub>1</sub> norm for the vector.
+     * @return L<sub>1</sub> norm for the vector
+     */
+    public T getNorm1() {
+        return x.abs().add(y.abs()).add(z.abs());
+    }
+
+    /** Get the L<sub>2</sub> norm for the vector.
+     * @return Euclidean norm for the vector
+     */
+    public T getNorm() {
+        // there are no cancellation problems here, so we use the straightforward formula
+        return x.multiply(x).add(y.multiply(y)).add(z.multiply(z)).sqrt();
+    }
+
+    /** Get the square of the norm for the vector.
+     * @return square of the Euclidean norm for the vector
+     */
+    public T getNormSq() {
+        // there are no cancellation problems here, so we use the straightforward formula
+        return x.multiply(x).add(y.multiply(y)).add(z.multiply(z));
+    }
+
+    /** Get the L<sub>&infin;</sub> norm for the vector.
+     * @return L<sub>&infin;</sub> norm for the vector
+     */
+    public T getNormInf() {
+        final T xAbs = x.abs();
+        final T yAbs = y.abs();
+        final T zAbs = z.abs();
+        if (xAbs.getReal() <= yAbs.getReal()) {
+            if (yAbs.getReal() <= zAbs.getReal()) {
+                return zAbs;
+            } else {
+                return yAbs;
+            }
+        } else {
+            if (xAbs.getReal() <= zAbs.getReal()) {
+                return zAbs;
+            } else {
+                return xAbs;
+            }
+        }
+    }
+
+    /** Get the azimuth of the vector.
+     * @return azimuth (&alpha;) of the vector, between -&pi; and +&pi;
+     * @see #Vector3D(T, T)
+     */
+    public T getAlpha() {
+        return y.atan2(x);
+    }
+
+    /** Get the elevation of the vector.
+     * @return elevation (&delta;) of the vector, between -&pi;/2 and +&pi;/2
+     * @see #Vector3D(T, T)
+     */
+    public T getDelta() {
+        return z.divide(getNorm()).asin();
+    }
+
+    /** Add a vector to the instance.
+     * @param v vector to add
+     * @return a new vector
+     */
+    public FieldVector3D<T> add(final FieldVector3D<T> v) {
+        return new FieldVector3D<T>(x.add(v.x), y.add(v.y), z.add(v.z));
+    }
+
+    /** Add a vector to the instance.
+     * @param v vector to add
+     * @return a new vector
+     */
+    public FieldVector3D<T> add(final Vector3D v) {
+        return new FieldVector3D<T>(x.add(v.getX()), y.add(v.getY()), z.add(v.getZ()));
+    }
+
+    /** Add a scaled vector to the instance.
+     * @param factor scale factor to apply to v before adding it
+     * @param v vector to add
+     * @return a new vector
+     */
+    public FieldVector3D<T> add(final T factor, final FieldVector3D<T> v) {
+        return new FieldVector3D<T>(x.getField().getOne(), this, factor, v);
+    }
+
+    /** Add a scaled vector to the instance.
+     * @param factor scale factor to apply to v before adding it
+     * @param v vector to add
+     * @return a new vector
+     */
+    public FieldVector3D<T> add(final T factor, final Vector3D v) {
+        return new FieldVector3D<T>(x.add(factor.multiply(v.getX())),
+                                    y.add(factor.multiply(v.getY())),
+                                    z.add(factor.multiply(v.getZ())));
+    }
+
+    /** Add a scaled vector to the instance.
+     * @param factor scale factor to apply to v before adding it
+     * @param v vector to add
+     * @return a new vector
+     */
+    public FieldVector3D<T> add(final double factor, final FieldVector3D<T> v) {
+        return new FieldVector3D<T>(1.0, this, factor, v);
+    }
+
+    /** Add a scaled vector to the instance.
+     * @param factor scale factor to apply to v before adding it
+     * @param v vector to add
+     * @return a new vector
+     */
+    public FieldVector3D<T> add(final double factor, final Vector3D v) {
+        return new FieldVector3D<T>(x.add(factor * v.getX()),
+                                    y.add(factor * v.getY()),
+                                    z.add(factor * v.getZ()));
+    }
+
+    /** Subtract a vector from the instance.
+     * @param v vector to subtract
+     * @return a new vector
+     */
+    public FieldVector3D<T> subtract(final FieldVector3D<T> v) {
+        return new FieldVector3D<T>(x.subtract(v.x), y.subtract(v.y), z.subtract(v.z));
+    }
+
+    /** Subtract a vector from the instance.
+     * @param v vector to subtract
+     * @return a new vector
+     */
+    public FieldVector3D<T> subtract(final Vector3D v) {
+        return new FieldVector3D<T>(x.subtract(v.getX()), y.subtract(v.getY()), z.subtract(v.getZ()));
+    }
+
+    /** Subtract a scaled vector from the instance.
+     * @param factor scale factor to apply to v before subtracting it
+     * @param v vector to subtract
+     * @return a new vector
+     */
+    public FieldVector3D<T> subtract(final T factor, final FieldVector3D<T> v) {
+        return new FieldVector3D<T>(x.getField().getOne(), this, factor.negate(), v);
+    }
+
+    /** Subtract a scaled vector from the instance.
+     * @param factor scale factor to apply to v before subtracting it
+     * @param v vector to subtract
+     * @return a new vector
+     */
+    public FieldVector3D<T> subtract(final T factor, final Vector3D v) {
+        return new FieldVector3D<T>(x.subtract(factor.multiply(v.getX())),
+                                    y.subtract(factor.multiply(v.getY())),
+                                    z.subtract(factor.multiply(v.getZ())));
+    }
+
+    /** Subtract a scaled vector from the instance.
+     * @param factor scale factor to apply to v before subtracting it
+     * @param v vector to subtract
+     * @return a new vector
+     */
+    public FieldVector3D<T> subtract(final double factor, final FieldVector3D<T> v) {
+        return new FieldVector3D<T>(1.0, this, -factor, v);
+    }
+
+    /** Subtract a scaled vector from the instance.
+     * @param factor scale factor to apply to v before subtracting it
+     * @param v vector to subtract
+     * @return a new vector
+     */
+    public FieldVector3D<T> subtract(final double factor, final Vector3D v) {
+        return new FieldVector3D<T>(x.subtract(factor * v.getX()),
+                                    y.subtract(factor * v.getY()),
+                                    z.subtract(factor * v.getZ()));
+    }
+
+    /** Get a normalized vector aligned with the instance.
+     * @return a new normalized vector
+     * @exception MathArithmeticException if the norm is zero
+     */
+    public FieldVector3D<T> normalize() throws MathArithmeticException {
+        final T s = getNorm();
+        if (s.getReal() == 0) {
+            throw new MathArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
+        }
+        return scalarMultiply(s.reciprocal());
+    }
+
+    /** Get a vector orthogonal to the instance.
+     * <p>There are an infinite number of normalized vectors orthogonal
+     * to the instance. This method picks up one of them almost
+     * arbitrarily. It is useful when one needs to compute a reference
+     * frame with one of the axes in a predefined direction. The
+     * following example shows how to build a frame having the k axis
+     * aligned with the known vector u :
+     * <pre><code>
+     *   Vector3D k = u.normalize();
+     *   Vector3D i = k.orthogonal();
+     *   Vector3D j = Vector3D.crossProduct(k, i);
+     * </code></pre></p>
+     * @return a new normalized vector orthogonal to the instance
+     * @exception MathArithmeticException if the norm of the instance is null
+     */
+    public FieldVector3D<T> orthogonal() throws MathArithmeticException {
+
+        final double threshold = 0.6 * getNorm().getReal();
+        if (threshold == 0) {
+            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
+        }
+
+        if (FastMath.abs(x.getReal()) <= threshold) {
+            final T inverse  = y.multiply(y).add(z.multiply(z)).sqrt().reciprocal();
+            return new FieldVector3D<T>(inverse.getField().getZero(), inverse.multiply(z), inverse.multiply(y).negate());
+        } else if (FastMath.abs(y.getReal()) <= threshold) {
+            final T inverse  = x.multiply(x).add(z.multiply(z)).sqrt().reciprocal();
+            return new FieldVector3D<T>(inverse.multiply(z).negate(), inverse.getField().getZero(), inverse.multiply(x));
+        } else {
+            final T inverse  = x.multiply(x).add(y.multiply(y)).sqrt().reciprocal();
+            return new FieldVector3D<T>(inverse.multiply(y), inverse.multiply(x).negate(), inverse.getField().getZero());
+        }
+
+    }
+
+    /** Compute the angular separation between the instance and another vector.
+     * <p>This method computes the angular separation between two
+     * vectors using the dot product for well separated vectors and the
+     * cross product for almost aligned vectors. This allows to have a
+     * good accuracy in all cases, even for vectors very close to each
+     * other.</p>
+     * @param v second vector
+     * @return angular separation between the instance and v
+     * @exception MathArithmeticException if either vector has a null norm
+     */
+    public T angle(FieldVector3D<T> v) throws MathArithmeticException {
+
+        final T normProduct = getNorm().multiply(v.getNorm());
+        if (normProduct.getReal() == 0) {
+            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
+        }
+
+        final T dot = dotProduct(v);
+        final double threshold = normProduct.getReal() * 0.9999;
+        if ((dot.getReal() < -threshold) || (dot.getReal() > threshold)) {
+            // the vectors are almost aligned, compute using the sine
+            FieldVector3D<T> v3 = crossProduct(v);
+            if (dot.getReal() >= 0) {
+                return v3.getNorm().divide(normProduct).asin();
+            }
+            return v3.getNorm().divide(normProduct).asin().subtract(FastMath.PI).negate();
+        }
+
+        // the vectors are sufficiently separated to use the cosine
+        return dot.divide(normProduct).acos();
+
+    }
+
+    /** Get the opposite of the instance.
+     * @return a new vector which is opposite to the instance
+     */
+    public FieldVector3D<T> negate() {
+        return new FieldVector3D<T>(x.negate(), y.negate(), z.negate());
+    }
+
+    /** Multiply the instance by a scalar.
+     * @param a scalar
+     * @return a new vector
+     */
+    public FieldVector3D<T> scalarMultiply(final T a) {
+        return new FieldVector3D<T>(x.multiply(a), y.multiply(a), z.multiply(a));
+    }
+
+    /** Multiply the instance by a scalar.
+     * @param a scalar
+     * @return a new vector
+     */
+    public FieldVector3D<T> scalarMultiply(final double a) {
+        return new FieldVector3D<T>(x.multiply(a), y.multiply(a), z.multiply(a));
+    }
+
+    /**
+     * Returns true if any coordinate of this vector is NaN; false otherwise
+     * @return  true if any coordinate of this vector is NaN; false otherwise
+     */
+    public boolean isNaN() {
+        return Double.isNaN(x.getReal()) || Double.isNaN(y.getReal()) || Double.isNaN(z.getReal());
+    }
+
+    /**
+     * Returns true if any coordinate of this vector is infinite and none are NaN;
+     * false otherwise
+     * @return  true if any coordinate of this vector is infinite and none are NaN;
+     * false otherwise
+     */
+    public boolean isInfinite() {
+        return !isNaN() && (Double.isInfinite(x.getReal()) || Double.isInfinite(y.getReal()) || Double.isInfinite(z.getReal()));
+    }
+
+    /**
+     * Test for the equality of two 3D vectors.
+     * <p>
+     * If all coordinates of two 3D vectors are exactly the same, and none are
+     * <code>T.NaN</code>, the two 3D vectors are considered to be equal.
+     * </p>
+     * <p>
+     * <code>NaN</code> coordinates are considered to affect globally the vector
+     * and be equals to each other - i.e, if either (or all) coordinates of the
+     * 3D vector are equal to <code>T.NaN</code>, the 3D vector is equal to
+     * {@link #NaN}.
+     * </p>
+     *
+     * @param other Object to test for equality to this
+     * @return true if two 3D vector objects are equal, false if
+     *         object is null, not an instance of Vector3D, or
+     *         not equal to this Vector3D instance
+     *
+     */
+    @Override
+    public boolean equals(Object other) {
+
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof FieldVector3D) {
+            @SuppressWarnings("unchecked")
+            final FieldVector3D<T> rhs = (FieldVector3D<T>) other;
+            if (rhs.isNaN()) {
+                return this.isNaN();
+            }
+
+            return x.equals(rhs.x) && y.equals(rhs.y) && z.equals(rhs.z);
+
+        }
+        return false;
+    }
+
+    /**
+     * Get a hashCode for the 3D vector.
+     * <p>
+     * All NaN values have the same hash code.</p>
+     *
+     * @return a hash code value for this object
+     */
+    @Override
+    public int hashCode() {
+        if (isNaN()) {
+            return 409;
+        }
+        return 311 * (107 * x.hashCode() + 83 * y.hashCode() +  z.hashCode());
+    }
+
+    /** Compute the dot-product of the instance and another vector.
+     * <p>
+     * The implementation uses specific multiplication and addition
+     * algorithms to preserve accuracy and reduce cancellation effects.
+     * It should be very accurate even for nearly orthogonal vectors.
+     * </p>
+     * @see MathArrays#linearCombination(double, double, double, double, double, double)
+     * @param v second vector
+     * @return the dot product this.v
+     */
+    public T dotProduct(final FieldVector3D<T> v) {
+        return x.linearCombination(x, v.x, y, v.y, z, v.z);
+    }
+
+    /** Compute the dot-product of the instance and another vector.
+     * <p>
+     * The implementation uses specific multiplication and addition
+     * algorithms to preserve accuracy and reduce cancellation effects.
+     * It should be very accurate even for nearly orthogonal vectors.
+     * </p>
+     * @see MathArrays#linearCombination(double, double, double, double, double, double)
+     * @param v second vector
+     * @return the dot product this.v
+     */
+    public T dotProduct(final Vector3D v) {
+        return x.linearCombination(v.getX(), x, v.getY(), y, v.getZ(), z);
+    }
+
+    /** Compute the cross-product of the instance with another vector.
+     * @param v other vector
+     * @return the cross product this ^ v as a new Vector3D
+     */
+    public FieldVector3D<T> crossProduct(final FieldVector3D<T> v) {
+        return new FieldVector3D<T>(x.linearCombination(y, v.z, z.negate(), v.y),
+                                    y.linearCombination(z, v.x, x.negate(), v.z),
+                                    z.linearCombination(x, v.y, y.negate(), v.x));
+    }
+
+    /** Compute the cross-product of the instance with another vector.
+     * @param v other vector
+     * @return the cross product this ^ v as a new Vector3D
+     */
+    public FieldVector3D<T> crossProduct(final Vector3D v) {
+        return new FieldVector3D<T>(x.linearCombination(v.getZ(), y, -v.getY(), z),
+                                    y.linearCombination(v.getX(), z, -v.getZ(), x),
+                                    z.linearCombination(v.getY(), x, -v.getX(), y));
+    }
+
+    /** Compute the distance between the instance and another vector according to the L<sub>1</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNorm1()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the distance between the instance and p according to the L<sub>1</sub> norm
+     */
+    public T distance1(final FieldVector3D<T> v) {
+        final T dx = v.x.subtract(x).abs();
+        final T dy = v.y.subtract(y).abs();
+        final T dz = v.z.subtract(z).abs();
+        return dx.add(dy).add(dz);
+    }
+
+    /** Compute the distance between the instance and another vector according to the L<sub>1</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNorm1()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the distance between the instance and p according to the L<sub>1</sub> norm
+     */
+    public T distance1(final Vector3D v) {
+        final T dx = x.subtract(v.getX()).abs();
+        final T dy = y.subtract(v.getY()).abs();
+        final T dz = z.subtract(v.getZ()).abs();
+        return dx.add(dy).add(dz);
+    }
+
+    /** Compute the distance between the instance and another vector according to the L<sub>2</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNorm()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the distance between the instance and p according to the L<sub>2</sub> norm
+     */
+    public T distance(final FieldVector3D<T> v) {
+        final T dx = v.x.subtract(x);
+        final T dy = v.y.subtract(y);
+        final T dz = v.z.subtract(z);
+        return dx.multiply(dx).add(dy.multiply(dy)).add(dz.multiply(dz)).sqrt();
+    }
+
+    /** Compute the distance between the instance and another vector according to the L<sub>2</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNorm()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the distance between the instance and p according to the L<sub>2</sub> norm
+     */
+    public T distance(final Vector3D v) {
+        final T dx = x.subtract(v.getX());
+        final T dy = y.subtract(v.getY());
+        final T dz = z.subtract(v.getZ());
+        return dx.multiply(dx).add(dy.multiply(dy)).add(dz.multiply(dz)).sqrt();
+    }
+
+    /** Compute the distance between the instance and another vector according to the L<sub>&infin;</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNormInf()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the distance between the instance and p according to the L<sub>&infin;</sub> norm
+     */
+    public T distanceInf(final FieldVector3D<T> v) {
+        final T dx = v.x.subtract(x).abs();
+        final T dy = v.y.subtract(y).abs();
+        final T dz = v.z.subtract(z).abs();
+        if (dx.getReal() <= dy.getReal()) {
+            if (dy.getReal() <= dz.getReal()) {
+                return dz;
+            } else {
+                return dy;
+            }
+        } else {
+            if (dx.getReal() <= dz.getReal()) {
+                return dz;
+            } else {
+                return dx;
+            }
+        }
+    }
+
+    /** Compute the distance between the instance and another vector according to the L<sub>&infin;</sub> norm.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNormInf()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the distance between the instance and p according to the L<sub>&infin;</sub> norm
+     */
+    public T distanceInf(final Vector3D v) {
+        final T dx = x.subtract(v.getX()).abs();
+        final T dy = y.subtract(v.getY()).abs();
+        final T dz = z.subtract(v.getZ()).abs();
+        if (dx.getReal() <= dy.getReal()) {
+            if (dy.getReal() <= dz.getReal()) {
+                return dz;
+            } else {
+                return dy;
+            }
+        } else {
+            if (dx.getReal() <= dz.getReal()) {
+                return dz;
+            } else {
+                return dx;
+            }
+        }
+    }
+
+    /** Compute the square of the distance between the instance and another vector.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNormSq()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the square of the distance between the instance and p
+     */
+    public T distanceSq(final FieldVector3D<T> v) {
+        final T dx = v.x.subtract(x);
+        final T dy = v.y.subtract(y);
+        final T dz = v.z.subtract(z);
+        return dx.multiply(dx).add(dy.multiply(dy)).add(dz.multiply(dz));
+    }
+
+    /** Compute the square of the distance between the instance and another vector.
+     * <p>Calling this method is equivalent to calling:
+     * <code>q.subtract(p).getNormSq()</code> except that no intermediate
+     * vector is built</p>
+     * @param v second vector
+     * @return the square of the distance between the instance and p
+     */
+    public T distanceSq(final Vector3D v) {
+        final T dx = x.subtract(v.getX());
+        final T dy = y.subtract(v.getY());
+        final T dz = z.subtract(v.getZ());
+        return dx.multiply(dx).add(dy.multiply(dy)).add(dz.multiply(dz));
+    }
+
+    /** Get a string representation of this vector.
+     * @return a string representation of this vector
+     */
+    @Override
+    public String toString() {
+        return Vector3DFormat.getInstance().format(toVector3D());
+    }
+
+    /** {@inheritDoc} */
+    public String toString(final NumberFormat format) {
+        return new Vector3DFormat(format).format(toVector3D());
+    }
+
+}

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

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

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java?rev=1449529&r1=1449528&r2=1449529&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java Sun Feb 24 19:13:17 2013
@@ -17,16 +17,16 @@
 package org.apache.commons.math3.linear;
 
 import java.io.Serializable;
-import java.lang.reflect.Array;
 
 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.MathArithmeticException;
 import org.apache.commons.math3.exception.NotPositiveException;
 import org.apache.commons.math3.exception.NullArgumentException;
 import org.apache.commons.math3.exception.OutOfRangeException;
-import org.apache.commons.math3.exception.DimensionMismatchException;
 import org.apache.commons.math3.exception.util.LocalizedFormats;
+import org.apache.commons.math3.util.MathArrays;
 import org.apache.commons.math3.util.OpenIntToFieldHashMap;
 
 /**
@@ -479,7 +479,7 @@ public class SparseFieldVector<T extends
 
     /** {@inheritDoc} */
     public T[] toArray() {
-        T[] res = buildArray(virtualSize);
+        T[] res = MathArrays.buildArray(field, virtualSize);
         OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
         while (iter.hasNext()) {
             iter.advance();
@@ -529,18 +529,6 @@ public class SparseFieldVector<T extends
         }
     }
 
-    /**
-     * Build an array of elements.
-     *
-     * @param length Size of the array to build.
-     * @return a new array.
-     */
-    @SuppressWarnings("unchecked") // field is type T
-    private T[] buildArray(final int length) {
-        return (T[]) Array.newInstance(field.getRuntimeClass(), length);
-    }
-
-
     /** {@inheritDoc} */
     @Override
     public int hashCode() {

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Decimal64.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Decimal64.java?rev=1449529&r1=1449528&r2=1449529&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Decimal64.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Decimal64.java Sun Feb 24 19:13:17 2013
@@ -16,19 +16,20 @@
  */
 package org.apache.commons.math3.util;
 
+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;
 
 /**
  * This class wraps a {@code double} value in an object. It is similar to the
  * standard class {@link Double}, while also implementing the
- * {@link FieldElement} interface.
+ * {@link ExtendedFieldElement} interface.
  *
  * @since 3.1
  * @version $Id$
  */
-public class Decimal64 extends Number implements FieldElement<Decimal64>,
-Comparable<Decimal64> {
+public class Decimal64 extends Number
+                       implements ExtendedFieldElement<Decimal64>, Comparable<Decimal64> {
 
     /** The constant value of {@code 0d} as a {@code Decimal64}. */
     public static final Decimal64 ZERO;
@@ -301,4 +302,287 @@ Comparable<Decimal64> {
     public boolean isNaN() {
         return Double.isNaN(value);
     }
+
+    /** {@inheritDoc} */
+    public double getReal() {
+        return value;
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 add(final double a) {
+        return new Decimal64(value + a);
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 subtract(final double a) {
+        return new Decimal64(value - a);
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 multiply(final double a) {
+        return new Decimal64(value * a);
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 divide(final double a) {
+        return new Decimal64(value / a);
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 remainder(final double a) {
+        return new Decimal64(value % a);
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 remainder(final Decimal64 a) {
+        return new Decimal64(value % a.value);
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 abs() {
+        return new Decimal64(FastMath.abs(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 ceil() {
+        return new Decimal64(FastMath.ceil(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 floor() {
+        return new Decimal64(FastMath.floor(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 rint() {
+        return new Decimal64(FastMath.rint(value));
+    }
+
+    /** {@inheritDoc} */
+    public long round() {
+        return FastMath.round(value);
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 signum() {
+        return new Decimal64(FastMath.signum(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 copySign(final double sign) {
+        return new Decimal64(FastMath.copySign(value, sign));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 scalb(final int n) {
+        return new Decimal64(FastMath.scalb(value, n));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 hypot(final Decimal64 y) {
+        return new Decimal64(FastMath.hypot(value, y.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 sqrt() {
+        return new Decimal64(FastMath.sqrt(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 cbrt() {
+        return new Decimal64(FastMath.cbrt(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 rootN(final int n) {
+        return new Decimal64(FastMath.pow(value, 1.0 / n));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 pow(final double p) {
+        return new Decimal64(FastMath.pow(value, p));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 pow(final int n) {
+        return new Decimal64(FastMath.pow(value, n));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 pow(final Decimal64 e) {
+        return new Decimal64(FastMath.pow(value, e.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 exp() {
+        return new Decimal64(FastMath.exp(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 expm1() {
+        return new Decimal64(FastMath.expm1(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 log() {
+        return new Decimal64(FastMath.log(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 log1p() {
+        return new Decimal64(FastMath.log1p(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 log10() {
+        return new Decimal64(FastMath.log10(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 cos() {
+        return new Decimal64(FastMath.cos(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 sin() {
+        return new Decimal64(FastMath.sin(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 tan() {
+        return new Decimal64(FastMath.tan(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 acos() {
+        return new Decimal64(FastMath.acos(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 asin() {
+        return new Decimal64(FastMath.asin(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 atan() {
+        return new Decimal64(FastMath.atan(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 atan2(final Decimal64 x) {
+        return new Decimal64(FastMath.atan2(value, x.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 cosh() {
+        return new Decimal64(FastMath.cosh(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 sinh() {
+        return new Decimal64(FastMath.sinh(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 tanh() {
+        return new Decimal64(FastMath.tanh(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 acosh() {
+        return new Decimal64(FastMath.acosh(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 asinh() {
+        return new Decimal64(FastMath.asinh(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 atanh() {
+        return new Decimal64(FastMath.atanh(value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final Decimal64[] a, final Decimal64[] b)
+        throws DimensionMismatchException {
+        if (a.length != b.length) {
+            throw new DimensionMismatchException(a.length, b.length);
+        }
+        final double[] aDouble = new double[a.length];
+        final double[] bDouble = new double[b.length];
+        for (int i = 0; i < a.length; ++i) {
+            aDouble[i] = a[i].value;
+            bDouble[i] = b[i].value;
+        }
+        return new Decimal64(MathArrays.linearCombination(aDouble, bDouble));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final double[] a, final Decimal64[] b)
+        throws DimensionMismatchException {
+        if (a.length != b.length) {
+            throw new DimensionMismatchException(a.length, b.length);
+        }
+        final double[] bDouble = new double[b.length];
+        for (int i = 0; i < a.length; ++i) {
+            bDouble[i] = b[i].value;
+        }
+        return new Decimal64(MathArrays.linearCombination(a, bDouble));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
+                                       final Decimal64 a2, final Decimal64 b2) {
+        return new Decimal64(MathArrays.linearCombination(a1.value, b1.value,
+                                                          a2.value, b2.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final double a1, final Decimal64 b1,
+                                       final double a2, final Decimal64 b2) {
+        return new Decimal64(MathArrays.linearCombination(a1, b1.value,
+                                                          a2, b2.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
+                                       final Decimal64 a2, final Decimal64 b2,
+                                       final Decimal64 a3, final Decimal64 b3) {
+        return new Decimal64(MathArrays.linearCombination(a1.value, b1.value,
+                                                          a2.value, b2.value,
+                                                          a3.value, b3.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final double a1, final Decimal64 b1,
+                                       final double a2, final Decimal64 b2,
+                                       final double a3, final Decimal64 b3) {
+        return new Decimal64(MathArrays.linearCombination(a1, b1.value,
+                                                          a2, b2.value,
+                                                          a3, b3.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
+                                       final Decimal64 a2, final Decimal64 b2,
+                                       final Decimal64 a3, final Decimal64 b3,
+                                       final Decimal64 a4, final Decimal64 b4) {
+        return new Decimal64(MathArrays.linearCombination(a1.value, b1.value,
+                                                          a2.value, b2.value,
+                                                          a3.value, b3.value,
+                                                          a4.value, b4.value));
+    }
+
+    /** {@inheritDoc} */
+    public Decimal64 linearCombination(final double a1, final Decimal64 b1,
+                                       final double a2, final Decimal64 b2,
+                                       final double a3, final Decimal64 b3,
+                                       final double a4, final Decimal64 b4) {
+        return new Decimal64(MathArrays.linearCombination(a1, b1.value,
+                                                          a2, b2.value,
+                                                          a3, b3.value,
+                                                          a4, b4.value));
+    }
+
 }

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/MathArrays.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/MathArrays.java?rev=1449529&r1=1449528&r2=1449529&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/MathArrays.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/MathArrays.java Sun Feb 24 19:13:17 2013
@@ -17,21 +17,23 @@
 
 package org.apache.commons.math3.util;
 
-import java.util.List;
+import java.lang.reflect.Array;
 import java.util.ArrayList;
-import java.util.Comparator;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
-import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.Field;
 import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.MathArithmeticException;
+import org.apache.commons.math3.exception.MathIllegalArgumentException;
 import org.apache.commons.math3.exception.MathInternalError;
 import org.apache.commons.math3.exception.NonMonotonicSequenceException;
 import org.apache.commons.math3.exception.NotPositiveException;
 import org.apache.commons.math3.exception.NotStrictlyPositiveException;
 import org.apache.commons.math3.exception.NullArgumentException;
-import org.apache.commons.math3.exception.MathIllegalArgumentException;
 import org.apache.commons.math3.exception.util.LocalizedFormats;
-import org.apache.commons.math3.exception.MathArithmeticException;
 
 /**
  * Arrays utilities.
@@ -1119,353 +1121,6 @@ public class MathArrays {
     }
 
     /**
-     * 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.
-     *
-     * @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
-     */
-    public static 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);
-
-    }
-
-    /**
-     * 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.
-     *
-     * @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 static 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);
-
-    }
-
-    /**
-     * 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>
-     * @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(DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure)
-     * @see #linearCombination(DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure)
-     * @since 3.2
-     */
-    public static 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(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
-
-    }
-
-    /**
-     * 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>
-     * @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, DerivativeStructure, double, DerivativeStructure, double, DerivativeStructure)
-     * @see #linearCombination(double, DerivativeStructure, double, DerivativeStructure, double, DerivativeStructure, double, DerivativeStructure)
-     * @since 3.2
-     */
-    public static 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(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
-
-    }
-
-    /**
-     * 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>
-     * @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(DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure)
-     * @see #linearCombination(DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure)
-     * @since 3.2
-     */
-    public static 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(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
-
-    }
-
-    /**
-     * 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>
-     * @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, DerivativeStructure, double, DerivativeStructure)
-     * @see #linearCombination(double, DerivativeStructure, double, DerivativeStructure, double, DerivativeStructure, double, DerivativeStructure)
-     * @since 3.2
-     */
-    public static 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(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
-
-    }
-
-    /**
-     * 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>
-     * @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(DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure)
-     * @see #linearCombination(DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure, DerivativeStructure)
-     * @since 3.2
-     */
-    public static 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(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
-
-    }
-
-    /**
-     * 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>
-     * @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, DerivativeStructure, double, DerivativeStructure)
-     * @see #linearCombination(double, DerivativeStructure, double, DerivativeStructure, double, DerivativeStructure)
-     * @since 3.2
-     */
-    public static 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(simpleValue.getFreeParameters(), simpleValue.getOrder(), data);
-
-    }
-
-    /**
      * Returns true iff both arguments are null or have same dimensions and all
      * their elements are equal as defined by
      * {@link Precision#equals(float,float)}.
@@ -1620,4 +1275,50 @@ public class MathArrays {
          }
          return out;
      }
+
+     /** Build an array of elements.
+      * <p>
+      * Arrays are filled with field.getZero()
+      * </p>
+      * @param <T> the type of the field elements
+      * @param field field to which array elements belong
+      * @param length of the array
+      * @return a new array
+      */
+     public static <T> T[] buildArray(final Field<T> field, final int length) {
+         @SuppressWarnings("unchecked") // OK because field must be correct class
+         T[] array = (T[]) Array.newInstance(field.getRuntimeClass(), length);
+         Arrays.fill(array, field.getZero());
+         return array;
+     }
+
+     /** Build a double dimension  array of elements.
+      * <p>
+      * Arrays are filled with field.getZero()
+      * </p>
+      * @param <T> the type of the field elements
+      * @param field field to which array elements belong
+      * @param rows number of rows in the array
+     * @param columns number of columns (may be negative to build partial
+     * arrays in the same way <code>new Field[rows][]</code> works)
+      * @return a new array
+      */
+     @SuppressWarnings("unchecked")
+    public static <T> T[][] buildArray(final Field<T> field, final int rows, final int columns) {
+         final T[][] array;
+         if (columns < 0) {
+             T[] dummyRow = buildArray(field, 0);
+             array = (T[][]) Array.newInstance(dummyRow.getClass(), rows);
+         } else {
+             array = (T[][]) Array.newInstance(field.getRuntimeClass(),
+                                               new int[] {
+                                                   rows, columns
+                                               });
+             for (int i = 0; i < rows; ++i) {
+                 Arrays.fill(array[i], field.getZero());
+             }
+         }
+         return array;
+     }
+
 }

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=1449529&r1=1449528&r2=1449529&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 Sun Feb 24 19:13:17 2013
@@ -24,6 +24,7 @@ import org.apache.commons.math3.TestUtil
 import org.apache.commons.math3.analysis.polynomials.PolynomialFunction;
 import org.apache.commons.math3.exception.DimensionMismatchException;
 import org.apache.commons.math3.exception.NumberIsTooLargeException;
+import org.apache.commons.math3.random.Well1024a;
 import org.apache.commons.math3.util.ArithmeticUtils;
 import org.apache.commons.math3.util.FastMath;
 import org.junit.Assert;
@@ -1268,6 +1269,147 @@ public class DerivativeStructureTest {
     }
 
     @Test
+    public void testLinearCombination1DSDS() {
+        final DerivativeStructure[] a = new DerivativeStructure[] {
+            new DerivativeStructure(6, 1, 0, -1321008684645961.0 / 268435456.0),
+            new DerivativeStructure(6, 1, 1, -5774608829631843.0 / 268435456.0),
+            new DerivativeStructure(6, 1, 2, -7645843051051357.0 / 8589934592.0)
+        };
+        final DerivativeStructure[] b = new DerivativeStructure[] {
+            new DerivativeStructure(6, 1, 3, -5712344449280879.0 / 2097152.0),
+            new DerivativeStructure(6, 1, 4, -4550117129121957.0 / 2097152.0),
+            new DerivativeStructure(6, 1, 5, 8846951984510141.0 / 131072.0)
+        };
+
+        final DerivativeStructure abSumInline = a[0].linearCombination(a[0], b[0], a[1], b[1], a[2], b[2]);
+        final DerivativeStructure abSumArray = a[0].linearCombination(a, b);
+
+        Assert.assertEquals(abSumInline.getValue(), abSumArray.getValue(), 0);
+        Assert.assertEquals(-1.8551294182586248737720779899, abSumInline.getValue(), 1.0e-15);
+        Assert.assertEquals(b[0].getValue(), abSumInline.getPartialDerivative(1, 0, 0, 0, 0, 0), 1.0e-15);
+        Assert.assertEquals(b[1].getValue(), abSumInline.getPartialDerivative(0, 1, 0, 0, 0, 0), 1.0e-15);
+        Assert.assertEquals(b[2].getValue(), abSumInline.getPartialDerivative(0, 0, 1, 0, 0, 0), 1.0e-15);
+        Assert.assertEquals(a[0].getValue(), abSumInline.getPartialDerivative(0, 0, 0, 1, 0, 0), 1.0e-15);
+        Assert.assertEquals(a[1].getValue(), abSumInline.getPartialDerivative(0, 0, 0, 0, 1, 0), 1.0e-15);
+        Assert.assertEquals(a[2].getValue(), abSumInline.getPartialDerivative(0, 0, 0, 0, 0, 1), 1.0e-15);
+
+    }
+
+    @Test
+    public void testLinearCombination1DoubleDS() {
+        final double[] a = new double[] {
+            -1321008684645961.0 / 268435456.0,
+            -5774608829631843.0 / 268435456.0,
+            -7645843051051357.0 / 8589934592.0
+        };
+        final DerivativeStructure[] b = new DerivativeStructure[] {
+            new DerivativeStructure(3, 1, 0, -5712344449280879.0 / 2097152.0),
+            new DerivativeStructure(3, 1, 1, -4550117129121957.0 / 2097152.0),
+            new DerivativeStructure(3, 1, 2, 8846951984510141.0 / 131072.0)
+        };
+
+        final DerivativeStructure abSumInline = b[0].linearCombination(a[0], b[0],
+                                                                       a[1], b[1],
+                                                                       a[2], b[2]);
+        final DerivativeStructure abSumArray = b[0].linearCombination(a, b);
+
+        Assert.assertEquals(abSumInline.getValue(), abSumArray.getValue(), 0);
+        Assert.assertEquals(-1.8551294182586248737720779899, abSumInline.getValue(), 1.0e-15);
+        Assert.assertEquals(a[0], abSumInline.getPartialDerivative(1, 0, 0), 1.0e-15);
+        Assert.assertEquals(a[1], abSumInline.getPartialDerivative(0, 1, 0), 1.0e-15);
+        Assert.assertEquals(a[2], abSumInline.getPartialDerivative(0, 0, 1), 1.0e-15);
+
+    }
+
+    @Test
+    public void testLinearCombination2DSDS() {
+        // we compare accurate versus naive dot product implementations
+        // on regular vectors (i.e. not extreme cases like in the previous test)
+        Well1024a random = new Well1024a(0xc6af886975069f11l);
+
+        for (int i = 0; i < 10000; ++i) {
+            final DerivativeStructure[] u = new DerivativeStructure[4];
+            final DerivativeStructure[] v = new DerivativeStructure[4];
+            for (int j = 0; j < u.length; ++j) {
+                u[j] = new DerivativeStructure(u.length, 1, j, 1e17 * random.nextDouble());
+                v[j] = new DerivativeStructure(u.length, 1, 1e17 * random.nextDouble());
+            }
+
+            DerivativeStructure lin = u[0].linearCombination(u[0], v[0], u[1], v[1]);
+            double ref = u[0].getValue() * v[0].getValue() +
+                         u[1].getValue() * v[1].getValue();
+            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
+            Assert.assertEquals(v[0].getValue(), lin.getPartialDerivative(1, 0, 0, 0), 1.0e-15 * FastMath.abs(v[0].getValue()));
+            Assert.assertEquals(v[1].getValue(), lin.getPartialDerivative(0, 1, 0, 0), 1.0e-15 * FastMath.abs(v[1].getValue()));
+
+            lin = u[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2]);
+            ref = u[0].getValue() * v[0].getValue() +
+                  u[1].getValue() * v[1].getValue() +
+                  u[2].getValue() * v[2].getValue();
+            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
+            Assert.assertEquals(v[0].getValue(), lin.getPartialDerivative(1, 0, 0, 0), 1.0e-15 * FastMath.abs(v[0].getValue()));
+            Assert.assertEquals(v[1].getValue(), lin.getPartialDerivative(0, 1, 0, 0), 1.0e-15 * FastMath.abs(v[1].getValue()));
+            Assert.assertEquals(v[2].getValue(), lin.getPartialDerivative(0, 0, 1, 0), 1.0e-15 * FastMath.abs(v[2].getValue()));
+
+            lin = u[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2], u[3], v[3]);
+            ref = u[0].getValue() * v[0].getValue() +
+                  u[1].getValue() * v[1].getValue() +
+                  u[2].getValue() * v[2].getValue() +
+                  u[3].getValue() * v[3].getValue();
+            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
+            Assert.assertEquals(v[0].getValue(), lin.getPartialDerivative(1, 0, 0, 0), 1.0e-15 * FastMath.abs(v[0].getValue()));
+            Assert.assertEquals(v[1].getValue(), lin.getPartialDerivative(0, 1, 0, 0), 1.0e-15 * FastMath.abs(v[1].getValue()));
+            Assert.assertEquals(v[2].getValue(), lin.getPartialDerivative(0, 0, 1, 0), 1.0e-15 * FastMath.abs(v[2].getValue()));
+            Assert.assertEquals(v[3].getValue(), lin.getPartialDerivative(0, 0, 0, 1), 1.0e-15 * FastMath.abs(v[3].getValue()));
+
+        }
+    }
+
+    @Test
+    public void testLinearCombination2DoubleDS() {
+        // we compare accurate versus naive dot product implementations
+        // on regular vectors (i.e. not extreme cases like in the previous test)
+        Well1024a random = new Well1024a(0xc6af886975069f11l);
+
+        for (int i = 0; i < 10000; ++i) {
+            final double[] u = new double[4];
+            final DerivativeStructure[] v = new DerivativeStructure[4];
+            for (int j = 0; j < u.length; ++j) {
+                u[j] = 1e17 * random.nextDouble();
+                v[j] = new DerivativeStructure(u.length, 1, j, 1e17 * random.nextDouble());
+            }
+
+            DerivativeStructure lin = v[0].linearCombination(u[0], v[0], u[1], v[1]);
+            double ref = u[0] * v[0].getValue() +
+                         u[1] * v[1].getValue();
+            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
+            Assert.assertEquals(u[0], lin.getPartialDerivative(1, 0, 0, 0), 1.0e-15 * FastMath.abs(v[0].getValue()));
+            Assert.assertEquals(u[1], lin.getPartialDerivative(0, 1, 0, 0), 1.0e-15 * FastMath.abs(v[1].getValue()));
+
+            lin = v[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2]);
+            ref = u[0] * v[0].getValue() +
+                  u[1] * v[1].getValue() +
+                  u[2] * v[2].getValue();
+            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
+            Assert.assertEquals(u[0], lin.getPartialDerivative(1, 0, 0, 0), 1.0e-15 * FastMath.abs(v[0].getValue()));
+            Assert.assertEquals(u[1], lin.getPartialDerivative(0, 1, 0, 0), 1.0e-15 * FastMath.abs(v[1].getValue()));
+            Assert.assertEquals(u[2], lin.getPartialDerivative(0, 0, 1, 0), 1.0e-15 * FastMath.abs(v[2].getValue()));
+
+            lin = v[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2], u[3], v[3]);
+            ref = u[0] * v[0].getValue() +
+                  u[1] * v[1].getValue() +
+                  u[2] * v[2].getValue() +
+                  u[3] * v[3].getValue();
+            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
+            Assert.assertEquals(u[0], lin.getPartialDerivative(1, 0, 0, 0), 1.0e-15 * FastMath.abs(v[0].getValue()));
+            Assert.assertEquals(u[1], lin.getPartialDerivative(0, 1, 0, 0), 1.0e-15 * FastMath.abs(v[1].getValue()));
+            Assert.assertEquals(u[2], lin.getPartialDerivative(0, 0, 1, 0), 1.0e-15 * FastMath.abs(v[2].getValue()));
+            Assert.assertEquals(u[3], lin.getPartialDerivative(0, 0, 0, 1), 1.0e-15 * FastMath.abs(v[3].getValue()));
+
+        }
+    }
+
+    @Test
     public void testSerialization() {
         DerivativeStructure a = new DerivativeStructure(3, 2, 0, 1.3);
         DerivativeStructure b = (DerivativeStructure) TestUtils.serializeAndRecover(a);

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/dfp/DfpTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/dfp/DfpTest.java?rev=1449529&r1=1449528&r2=1449529&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/dfp/DfpTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/dfp/DfpTest.java Sun Feb 24 19:13:17 2013
@@ -1435,23 +1435,23 @@ public class DfpTest {
     public void testLog10()
     {
 
-        Assert.assertEquals("log10 #1", 1, field.newDfp("12").log10());
-        Assert.assertEquals("log10 #2", 2, field.newDfp("123").log10());
-        Assert.assertEquals("log10 #3", 3, field.newDfp("1234").log10());
-        Assert.assertEquals("log10 #4", 4, field.newDfp("12345").log10());
-        Assert.assertEquals("log10 #5", 5, field.newDfp("123456").log10());
-        Assert.assertEquals("log10 #6", 6, field.newDfp("1234567").log10());
-        Assert.assertEquals("log10 #6", 7, field.newDfp("12345678").log10());
-        Assert.assertEquals("log10 #7", 8, field.newDfp("123456789").log10());
-        Assert.assertEquals("log10 #8", 9, field.newDfp("1234567890").log10());
-        Assert.assertEquals("log10 #9", 10, field.newDfp("12345678901").log10());
-        Assert.assertEquals("log10 #10", 11, field.newDfp("123456789012").log10());
-        Assert.assertEquals("log10 #11", 12, field.newDfp("1234567890123").log10());
-
-        Assert.assertEquals("log10 #12", 0, field.newDfp("2").log10());
-        Assert.assertEquals("log10 #13", 0, field.newDfp("1").log10());
-        Assert.assertEquals("log10 #14", -1, field.newDfp("0.12").log10());
-        Assert.assertEquals("log10 #15", -2, field.newDfp("0.012").log10());
+        Assert.assertEquals("log10 #1", 1, field.newDfp("12").intLog10());
+        Assert.assertEquals("log10 #2", 2, field.newDfp("123").intLog10());
+        Assert.assertEquals("log10 #3", 3, field.newDfp("1234").intLog10());
+        Assert.assertEquals("log10 #4", 4, field.newDfp("12345").intLog10());
+        Assert.assertEquals("log10 #5", 5, field.newDfp("123456").intLog10());
+        Assert.assertEquals("log10 #6", 6, field.newDfp("1234567").intLog10());
+        Assert.assertEquals("log10 #6", 7, field.newDfp("12345678").intLog10());
+        Assert.assertEquals("log10 #7", 8, field.newDfp("123456789").intLog10());
+        Assert.assertEquals("log10 #8", 9, field.newDfp("1234567890").intLog10());
+        Assert.assertEquals("log10 #9", 10, field.newDfp("12345678901").intLog10());
+        Assert.assertEquals("log10 #10", 11, field.newDfp("123456789012").intLog10());
+        Assert.assertEquals("log10 #11", 12, field.newDfp("1234567890123").intLog10());
+
+        Assert.assertEquals("log10 #12", 0, field.newDfp("2").intLog10());
+        Assert.assertEquals("log10 #13", 0, field.newDfp("1").intLog10());
+        Assert.assertEquals("log10 #14", -1, field.newDfp("0.12").intLog10());
+        Assert.assertEquals("log10 #15", -2, field.newDfp("0.012").intLog10());
     }
 
     @Test