Added accurate linear combinations for DerivativeStructure instances.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1446210 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
81eddba084
commit
ef76ef299e
|
@ -55,6 +55,10 @@ This is a minor release: It combines bug fixes and new features.
|
|||
Changes to existing features were made in a backwards-compatible
|
||||
way such as to allow drop-in replacement of the v3.1[.1] JAR file.
|
||||
">
|
||||
<action dev="luc" type="add" >
|
||||
Added accurate linear combination of DerivativeStructure instances,
|
||||
avoiding cancellation.
|
||||
</action>
|
||||
<action dev="erans" type="update" issue="MATH-933">
|
||||
Throw "MathUnsupportedOperationException" from optimizers that do
|
||||
not support constraints (previous behaviour was to silently ignore
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
|||
import java.util.Comparator;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
|
||||
import org.apache.commons.math3.exception.DimensionMismatchException;
|
||||
import org.apache.commons.math3.exception.MathInternalError;
|
||||
import org.apache.commons.math3.exception.NonMonotonicSequenceException;
|
||||
|
@ -1117,6 +1118,353 @@ public class MathArrays {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
package org.apache.commons.math3.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
|
||||
import org.apache.commons.math3.exception.NonMonotonicSequenceException;
|
||||
import org.apache.commons.math3.exception.DimensionMismatchException;
|
||||
import org.apache.commons.math3.exception.NotPositiveException;
|
||||
|
@ -537,6 +539,11 @@ public class MathArraysTest {
|
|||
final double abSumArray = MathArrays.linearCombination(a, b);
|
||||
|
||||
Assert.assertEquals(abSumInline, abSumArray, 0);
|
||||
Assert.assertEquals(-1.8551294182586248737720779899, abSumInline, 1.0e-15);
|
||||
|
||||
final double naive = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
Assert.assertTrue(FastMath.abs(naive - abSumInline) > 1.5);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -713,6 +720,149 @@ public class MathArraysTest {
|
|||
Assert.assertTrue(Double.isNaN(MathArrays.linearCombination(a[7], b[7])));
|
||||
}
|
||||
|
||||
@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 = MathArrays.linearCombination(a[0], b[0],
|
||||
a[1], b[1],
|
||||
a[2], b[2]);
|
||||
final DerivativeStructure abSumArray = MathArrays.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 = MathArrays.linearCombination(a[0], b[0],
|
||||
a[1], b[1],
|
||||
a[2], b[2]);
|
||||
final DerivativeStructure abSumArray = MathArrays.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 = MathArrays.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 = MathArrays.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 = MathArrays.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 = MathArrays.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 = MathArrays.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 = MathArrays.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 testArrayEquals() {
|
||||
Assert.assertFalse(MathArrays.equals(new double[] { 1d }, null));
|
||||
|
|
Loading…
Reference in New Issue