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);
+       }
+   }
 }


Reply via email to