Author: erans
Date: Fri Oct 14 14:50:38 2011
New Revision: 1183373
URL: http://svn.apache.org/viewvc?rev=1183373&view=rev
Log:
Added "derivative".
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/function/Sinc.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/function/SincTest.java
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/function/Sinc.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/function/Sinc.java?rev=1183373&r1=1183372&r2=1183373&view=diff
==============================================================================
---
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/function/Sinc.java
(original)
+++
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/function/Sinc.java
Fri Oct 14 14:50:38 2011
@@ -18,6 +18,7 @@
package org.apache.commons.math.analysis.function;
import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
import org.apache.commons.math.util.FastMath;
/**
@@ -31,7 +32,13 @@ import org.apache.commons.math.util.Fast
* @version $Id$
* @since 3.0
*/
-public class Sinc implements UnivariateRealFunction {
+public class Sinc implements DifferentiableUnivariateRealFunction {
+ /**
+ * Value below which the result of the computation will not change
+ * anymore due to the finite precision of the "double" representation
+ * of real numbers.
+ */
+ private static final double SHORTCUT = 1e-9;
/** For normalized sinc function. */
private final boolean normalized;
@@ -62,6 +69,26 @@ public class Sinc implements UnivariateR
}
}
+ /** {@inheritDoc} */
+ public UnivariateRealFunction derivative() {
+ if (normalized) {
+ return new UnivariateRealFunction() {
+ /** {@inheritDoc} */
+ public double value(double x) {
+ final double piTimesX = Math.PI * x;
+ return sincDerivative(piTimesX);
+ }
+ };
+ } else {
+ return new UnivariateRealFunction() {
+ /** {@inheritDoc} */
+ public double value(double x) {
+ return sincDerivative(x);
+ }
+ };
+ }
+ }
+
/**
* @param x Argument.
* @return {@code sin(x) / x}.
@@ -71,6 +98,20 @@ public class Sinc implements UnivariateR
// optimization on the ground that the result of the full computation
// is indistinguishable from 1 due to the limited accuracy of the
// floating point representation.
- return FastMath.abs(x) < 1e-9 ? 1 : FastMath.sin(x) / x;
+ return FastMath.abs(x) < SHORTCUT ? 1 :
+ FastMath.sin(x) / x;
+ }
+
+ /**
+ * @param x Argument.
+ * @return {@code (cos(x) - sin(x) / x) / x}.
+ */
+ private static double sincDerivative(double x) {
+ // The direct assignment to 0 for values below 1e-9 is an efficiency
+ // optimization on the ground that the result of the full computation
+ // is indistinguishable from 1 due to the limited accuracy of the
+ // floating point representation.
+ return FastMath.abs(x) < SHORTCUT ? 0 :
+ (FastMath.cos(x) - FastMath.sin(x) / x) / x;
}
}
Modified:
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/function/SincTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/function/SincTest.java?rev=1183373&r1=1183372&r2=1183373&view=diff
==============================================================================
---
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/function/SincTest.java
(original)
+++
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/function/SincTest.java
Fri Oct 14 14:50:38 2011
@@ -34,7 +34,7 @@ public class SincTest {
}
};
- for (double x = 1e-30; x < 1e10; x *= 5) {
+ for (double x = 1e-30; x < 1e10; x *= 2) {
final double fX = f.value(x);
final double sX = s.value(x);
Assert.assertEquals("x=" + x, fX, sX, 0);
@@ -69,4 +69,27 @@ public class SincTest {
}
Assert.assertEquals(prod, s.value(x), 1e-13);
}
+
+ @Test
+ public void testDerivativeZero() {
+ final UnivariateRealFunction sPrime = (new Sinc(true)).derivative();
+
+ Assert.assertEquals(0, sPrime.value(0), 0);
+ }
+
+ @Test
+ public void testDerivativeShortcut() {
+ final UnivariateRealFunction sPrime = (new Sinc()).derivative();
+ final UnivariateRealFunction f = new UnivariateRealFunction() {
+ public double value(double x) {
+ return (FastMath.cos(x) - FastMath.sin(x) / x) / x;
+ }
+ };
+
+ for (double x = 1e-30; x < 1e10; x *= 2) {
+ final double fX = f.value(x);
+ final double sX = sPrime.value(x);
+ Assert.assertEquals("x=" + x, fX, sX, 0);
+ }
+ }
}