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 (α) around Z
+ * (0 is +X, π/2 is +Y, π is -X and 3π/2 is -Y)
+ * @param delta elevation (δ) above (XY) plane, from -π/2 to +π/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>∞</sub> norm for the vector.
+ * @return L<sub>∞</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 (α) of the vector, between -π and +π
+ * @see #Vector3D(T, T)
+ */
+ public T getAlpha() {
+ return y.atan2(x);
+ }
+
+ /** Get the elevation of the vector.
+ * @return elevation (δ) of the vector, between -π/2 and +π/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>∞</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>∞</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>∞</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>∞</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>Σ<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>Σ<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>×b<sub>1</sub> +
- * a<sub>2</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> +
- * a<sub>4</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> +
- * a<sub>4</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> +
- * a<sub>4</sub>×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>×b<sub>1</sub> +
- * a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> +
- * a<sub>4</sub>×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