Implement "DifferentiableUnivariateRealFunction".


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1070698 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2011-02-14 23:54:10 +00:00
parent 5a2bf9c657
commit 2686e1efd3
2 changed files with 62 additions and 2 deletions

View File

@ -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.exception.NotStrictlyPositiveException;
import org.apache.commons.math.util.FastMath;
@ -28,7 +29,7 @@ import org.apache.commons.math.util.FastMath;
* @version $Revision$ $Date$
* @since 3.0
*/
public class Gaussian implements UnivariateRealFunction {
public class Gaussian implements DifferentiableUnivariateRealFunction {
/** Mean. */
private final double mean;
/** Inverse of twice the square of the standard deviation. */
@ -80,4 +81,22 @@ public class Gaussian implements UnivariateRealFunction {
final double diff = x - mean;
return norm * FastMath.exp(-diff * diff * i2s2);
}
/** {@inheritDoc} */
public UnivariateRealFunction derivative() {
return new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double x) {
final double diff = x - mean;
final double g = Gaussian.this.value(x);
if (g == 0) {
// Avoid returning NaN in case of overflow.
return 0;
} else {
return -2 * diff * i2s2 * g;
}
}
};
}
}

View File

@ -39,8 +39,49 @@ public class GaussianTest {
public void testSomeValues() {
final UnivariateRealFunction f = new Gaussian();
Assert.assertEquals(0, f.value(Double.NEGATIVE_INFINITY), 0);
Assert.assertEquals(1 / FastMath.sqrt(2 * Math.PI), f.value(0), EPS);
}
@Test
public void testLargeArguments() {
final UnivariateRealFunction f = new Gaussian();
Assert.assertEquals(0, f.value(Double.NEGATIVE_INFINITY), 0);
Assert.assertEquals(0, f.value(-Double.MAX_VALUE), 0);
Assert.assertEquals(0, f.value(-1e2), 0);
Assert.assertEquals(0, f.value(1e2), 0);
Assert.assertEquals(0, f.value(Double.MAX_VALUE), 0);
Assert.assertEquals(0, f.value(Double.POSITIVE_INFINITY), 0);
}
@Test
public void testDerivative() {
final Gaussian f = new Gaussian();
final UnivariateRealFunction dfdx = f.derivative();
Assert.assertEquals(0, dfdx.value(0), 0);
}
@Test
public void testDerivativeLargeArguments() {
final Gaussian f = new Gaussian(0, 1e-50);
final UnivariateRealFunction dfdx = f.derivative();
Assert.assertEquals(0, dfdx.value(Double.NEGATIVE_INFINITY), 0);
Assert.assertEquals(0, dfdx.value(-Double.MAX_VALUE), 0);
Assert.assertEquals(0, f.value(-1e50), 0);
Assert.assertEquals(0, f.value(-1e2), 0);
Assert.assertEquals(0, f.value(1e2), 0);
Assert.assertEquals(0, f.value(1e50), 0);
Assert.assertEquals(0, dfdx.value(Double.MAX_VALUE), 0);
Assert.assertEquals(0, dfdx.value(Double.POSITIVE_INFINITY), 0);
}
@Test
public void testDerivativeNaN() {
final Gaussian f = new Gaussian(0, 1e-50);
final UnivariateRealFunction dfdx = f.derivative();
Assert.assertTrue(Double.isNaN(dfdx.value(Double.NaN)));
}
}