From 64a7948cee2c83e44bb51b7cb7b282a915557b1d Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Fri, 17 Aug 2012 07:15:28 +0000 Subject: [PATCH] Added log10 to DerivativeStructure and DSCompiler. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1374162 13f79535-47bb-0310-9956-ffa450edef68 --- .../analysis/differentiation/DSCompiler.java | 32 +++++++++++++++++-- .../differentiation/DerivativeStructure.java | 9 ++++++ .../DerivativeStructureTest.java | 31 ++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/math3/analysis/differentiation/DSCompiler.java b/src/main/java/org/apache/commons/math3/analysis/differentiation/DSCompiler.java index de9516bc8..1b3cc675d 100644 --- a/src/main/java/org/apache/commons/math3/analysis/differentiation/DSCompiler.java +++ b/src/main/java/org/apache/commons/math3/analysis/differentiation/DSCompiler.java @@ -1023,11 +1023,11 @@ public class DSCompiler { } - /** Computes of a derivative structure. + /** Computes shifted logarithm of a derivative structure. * @param operand array holding the operand * @param operandOffset offset of the operand in its array * @param result array where result must be stored (for - * logarithm the result array cannot be the input + * shifted logarithm the result array cannot be the input * array) */ public void log1p(final double[] operand, final int operandOffset, @@ -1051,6 +1051,34 @@ public class DSCompiler { } + /** Computes base 10 logarithm of a derivative structure. + * @param operand array holding the operand + * @param operandOffset offset of the operand in its array + * @param result array where result must be stored (for + * base 10 logarithm the result array cannot be the input + * array) + */ + public void log10(final double[] operand, final int operandOffset, + final double[] result, final int resultOffset) { + + + // create the function value and derivatives + double[] function = new double[1 + order]; + function[0] = FastMath.log10(operand[operandOffset]); + if (order > 0) { + double inv = 1.0 / operand[operandOffset]; + double xk = inv / FastMath.log(10.0); + for (int i = 1; i <= order; ++i) { + function[i] = xk; + xk *= -i * inv; + } + } + + // apply function composition + compose(operand, operandOffset, function, result, resultOffset); + + } + /** Compute cosine of a derivative structure. * @param operand array holding the operand * @param operandOffset offset of the operand in its array diff --git a/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java b/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java index c7023dafb..6778d1fe0 100644 --- a/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java +++ b/src/main/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.java @@ -636,6 +636,15 @@ public class DerivativeStructure implements FieldElement, S return result; } + /** Base 10 logarithm. + * @return base 10 logarithm of the instance + */ + public DerivativeStructure log10() { + final DerivativeStructure result = new DerivativeStructure(compiler); + compiler.log10(data, 0, result.data, 0); + return result; + } + /** Cosine operation. * @return cos(this) */ diff --git a/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java b/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java index 1685d436b..996592ca7 100644 --- a/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java +++ b/src/test/java/org/apache/commons/math3/analysis/differentiation/DerivativeStructureTest.java @@ -502,6 +502,22 @@ public class DerivativeStructureTest { } } + @Test + public void testLog10Definition() { + double[] epsilon = new double[] { 3.0e-16, 3.0e-16, 8.0e-15, 3.0e-13, 8.0e-12 }; + for (int maxOrder = 0; maxOrder < 5; ++maxOrder) { + for (double x = 0.1; x < 1.2; x += 0.001) { + DerivativeStructure dsX = new DerivativeStructure(1, maxOrder, 0, x); + DerivativeStructure log101 = dsX.log10(); + DerivativeStructure log102 = dsX.log().divide(FastMath.log(10.0)); + DerivativeStructure zero = log101.subtract(log102); + for (int n = 0; n <= maxOrder; ++n) { + Assert.assertEquals(0, zero.getPartialDerivative(n), epsilon[n]); + } + } + } + } + @Test public void testLogExp() { double[] epsilon = new double[] { 2.0e-16, 2.0e-16, 3.0e-16, 2.0e-15, 6.0e-15 }; @@ -532,6 +548,21 @@ public class DerivativeStructureTest { } } + @Test + public void testLog10Power() { + double[] epsilon = new double[] { 3.0e-16, 3.0e-16, 9.0e-16, 6.0e-15, 6.0e-14 }; + for (int maxOrder = 0; maxOrder < 5; ++maxOrder) { + for (double x = 0.1; x < 1.2; x += 0.001) { + DerivativeStructure dsX = new DerivativeStructure(1, maxOrder, 0, x); + DerivativeStructure rebuiltX = new DerivativeStructure(1, maxOrder, 10.0).pow(dsX).log10(); + DerivativeStructure zero = rebuiltX.subtract(dsX); + for (int n = 0; n <= maxOrder; ++n) { + Assert.assertEquals(0, zero.getPartialDerivative(n), epsilon[n]); + } + } + } + } + @Test public void testSinCos() { double epsilon = 5.0e-16;