added composition features for real functions

JIRA: MATH-313

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@890002 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2009-12-12 23:15:32 +00:00
parent 06c388acc9
commit 6a5848130f
8 changed files with 861 additions and 248 deletions

View File

@ -0,0 +1,110 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
/**
* Base class for {@link BivariateRealFunction} that can be composed with other functions.
*
* @version $Revision$ $Date$
*/
public abstract class BinaryFunction implements BivariateRealFunction {
/** The + operator method wrapped as a {@link BinaryFunction}. */
public static final BinaryFunction ADD = new BinaryFunction() {
/** {@inheritDoc} */
public double value(double x, double y) {
return x + y;
}
};
/** The - operator method wrapped as a {@link BinaryFunction}. */
public static final BinaryFunction SUBTRACT = new BinaryFunction() {
/** {@inheritDoc} */
public double value(double x, double y) {
return x - y;
}
};
/** The * operator method wrapped as a {@link BinaryFunction}. */
public static final BinaryFunction MULTIPLY = new BinaryFunction() {
/** {@inheritDoc} */
public double value(double x, double y) {
return x * y;
}
};
/** The / operator method wrapped as a {@link BinaryFunction}. */
public static final BinaryFunction DIVIDE = new BinaryFunction() {
/** {@inheritDoc} */
public double value(double x, double y) {
return x / y;
}
};
/** The {@code Math.pow} method wrapped as a {@link BinaryFunction}. */
public static final BinaryFunction POW = new BinaryFunction() {
/** {@inheritDoc} */
public double value(double x, double y) {
return Math.pow(x, y);
}
};
/** The {@code Math.atan2} method wrapped as a {@link BinaryFunction}. */
public static final BinaryFunction ATAN2 = new BinaryFunction() {
/** {@inheritDoc} */
public double value(double x, double y) {
return Math.atan2(x, y);
}
};
/** {@inheritDoc} */
public abstract double value(double x, double y) throws FunctionEvaluationException;
/** Get a composable function by fixing the first argument of the instance.
* @param fixedX fixed value of the first argument
* @return a function such that {@code f.value(y) == value(fixedX, y)}
*/
public ComposableFunction fix1stArgument(final double fixedX) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return BinaryFunction.this.value(fixedX, x);
}
};
}
/** Get a composable function by fixing the second argument of the instance.
* @param fixedY fixed value of the second argument
* @return a function such that {@code f.value(x) == value(x, fixedY)}
*/
public ComposableFunction fix2ndArgument(final double fixedY) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return BinaryFunction.this.value(x, fixedY);
}
};
}
}

View File

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
/**
* An interface representing a bivariate real function.
*
* @version $Revision$ $Date$
*/
public interface BivariateRealFunction {
/**
* Compute the value for the function.
* @param x abscissa for which the function value should be computed
* @param y ordinate for which the function value should be computed
* @return the value
* @throws FunctionEvaluationException if the function evaluation fails
*/
double value(double x, double y) throws FunctionEvaluationException;
}

View File

@ -0,0 +1,462 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
/**
* Base class for {@link UnivariateRealFunction} that can be composed with other functions.
*
* @version $Revision$ $Date$
*/
public abstract class ComposableFunction implements UnivariateRealFunction {
/** The constant function always returning 0. */
public static final ComposableFunction ZERO = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return 0;
}
};
/** The constant function always returning 1. */
public static final ComposableFunction ONE = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return 1;
}
};
/** The identity function. */
public static final ComposableFunction IDENTITY = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return d;
}
};
/** The {@code Math.abs} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction ABS = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.abs(d);
}
};
/** The - operator wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction NEGATE = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return -d;
}
};
/** The {@code Math.sin} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction SIN = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.sin(d);
}
};
/** The {@code Math.sqrt} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction SQRT = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.sqrt(d);
}
};
/** The {@code Math.sinh} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction SINH = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.sinh(d);
}
};
/** The {@code Math.exp} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction EXP = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.exp(d);
}
};
/** The {@code Math.expm1} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction EXPM1 = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.expm1(d);
}
};
/** The {@code Math.asin} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction ASIN = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.asin(d);
}
};
/** The {@code Math.atan} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction ATAN = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.atan(d);
}
};
/** The {@code Math.tan} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction TAN = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.tan(d);
}
};
/** The {@code Math.tanh} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction TANH = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.tanh(d);
}
};
/** The {@code Math.cbrt} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction CBRT = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.cbrt(d);
}
};
/** The {@code Math.ceil} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction CEIL = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.ceil(d);
}
};
/** The {@code Math.floor} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction FLOOR = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.floor(d);
}
};
/** The {@code Math.log} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction LOG = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.log(d);
}
};
/** The {@code Math.log10} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction LOG10 = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.log10(d);
}
};
/** The {@code Math.cos} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction COS = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.cos(d);
}
};
/** The {@code Math.abs} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction ACOS = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.acos(d);
}
};
/** The {@code Math.cosh} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction COSH = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.cosh(d);
}
};
/** The {@code Math.rint} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction RINT = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.rint(d);
}
};
/** The {@code Math.signum} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction SIGNUM = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.signum(d);
}
};
/** The {@code Math.ulp} method wrapped as a {@link ComposableFunction}. */
public static final ComposableFunction ULP = new ComposableFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.ulp(d);
}
};
/** Precompose the instance with another function.
* <p>
* The composed function h created by {@code h = g.of(f)} is such
* that {@code h.value(x) == g.value(f.value(x))} for all x.
* </p>
* @param f function to compose with
* @return a new function which computes {@code this.value(f.value(x))}
* @see #postCompose(UnivariateRealFunction)
*/
public ComposableFunction of(final UnivariateRealFunction f) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return ComposableFunction.this.value(f.value(x));
}
};
}
/** Postcompose the instance with another function.
* <p>
* The composed function h created by {@code h = g.postCompose(f)} is such
* that {@code h.value(x) == f.value(g.value(x))} for all x.
* </p>
* @param f function to compose with
* @return a new function which computes {@code f.value(this.value(x))}
* @see #of(UnivariateRealFunction)
*/
public ComposableFunction postCompose(final UnivariateRealFunction f) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return f.value(ComposableFunction.this.value(x));
}
};
}
/**
* Return a function combining the instance and another function.
* <p>
* The function h created by {@code h = g.combine(f, combiner)} is such that
* {@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all x.
* </p>
* @param f function to combine with the instance
* @param combiner bivariate function used for combining
* @return a new function which computes {@code combine.value(this.value(x), f.value(x))}
*/
public ComposableFunction combine(final UnivariateRealFunction f,
final BivariateRealFunction combiner) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return combiner.value(ComposableFunction.this.value(x), f.value(x));
}
};
}
/**
* Return a function adding the instance and another function.
* @param f function to combine with the instance
* @return a new function which computes {@code this.value(x) + f.value(x)}
*/
public ComposableFunction add(final UnivariateRealFunction f) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return ComposableFunction.this.value(x) + f.value(x);
}
};
}
/**
* Return a function adding a constant term to the instance.
* @param a term to add
* @return a new function which computes {@code this.value(x) + a}
*/
public ComposableFunction add(final double a) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return ComposableFunction.this.value(x) + a;
}
};
}
/**
* Return a function subtracting another function from the instance.
* @param f function to combine with the instance
* @return a new function which computes {@code this.value(x) - f.value(x)}
*/
public ComposableFunction subtract(final UnivariateRealFunction f) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return ComposableFunction.this.value(x) - f.value(x);
}
};
}
/**
* Return a function multiplying the instance and another function.
* @param f function to combine with the instance
* @return a new function which computes {@code this.value(x) * f.value(x)}
*/
public ComposableFunction multiply(final UnivariateRealFunction f) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return ComposableFunction.this.value(x) * f.value(x);
}
};
}
/**
* Return a function scaling the instance by a constant factor.
* @param scaleFactor constant scaling factor
* @return a new function which computes {@code this.value(x) * scaleFactor}
*/
public ComposableFunction multiply(final double scaleFactor) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return ComposableFunction.this.value(x) * scaleFactor;
}
};
}
/**
* Return a function dividing the instance by another function.
* @param f function to combine with the instance
* @return a new function which computes {@code this.value(x) / f.value(x)}
*/
public ComposableFunction divide(final UnivariateRealFunction f) {
return new ComposableFunction() {
@Override
/** {@inheritDoc} */
public double value(double x) throws FunctionEvaluationException {
return ComposableFunction.this.value(x) / f.value(x);
}
};
}
/**
* Generates a function that iteratively apply instance function on all
* elements of an array.
* <p>
* The generated function behaves as follows:
* <ul>
* <li>initialize result = initialValue</li>
* <li>iterate: {@code result = combiner.value(result,
* this.value(nextMultivariateEntry));}</li>
* <li>return result</li>
* </ul>
* </p>
* @param combiner combiner to use between entries
* @param initialValue initial value to use before first entry
* @return a new function that iteratively applie instance function on all
* elements of an array.
*/
public MultivariateRealFunction asCollector(final BivariateRealFunction combiner,
final double initialValue) {
return new MultivariateRealFunction() {
/** {@inheritDoc} */
public double value(double[] point)
throws FunctionEvaluationException, IllegalArgumentException {
double result = initialValue;
for (final double entry : point) {
result = combiner.value(result, ComposableFunction.this.value(entry));
}
return result;
}
};
}
/**
* Generates a function that iteratively apply instance function on all
* elements of an array.
* <p>
* Calling this method is equivalent to call {@link
* #asCollector(BivariateRealFunction, double) asCollector(BivariateRealFunction, 0.0)}.
* </p>
* @param combiner combiner to use between entries
* @return a new function that iteratively applie instance function on all
* elements of an array.
* @see #asCollector(BivariateRealFunction, double)
*/
public MultivariateRealFunction asCollector(final BivariateRealFunction combiner) {
return asCollector(combiner, 0.0);
}
/**
* Generates a function that iteratively apply instance function on all
* elements of an array.
* <p>
* Calling this method is equivalent to call {@link
* #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, initialValue)}.
* </p>
* @param initialValue initial value to use before first entry
* @return a new function that iteratively applie instance function on all
* elements of an array.
* @see #asCollector(BivariateRealFunction, double)
* @see BinaryFunction#ADD
*/
public MultivariateRealFunction asCollector(final double initialValue) {
return asCollector(BinaryFunction.ADD, initialValue);
}
/**
* Generates a function that iteratively apply instance function on all
* elements of an array.
* <p>
* Calling this method is equivalent to call {@link
* #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, 0.0)}.
* </p>
* @return a new function that iteratively applie instance function on all
* elements of an array.
* @see #asCollector(BivariateRealFunction, double)
* @see BinaryFunction#ADD
*/
public MultivariateRealFunction asCollector() {
return asCollector(BinaryFunction.ADD, 0.0);
}
/** {@inheritDoc} */
public abstract double value(double x) throws FunctionEvaluationException;
}

View File

@ -1,225 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
/**
* Set of {@link UnivariateRealFunction} classes wrapping methods from
* the standard Math class.
*
* @version $Revision$ $Date$
*/
public class UnivariateRealFunctions {
/** The {@code Math.abs} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction ABS = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.abs(d);
}
};
/** The - operator wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction NEGATE = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return -d;
}
};
/** The {@code Math.sin} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction SIN = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.sin(d);
}
};
/** The {@code Math.sqrt} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction SQRT = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.sqrt(d);
}
};
/** The {@code Math.sinh} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction SINH = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.sinh(d);
}
};
/** The {@code Math.exp} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction EXP = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.exp(d);
}
};
/** The {@code Math.expm1} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction EXP1M = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.expm1(d);
}
};
/** The {@code Math.asin} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction ASIN = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.asin(d);
}
};
/** The {@code Math.atan} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction ATAN = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.atan(d);
}
};
/** The {@code Math.tan} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction TAN = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.tan(d);
}
};
/** The {@code Math.tanh} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction TANH = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.tanh(d);
}
};
/** The {@code Math.cbrt} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction CBRT = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.cbrt(d);
}
};
/** The {@code Math.ceil} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction CEIL = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.ceil(d);
}
};
/** The {@code Math.floor} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction FLOOR = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.floor(d);
}
};
/** The {@code Math.log} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction LOG = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.log(d);
}
};
/** The {@code Math.log10} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction LOG10 = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.log10(d);
}
};
/** The {@code Math.cos} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction COS = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.cos(d);
}
};
/** The {@code Math.abs} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction ACOS = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.acos(d);
}
};
/** The {@code Math.cosh} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction COSH = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.cosh(d);
}
};
/** The {@code Math.rint} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction RINT = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.rint(d);
}
};
/** The {@code Math.signum} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction SIGNUM = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.signum(d);
}
};
/** The {@code Math.ulp} method wrapped as a {@link UnivariateRealFunction}. */
public static final UnivariateRealFunction ULP = new UnivariateRealFunction() {
/** {@inheritDoc} */
public double value(double d) {
return Math.ulp(d);
}
};
/** The {@code Math.pow} method wrapped as a {@link UnivariateRealFunction}. */
public static class Pow implements UnivariateRealFunction {
/** The power to which the value should be raised. */
private final double pow;
/** Simple constructor.
* @param pow the power to which the value should be raised
*/
public Pow(double pow) {
this.pow = pow;
}
/** {@inheritDoc} */
public double value(double d) {
return Math.pow(d, pow);
}
}
}

View File

@ -22,7 +22,7 @@ import java.util.Iterator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.analysis.UnivariateRealFunctions;
import org.apache.commons.math.analysis.ComposableFunction;
/**
* This class provides default basic implementations for many methods in the
@ -273,7 +273,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapAbsToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.ABS);
return mapToSelf(ComposableFunction.ABS);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -287,7 +287,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapAcosToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.ACOS);
return mapToSelf(ComposableFunction.ACOS);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -301,7 +301,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapAsinToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.ASIN);
return mapToSelf(ComposableFunction.ASIN);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -315,7 +315,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapAtanToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.ATAN);
return mapToSelf(ComposableFunction.ATAN);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -329,7 +329,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapCbrtToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.CBRT);
return mapToSelf(ComposableFunction.CBRT);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -343,7 +343,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapCeilToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.CEIL);
return mapToSelf(ComposableFunction.CEIL);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -357,7 +357,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapCosToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.COS);
return mapToSelf(ComposableFunction.COS);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -371,7 +371,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapCoshToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.COSH);
return mapToSelf(ComposableFunction.COSH);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -390,7 +390,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapExpToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.EXP);
return mapToSelf(ComposableFunction.EXP);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -404,7 +404,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapExpm1ToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.EXP1M);
return mapToSelf(ComposableFunction.EXPM1);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -418,7 +418,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapFloorToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.FLOOR);
return mapToSelf(ComposableFunction.FLOOR);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -437,7 +437,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapLogToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.LOG);
return mapToSelf(ComposableFunction.LOG);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -451,7 +451,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapLog10ToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.LOG10);
return mapToSelf(ComposableFunction.LOG10);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -465,7 +465,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapLog1pToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.ASIN);
return mapToSelf(ComposableFunction.ASIN);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -489,7 +489,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapRintToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.RINT);
return mapToSelf(ComposableFunction.RINT);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -503,7 +503,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapSignumToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.SIGNUM);
return mapToSelf(ComposableFunction.SIGNUM);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -517,7 +517,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapSinToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.SIN);
return mapToSelf(ComposableFunction.SIN);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -531,7 +531,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapSinhToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.SINH);
return mapToSelf(ComposableFunction.SINH);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -545,7 +545,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapSqrtToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.SQRT);
return mapToSelf(ComposableFunction.SQRT);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -564,7 +564,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapTanToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.TAN);
return mapToSelf(ComposableFunction.TAN);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -578,7 +578,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapTanhToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.TANH);
return mapToSelf(ComposableFunction.TANH);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}
@ -592,7 +592,7 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public RealVector mapUlpToSelf() {
try {
return mapToSelf(UnivariateRealFunctions.ULP);
return mapToSelf(ComposableFunction.ULP);
} catch (FunctionEvaluationException e) {
throw new IllegalArgumentException(e);
}

View File

@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
</properties>
<body>
<release version="2.1" date="TBD" description="TBD">
<action dev="luc" type="fix" issue="MATH-313" due-to="Jake Mannix">
Added composition features for real functions.
</action>
<action dev="luc" type="fix" issue="MATH-312" due-to="Jake Mannix">
Added mapping and iteration methods to vectors. Provided a default implementation
for the numerous simple methods in the RealVectorInterface.

View File

@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.junit.Assert;
import org.junit.Test;
public class BinaryFunctionTest {
@Test
public void testAdd() throws FunctionEvaluationException {
Assert.assertEquals(5.0, BinaryFunction.ADD.value(2, 3), 1.0e-15);
Assert.assertEquals(0.0, BinaryFunction.ADD.value(-1, 1), 1.0e-15);
}
@Test
public void testSubtract() throws FunctionEvaluationException {
Assert.assertEquals(-1.0, BinaryFunction.SUBTRACT.value(2, 3), 1.0e-15);
Assert.assertEquals(-2.0, BinaryFunction.SUBTRACT.value(-1, 1), 1.0e-15);
}
@Test
public void testMultiply() throws FunctionEvaluationException {
Assert.assertEquals(6.0, BinaryFunction.MULTIPLY.value(2, 3), 1.0e-15);
Assert.assertEquals(-1.0, BinaryFunction.MULTIPLY.value(-1, 1), 1.0e-15);
}
@Test
public void testDivide() throws FunctionEvaluationException {
Assert.assertEquals(1.5, BinaryFunction.DIVIDE.value(3, 2), 1.0e-15);
Assert.assertEquals(-1.0, BinaryFunction.DIVIDE.value(-1, 1), 1.0e-15);
}
@Test
public void testPow() throws FunctionEvaluationException {
Assert.assertEquals(9.0, BinaryFunction.POW.value(3, 2), 1.0e-15);
Assert.assertEquals(-1.0, BinaryFunction.POW.value(-1, 1), 1.0e-15);
}
@Test
public void testAtan2() throws FunctionEvaluationException {
Assert.assertEquals(Math.PI / 4, BinaryFunction.ATAN2.value(1, 1), 1.0e-15);
Assert.assertEquals(-Math.PI / 4, BinaryFunction.ATAN2.value(-1, 1), 1.0e-15);
}
@Test
public void testFix1st() throws FunctionEvaluationException {
ComposableFunction f = BinaryFunction.POW.fix1stArgument(2);
for (double x = 0.0; x < 1.0; x += 0.01) {
Assert.assertEquals(Math.pow(2.0, x), f.value(x), 1.0e-15);
}
}
@Test
public void testFix2nd() throws FunctionEvaluationException {
ComposableFunction f = BinaryFunction.POW.fix2ndArgument(2);
for (double y = 0.0; y < 1.0; y += 0.01) {
Assert.assertEquals(y * y, f.value(y), 1.0e-15);
}
}
}

View File

@ -0,0 +1,146 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.junit.Assert;
import org.junit.Test;
public class ComposableFunctionTest {
@Test
public void testZero() throws FunctionEvaluationException {
Assert.assertEquals(0.0, ComposableFunction.ZERO.value(1), 1.0e-15);
Assert.assertEquals(0.0, ComposableFunction.ZERO.value(2), 1.0e-15);
}
@Test
public void testOne() throws FunctionEvaluationException {
Assert.assertEquals(1.0, ComposableFunction.ONE.value(1), 1.0e-15);
Assert.assertEquals(1.0, ComposableFunction.ONE.value(2), 1.0e-15);
}
@Test
public void testIdentity() throws FunctionEvaluationException {
Assert.assertEquals(1.0, ComposableFunction.IDENTITY.value(1), 1.0e-15);
Assert.assertEquals(2.0, ComposableFunction.IDENTITY.value(2), 1.0e-15);
}
@Test
public void testRint() throws FunctionEvaluationException {
Assert.assertEquals(1.0, ComposableFunction.RINT.value(0.9), 1.0e-15);
Assert.assertEquals(2.0, ComposableFunction.RINT.value(2.2), 1.0e-15);
}
@Test
public void testSignum() throws FunctionEvaluationException {
Assert.assertEquals(1.0, ComposableFunction.SIGNUM.value(12.3), 1.0e-15);
Assert.assertEquals(-1.0, ComposableFunction.SIGNUM.value(-6), 1.0e-15);
}
@Test
public void testComposition() throws FunctionEvaluationException {
ComposableFunction abs = ComposableFunction.ABS;
ComposableFunction acos = ComposableFunction.ACOS;
ComposableFunction asin = ComposableFunction.ASIN;
ComposableFunction atan = ComposableFunction.ATAN;
ComposableFunction cbrt = ComposableFunction.CBRT;
ComposableFunction ceil = ComposableFunction.CEIL;
ComposableFunction cos = ComposableFunction.COS;
ComposableFunction cosh = ComposableFunction.COSH;
ComposableFunction exp = ComposableFunction.EXP;
ComposableFunction expm1 = ComposableFunction.EXPM1;
ComposableFunction floor = ComposableFunction.FLOOR;
ComposableFunction id = ComposableFunction.IDENTITY;
ComposableFunction log = ComposableFunction.LOG;
ComposableFunction log10 = ComposableFunction.LOG10;
ComposableFunction negate = ComposableFunction.NEGATE;
ComposableFunction sin = ComposableFunction.SIN;
ComposableFunction sinh = ComposableFunction.SINH;
ComposableFunction sqrt = ComposableFunction.SQRT;
ComposableFunction tan = ComposableFunction.TAN;
ComposableFunction tanh = ComposableFunction.TANH;
ComposableFunction ulp = ComposableFunction.ULP;
ComposableFunction f1 = sqrt.of(abs.of(expm1.of(cbrt.of(tanh).of(id))));
for (double x = 0.1; x < 0.9; x += 0.01) {
Assert.assertEquals(Math.sqrt(Math.abs(Math.expm1(Math.cbrt(Math.tanh(x))))),
f1.value(x), 1.0e-15);
}
ComposableFunction f2 = cosh.of(sinh.of(tanh.of(ceil.postCompose(log.postCompose(cosh)))));
for (double x = 0.1; x < 12.9; x += 1.0) {
Assert.assertEquals(Math.cosh(Math.sinh(Math.tanh(Math.cosh(Math.log(Math.ceil(x)))))),
f2.value(x), 1.0e-15);
}
ComposableFunction f3 = cos.of(sin.of(tan.of(acos.of(asin.of(log10.of(log.of(ulp)))))));
for (double x = 1.0e16; x < 1.0e17; x += 1.0e16) {
Assert.assertEquals(Math.cos(Math.sin(Math.tan(Math.acos(Math.asin(Math.log10(Math.log(Math.ulp(x)))))))),
f3.value(x), 1.0e-15);
}
ComposableFunction f4 = atan.of(exp.of(negate.of(floor)));
for (double x = 1.1; x < 10.2; x += 1.0) {
Assert.assertEquals(Math.atan(Math.exp(-Math.floor(x))),
f4.value(x), 1.0e-15);
}
}
@Test
public void testCombine() throws FunctionEvaluationException {
ComposableFunction f =
ComposableFunction.COS.combine(ComposableFunction.ASIN, BinaryFunction.POW);
for (double x = 0.1; x < 0.9; x += 0.01) {
Assert.assertEquals(Math.pow(Math.cos(x), Math.asin(x)), f.value(x), 1.0e-15);
}
}
@Test
public void testSimpleCombination() throws FunctionEvaluationException {
ComposableFunction f1 = ComposableFunction.COS.add(3);
ComposableFunction f2 = ComposableFunction.COS.add(ComposableFunction.SIN);
ComposableFunction f3 = ComposableFunction.COS.subtract(ComposableFunction.SIN);
ComposableFunction f4 = ComposableFunction.COS.multiply(ComposableFunction.SIN);
ComposableFunction f5 = ComposableFunction.COS.multiply(5);
ComposableFunction f6 = ComposableFunction.COS.divide(ComposableFunction.SIN);
for (double x = 0.1; x < 0.9; x += 0.01) {
Assert.assertEquals(Math.cos(x) + 3, f1.value(x), 1.0e-15);
Assert.assertEquals(Math.cos(x) + Math.sin(x), f2.value(x), 1.0e-15);
Assert.assertEquals(Math.cos(x) - Math.sin(x), f3.value(x), 1.0e-15);
Assert.assertEquals(Math.cos(x) * Math.sin(x), f4.value(x), 1.0e-15);
Assert.assertEquals(Math.cos(x) * 5, f5.value(x), 1.0e-15);
Assert.assertEquals(Math.cos(x) / Math.sin(x), f6.value(x), 1.0e-15);
}
}
@Test
public void testCollector() throws FunctionEvaluationException {
ComposableFunction f = BinaryFunction.POW.fix2ndArgument(2);
Assert.assertEquals(30, f.asCollector().value(new double[] { 1, 2, 3, 4 }), 1.0e-15);
Assert.assertEquals(33, f.asCollector(3).value(new double[] { 1, 2, 3, 4 }), 1.0e-15);
Assert.assertEquals(-30, f.asCollector(BinaryFunction.SUBTRACT).value(new double[] { 1, 2, 3, 4 }), 1.0e-15);
Assert.assertEquals(1152, f.asCollector(BinaryFunction.MULTIPLY, 2).value(new double[] { 1, 2, 3, 4 }), 1.0e-15);
}
}