"add", "multiply", "compose" instances of "DifferentiableUnivariateRealFunction".
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1185351 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9227754177
commit
976c85755d
|
@ -52,6 +52,43 @@ public class FunctionUtils {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose functions. The functions in the argument list are composed
|
||||
* sequentially, in the order given. For example, compose(f1,f2,f3)
|
||||
* acts like f1(f2(f3(x))).
|
||||
*
|
||||
* @param f List of functions.
|
||||
* @return the composite function.
|
||||
*/
|
||||
public static DifferentiableUnivariateRealFunction compose(final DifferentiableUnivariateRealFunction ... f) {
|
||||
return new DifferentiableUnivariateRealFunction() {
|
||||
/** {@inheritDoc} */
|
||||
public double value(double x) {
|
||||
double r = x;
|
||||
for (int i = f.length - 1; i >= 0; i--) {
|
||||
r = f[i].value(r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public UnivariateRealFunction derivative() {
|
||||
return new UnivariateRealFunction() {
|
||||
/** {@inheritDoc} */
|
||||
public double value(double x) {
|
||||
double p = 1;
|
||||
double r = x;
|
||||
for (int i = f.length - 1; i >= 0; i--) {
|
||||
p *= f[i].derivative().value(r);
|
||||
r = f[i].value(r);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Add functions.
|
||||
*
|
||||
|
@ -71,6 +108,39 @@ public class FunctionUtils {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Add functions.
|
||||
*
|
||||
* @param f List of functions.
|
||||
* @return a function that computes the sum of the functions.
|
||||
*/
|
||||
public static DifferentiableUnivariateRealFunction add(final DifferentiableUnivariateRealFunction ... f) {
|
||||
return new DifferentiableUnivariateRealFunction() {
|
||||
/** {@inheritDoc} */
|
||||
public double value(double x) {
|
||||
double r = f[0].value(x);
|
||||
for (int i = 1; i < f.length; i++) {
|
||||
r += f[i].value(x);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public UnivariateRealFunction derivative() {
|
||||
return new UnivariateRealFunction() {
|
||||
/** {@inheritDoc} */
|
||||
public double value(double x) {
|
||||
double r = f[0].derivative().value(x);
|
||||
for (int i = 1; i < f.length; i++) {
|
||||
r += f[i].derivative().value(x);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply functions.
|
||||
*
|
||||
|
@ -90,6 +160,45 @@ public class FunctionUtils {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply functions.
|
||||
*
|
||||
* @param f List of functions.
|
||||
* @return a function that computes the product of the functions.
|
||||
*/
|
||||
public static DifferentiableUnivariateRealFunction multiply(final DifferentiableUnivariateRealFunction ... f) {
|
||||
return new DifferentiableUnivariateRealFunction() {
|
||||
/** {@inheritDoc} */
|
||||
public double value(double x) {
|
||||
double r = f[0].value(x);
|
||||
for (int i = 1; i < f.length; i++) {
|
||||
r *= f[i].value(x);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public UnivariateRealFunction derivative() {
|
||||
return new UnivariateRealFunction() {
|
||||
/** {@inheritDoc} */
|
||||
public double value(double x) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < f.length; i++) {
|
||||
double prod = f[i].derivative().value(x);
|
||||
for (int j = 0; j < f.length; j++) {
|
||||
if (i != j) {
|
||||
prod *= f[j].value(x);
|
||||
}
|
||||
}
|
||||
sum += prod;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the univariate function <br/>
|
||||
* {@code h(x) = combiner(f(x), g(x))}.
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.apache.commons.math.analysis.function.Inverse;
|
|||
import org.apache.commons.math.analysis.function.Power;
|
||||
import org.apache.commons.math.analysis.function.Sin;
|
||||
import org.apache.commons.math.analysis.function.Sinc;
|
||||
import org.apache.commons.math.analysis.function.Cos;
|
||||
import org.apache.commons.math.analysis.function.Cosh;
|
||||
import org.apache.commons.math.analysis.BivariateRealFunction;
|
||||
import org.apache.commons.math.analysis.function.Add;
|
||||
import org.apache.commons.math.analysis.function.Multiply;
|
||||
|
@ -32,6 +34,7 @@ import org.apache.commons.math.analysis.function.Divide;
|
|||
import org.apache.commons.math.analysis.function.Min;
|
||||
import org.apache.commons.math.analysis.function.Max;
|
||||
import org.apache.commons.math.analysis.function.Pow;
|
||||
import org.apache.commons.math.analysis.function.Log;
|
||||
import org.apache.commons.math.analysis.MultivariateRealFunction;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
@ -63,6 +66,31 @@ public class FunctionUtilsTest {
|
|||
Assert.assertEquals(81, FunctionUtils.compose(pow, pow).value(3), EPS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComposeDifferentiable() {
|
||||
DifferentiableUnivariateRealFunction id = new Identity();
|
||||
Assert.assertEquals(1, FunctionUtils.compose(id, id, id).derivative().value(3), EPS);
|
||||
|
||||
DifferentiableUnivariateRealFunction c = new Constant(4);
|
||||
Assert.assertEquals(0, FunctionUtils.compose(id, c).derivative().value(3), EPS);
|
||||
Assert.assertEquals(0, FunctionUtils.compose(c, id).derivative().value(3), EPS);
|
||||
|
||||
DifferentiableUnivariateRealFunction m = new Minus();
|
||||
Assert.assertEquals(-1, FunctionUtils.compose(m).derivative().value(3), EPS);
|
||||
Assert.assertEquals(1, FunctionUtils.compose(m, m).derivative().value(3), EPS);
|
||||
|
||||
DifferentiableUnivariateRealFunction inv = new Inverse();
|
||||
Assert.assertEquals(0.25, FunctionUtils.compose(inv, m, id).derivative().value(2), EPS);
|
||||
|
||||
DifferentiableUnivariateRealFunction pow = new Power(2);
|
||||
Assert.assertEquals(108, FunctionUtils.compose(pow, pow).derivative().value(3), EPS);
|
||||
|
||||
DifferentiableUnivariateRealFunction log = new Log();
|
||||
double a = 9876.54321;
|
||||
Assert.assertEquals(pow.derivative().value(a) / pow.value(a),
|
||||
FunctionUtils.compose(log, pow).derivative().value(a), EPS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() {
|
||||
UnivariateRealFunction id = new Identity();
|
||||
|
@ -75,6 +103,19 @@ public class FunctionUtilsTest {
|
|||
Assert.assertEquals(4 - 2, FunctionUtils.add(c, FunctionUtils.compose(m, id)).value(2), EPS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddDifferentiable() {
|
||||
DifferentiableUnivariateRealFunction sin = new Sin();
|
||||
DifferentiableUnivariateRealFunction c = new Constant(4);
|
||||
DifferentiableUnivariateRealFunction m = new Minus();
|
||||
DifferentiableUnivariateRealFunction inv = new Inverse();
|
||||
|
||||
final double a = 123.456;
|
||||
Assert.assertEquals(- 1 / (a * a) -1 + Math.cos(a),
|
||||
FunctionUtils.add(inv, m, c, sin).derivative().value(a),
|
||||
EPS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiply() {
|
||||
UnivariateRealFunction c = new Constant(4);
|
||||
|
@ -85,6 +126,24 @@ public class FunctionUtilsTest {
|
|||
Assert.assertEquals(1, FunctionUtils.multiply(FunctionUtils.compose(inv, pow), pow).value(3.5), EPS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiplyDifferentiable() {
|
||||
DifferentiableUnivariateRealFunction c = new Constant(4);
|
||||
DifferentiableUnivariateRealFunction id = new Identity();
|
||||
final double a = 1.2345678;
|
||||
Assert.assertEquals(8 * a, FunctionUtils.multiply(c, id, id).derivative().value(a), EPS);
|
||||
|
||||
DifferentiableUnivariateRealFunction inv = new Inverse();
|
||||
DifferentiableUnivariateRealFunction pow = new Power(2.5);
|
||||
DifferentiableUnivariateRealFunction cos = new Cos();
|
||||
Assert.assertEquals(1.5 * Math.sqrt(a) * Math.cos(a) - Math.pow(a, 1.5) * Math.sin(a),
|
||||
FunctionUtils.multiply(inv, pow, cos).derivative().value(a), EPS);
|
||||
|
||||
DifferentiableUnivariateRealFunction cosh = new Cosh();
|
||||
Assert.assertEquals(1.5 * Math.sqrt(a) * Math.cosh(a) + Math.pow(a, 1.5) * Math.sinh(a),
|
||||
FunctionUtils.multiply(inv, pow, cosh).derivative().value(a), 8 * EPS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombine() {
|
||||
BivariateRealFunction bi = new Add();
|
||||
|
|
Loading…
Reference in New Issue