JonasBollack
6 years ago
992 changed files with 224273 additions and 0 deletions
@ -0,0 +1,35 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>com.fr.third</groupId> |
||||||
|
<artifactId>commons-math3</artifactId> |
||||||
|
<version>3.6.1</version> |
||||||
|
<build> |
||||||
|
<sourceDirectory>${basedir}/src</sourceDirectory> |
||||||
|
<plugins> |
||||||
|
<!-- 使用 maven-Assembly-plugin插件打可执行包--> |
||||||
|
<plugin> |
||||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||||
|
<artifactId>maven-assembly-plugin</artifactId> |
||||||
|
<version>2.6</version> |
||||||
|
<configuration> |
||||||
|
<!-- get all project dependencies --> |
||||||
|
<descriptorRefs> |
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef> |
||||||
|
</descriptorRefs> |
||||||
|
</configuration> |
||||||
|
<executions> |
||||||
|
<execution> |
||||||
|
<id>make-assembly</id> |
||||||
|
<phase>package</phase> |
||||||
|
<goals> |
||||||
|
<goal>single</goal> |
||||||
|
</goals> |
||||||
|
</execution> |
||||||
|
</executions> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
</project> |
@ -0,0 +1,58 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3; |
||||||
|
|
||||||
|
/** |
||||||
|
* Interface representing a <a href="http://mathworld.wolfram.com/Field.html">field</a>. |
||||||
|
* <p> |
||||||
|
* Classes implementing this interface will often be singletons. |
||||||
|
* </p> |
||||||
|
* @param <T> the type of the field elements |
||||||
|
* @see FieldElement |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
public interface Field<T> { |
||||||
|
|
||||||
|
/** Get the additive identity of the field. |
||||||
|
* <p> |
||||||
|
* The additive identity is the element e<sub>0</sub> of the field such that |
||||||
|
* for all elements a of the field, the equalities a + e<sub>0</sub> = |
||||||
|
* e<sub>0</sub> + a = a hold. |
||||||
|
* </p> |
||||||
|
* @return additive identity of the field |
||||||
|
*/ |
||||||
|
T getZero(); |
||||||
|
|
||||||
|
/** Get the multiplicative identity of the field. |
||||||
|
* <p> |
||||||
|
* The multiplicative identity is the element e<sub>1</sub> of the field such that |
||||||
|
* for all elements a of the field, the equalities a × e<sub>1</sub> = |
||||||
|
* e<sub>1</sub> × a = a hold. |
||||||
|
* </p> |
||||||
|
* @return multiplicative identity of the field |
||||||
|
*/ |
||||||
|
T getOne(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the runtime class of the FieldElement. |
||||||
|
* |
||||||
|
* @return The {@code Class} object that represents the runtime |
||||||
|
* class of this object. |
||||||
|
*/ |
||||||
|
Class<? extends FieldElement<T>> getRuntimeClass(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,87 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathArithmeticException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Interface representing <a href="http://mathworld.wolfram.com/Field.html">field</a> elements. |
||||||
|
* @param <T> the type of the field elements |
||||||
|
* @see Field |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
public interface FieldElement<T> { |
||||||
|
|
||||||
|
/** Compute this + a. |
||||||
|
* @param a element to add |
||||||
|
* @return a new element representing this + a |
||||||
|
* @throws NullArgumentException if {@code a} is {@code null}. |
||||||
|
*/ |
||||||
|
T add(T a) throws NullArgumentException; |
||||||
|
|
||||||
|
/** Compute this - a. |
||||||
|
* @param a element to subtract |
||||||
|
* @return a new element representing this - a |
||||||
|
* @throws NullArgumentException if {@code a} is {@code null}. |
||||||
|
*/ |
||||||
|
T subtract(T a) throws NullArgumentException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the additive inverse of {@code this} element. |
||||||
|
* @return the opposite of {@code this}. |
||||||
|
*/ |
||||||
|
T negate(); |
||||||
|
|
||||||
|
/** Compute n × this. Multiplication by an integer number is defined |
||||||
|
* as the following sum |
||||||
|
* <center> |
||||||
|
* n × this = ∑<sub>i=1</sub><sup>n</sup> this. |
||||||
|
* </center> |
||||||
|
* @param n Number of times {@code this} must be added to itself. |
||||||
|
* @return A new element representing n × this. |
||||||
|
*/ |
||||||
|
T multiply(int n); |
||||||
|
|
||||||
|
/** Compute this × a. |
||||||
|
* @param a element to multiply |
||||||
|
* @return a new element representing this × a |
||||||
|
* @throws NullArgumentException if {@code a} is {@code null}. |
||||||
|
*/ |
||||||
|
T multiply(T a) throws NullArgumentException; |
||||||
|
|
||||||
|
/** Compute this ÷ a. |
||||||
|
* @param a element to divide by |
||||||
|
* @return a new element representing this ÷ a |
||||||
|
* @throws NullArgumentException if {@code a} is {@code null}. |
||||||
|
* @throws MathArithmeticException if {@code a} is zero |
||||||
|
*/ |
||||||
|
T divide(T a) throws NullArgumentException, MathArithmeticException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the multiplicative inverse of {@code this} element. |
||||||
|
* @return the inverse of {@code this}. |
||||||
|
* @throws MathArithmeticException if {@code this} is zero |
||||||
|
*/ |
||||||
|
T reciprocal() throws MathArithmeticException; |
||||||
|
|
||||||
|
/** Get the {@link Field} to which the instance belongs. |
||||||
|
* @return {@link Field} to which the instance belongs |
||||||
|
*/ |
||||||
|
Field<T> getField(); |
||||||
|
} |
@ -0,0 +1,402 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Interface representing a <a href="http://mathworld.wolfram.com/RealNumber.html">real</a> |
||||||
|
* <a href="http://mathworld.wolfram.com/Field.html">field</a>. |
||||||
|
* @param <T> the type of the field elements |
||||||
|
* @see FieldElement |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
public interface RealFieldElement<T> extends FieldElement<T> { |
||||||
|
|
||||||
|
/** Get the real value of the number. |
||||||
|
* @return real value |
||||||
|
*/ |
||||||
|
double getReal(); |
||||||
|
|
||||||
|
/** '+' operator. |
||||||
|
* @param a right hand side parameter of the operator |
||||||
|
* @return this+a |
||||||
|
*/ |
||||||
|
T add(double a); |
||||||
|
|
||||||
|
/** '-' operator. |
||||||
|
* @param a right hand side parameter of the operator |
||||||
|
* @return this-a |
||||||
|
*/ |
||||||
|
T subtract(double a); |
||||||
|
|
||||||
|
/** '×' operator. |
||||||
|
* @param a right hand side parameter of the operator |
||||||
|
* @return this×a |
||||||
|
*/ |
||||||
|
T multiply(double a); |
||||||
|
|
||||||
|
/** '÷' operator. |
||||||
|
* @param a right hand side parameter of the operator |
||||||
|
* @return this÷a |
||||||
|
*/ |
||||||
|
T divide(double a); |
||||||
|
|
||||||
|
/** IEEE remainder operator. |
||||||
|
* @param a right hand side parameter of the operator |
||||||
|
* @return this - n × a where n is the closest integer to this/a |
||||||
|
* (the even integer is chosen for n if this/a is halfway between two integers) |
||||||
|
*/ |
||||||
|
T remainder(double a); |
||||||
|
|
||||||
|
/** IEEE remainder operator. |
||||||
|
* @param a right hand side parameter of the operator |
||||||
|
* @return this - n × a where n is the closest integer to this/a |
||||||
|
* (the even integer is chosen for n if this/a is halfway between two integers) |
||||||
|
* @exception DimensionMismatchException if number of free parameters or orders are inconsistent |
||||||
|
*/ |
||||||
|
T remainder(T a) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
/** absolute value. |
||||||
|
* @return abs(this) |
||||||
|
*/ |
||||||
|
T abs(); |
||||||
|
|
||||||
|
/** Get the smallest whole number larger than instance. |
||||||
|
* @return ceil(this) |
||||||
|
*/ |
||||||
|
T ceil(); |
||||||
|
|
||||||
|
/** Get the largest whole number smaller than instance. |
||||||
|
* @return floor(this) |
||||||
|
*/ |
||||||
|
T floor(); |
||||||
|
|
||||||
|
/** Get the whole number that is the nearest to the instance, or the even one if x is exactly half way between two integers. |
||||||
|
* @return a double number r such that r is an integer r - 0.5 ≤ this ≤ r + 0.5 |
||||||
|
*/ |
||||||
|
T rint(); |
||||||
|
|
||||||
|
/** Get the closest long to instance value. |
||||||
|
* @return closest long to {@link #getReal()} |
||||||
|
*/ |
||||||
|
long round(); |
||||||
|
|
||||||
|
/** Compute the signum of the instance. |
||||||
|
* The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise |
||||||
|
* @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a |
||||||
|
*/ |
||||||
|
T signum(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the instance with the sign of the argument. |
||||||
|
* A NaN {@code sign} argument is treated as positive. |
||||||
|
* |
||||||
|
* @param sign the sign for the returned value |
||||||
|
* @return the instance with the same sign as the {@code sign} argument |
||||||
|
*/ |
||||||
|
T copySign(T sign); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the instance with the sign of the argument. |
||||||
|
* A NaN {@code sign} argument is treated as positive. |
||||||
|
* |
||||||
|
* @param sign the sign for the returned value |
||||||
|
* @return the instance with the same sign as the {@code sign} argument |
||||||
|
*/ |
||||||
|
T copySign(double sign); |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiply the instance by a power of 2. |
||||||
|
* @param n power of 2 |
||||||
|
* @return this × 2<sup>n</sup> |
||||||
|
*/ |
||||||
|
T scalb(int n); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the hypotenuse of a triangle with sides {@code this} and {@code y} |
||||||
|
* - sqrt(<i>this</i><sup>2</sup> +<i>y</i><sup>2</sup>) |
||||||
|
* avoiding intermediate overflow or underflow. |
||||||
|
* |
||||||
|
* <ul> |
||||||
|
* <li> If either argument is infinite, then the result is positive infinity.</li> |
||||||
|
* <li> else, if either argument is NaN then the result is NaN.</li> |
||||||
|
* </ul> |
||||||
|
* |
||||||
|
* @param y a value |
||||||
|
* @return sqrt(<i>this</i><sup>2</sup> +<i>y</i><sup>2</sup>) |
||||||
|
* @exception DimensionMismatchException if number of free parameters or orders are inconsistent |
||||||
|
*/ |
||||||
|
T hypot(T y) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
T reciprocal(); |
||||||
|
|
||||||
|
/** Square root. |
||||||
|
* @return square root of the instance |
||||||
|
*/ |
||||||
|
T sqrt(); |
||||||
|
|
||||||
|
/** Cubic root. |
||||||
|
* @return cubic root of the instance |
||||||
|
*/ |
||||||
|
T cbrt(); |
||||||
|
|
||||||
|
/** N<sup>th</sup> root. |
||||||
|
* @param n order of the root |
||||||
|
* @return n<sup>th</sup> root of the instance |
||||||
|
*/ |
||||||
|
T rootN(int n); |
||||||
|
|
||||||
|
/** Power operation. |
||||||
|
* @param p power to apply |
||||||
|
* @return this<sup>p</sup> |
||||||
|
*/ |
||||||
|
T pow(double p); |
||||||
|
|
||||||
|
/** Integer power operation. |
||||||
|
* @param n power to apply |
||||||
|
* @return this<sup>n</sup> |
||||||
|
*/ |
||||||
|
T pow(int n); |
||||||
|
|
||||||
|
/** Power operation. |
||||||
|
* @param e exponent |
||||||
|
* @return this<sup>e</sup> |
||||||
|
* @exception DimensionMismatchException if number of free parameters or orders are inconsistent |
||||||
|
*/ |
||||||
|
T pow(T e) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
/** Exponential. |
||||||
|
* @return exponential of the instance |
||||||
|
*/ |
||||||
|
T exp(); |
||||||
|
|
||||||
|
/** Exponential minus 1. |
||||||
|
* @return exponential minus one of the instance |
||||||
|
*/ |
||||||
|
T expm1(); |
||||||
|
|
||||||
|
/** Natural logarithm. |
||||||
|
* @return logarithm of the instance |
||||||
|
*/ |
||||||
|
T log(); |
||||||
|
|
||||||
|
/** Shifted natural logarithm. |
||||||
|
* @return logarithm of one plus the instance |
||||||
|
*/ |
||||||
|
T log1p(); |
||||||
|
|
||||||
|
// TODO: add this method in 4.0, as it is not possible to do it in 3.2
|
||||||
|
// due to incompatibility of the return type in the Dfp class
|
||||||
|
// /** Base 10 logarithm.
|
||||||
|
// * @return base 10 logarithm of the instance
|
||||||
|
// */
|
||||||
|
// T log10();
|
||||||
|
|
||||||
|
/** Cosine operation. |
||||||
|
* @return cos(this) |
||||||
|
*/ |
||||||
|
T cos(); |
||||||
|
|
||||||
|
/** Sine operation. |
||||||
|
* @return sin(this) |
||||||
|
*/ |
||||||
|
T sin(); |
||||||
|
|
||||||
|
/** Tangent operation. |
||||||
|
* @return tan(this) |
||||||
|
*/ |
||||||
|
T tan(); |
||||||
|
|
||||||
|
/** Arc cosine operation. |
||||||
|
* @return acos(this) |
||||||
|
*/ |
||||||
|
T acos(); |
||||||
|
|
||||||
|
/** Arc sine operation. |
||||||
|
* @return asin(this) |
||||||
|
*/ |
||||||
|
T asin(); |
||||||
|
|
||||||
|
/** Arc tangent operation. |
||||||
|
* @return atan(this) |
||||||
|
*/ |
||||||
|
T atan(); |
||||||
|
|
||||||
|
/** Two arguments arc tangent operation. |
||||||
|
* @param x second argument of the arc tangent |
||||||
|
* @return atan2(this, x) |
||||||
|
* @exception DimensionMismatchException if number of free parameters or orders are inconsistent |
||||||
|
*/ |
||||||
|
T atan2(T x) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
/** Hyperbolic cosine operation. |
||||||
|
* @return cosh(this) |
||||||
|
*/ |
||||||
|
T cosh(); |
||||||
|
|
||||||
|
/** Hyperbolic sine operation. |
||||||
|
* @return sinh(this) |
||||||
|
*/ |
||||||
|
T sinh(); |
||||||
|
|
||||||
|
/** Hyperbolic tangent operation. |
||||||
|
* @return tanh(this) |
||||||
|
*/ |
||||||
|
T tanh(); |
||||||
|
|
||||||
|
/** Inverse hyperbolic cosine operation. |
||||||
|
* @return acosh(this) |
||||||
|
*/ |
||||||
|
T acosh(); |
||||||
|
|
||||||
|
/** Inverse hyperbolic sine operation. |
||||||
|
* @return asin(this) |
||||||
|
*/ |
||||||
|
T asinh(); |
||||||
|
|
||||||
|
/** Inverse hyperbolic tangent operation. |
||||||
|
* @return atanh(this) |
||||||
|
*/ |
||||||
|
T atanh(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a Factors. |
||||||
|
* @param b Factors. |
||||||
|
* @return <code>Σ<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>. |
||||||
|
* @throws DimensionMismatchException if arrays dimensions don't match |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(T[] a, T[] b) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a Factors. |
||||||
|
* @param b Factors. |
||||||
|
* @return <code>Σ<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>. |
||||||
|
* @throws DimensionMismatchException if arrays dimensions don't match |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(double[] a, T[] b) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a1 first factor of the first term |
||||||
|
* @param b1 second factor of the first term |
||||||
|
* @param a2 first factor of the second term |
||||||
|
* @param b2 second factor of the second term |
||||||
|
* @return a<sub>1</sub>×b<sub>1</sub> + |
||||||
|
* a<sub>2</sub>×b<sub>2</sub> |
||||||
|
* @see #linearCombination(Object, Object, Object, Object, Object, Object) |
||||||
|
* @see #linearCombination(Object, Object, Object, Object, Object, Object, Object, Object) |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(T a1, T b1, T a2, T b2); |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a1 first factor of the first term |
||||||
|
* @param b1 second factor of the first term |
||||||
|
* @param a2 first factor of the second term |
||||||
|
* @param b2 second factor of the second term |
||||||
|
* @return a<sub>1</sub>×b<sub>1</sub> + |
||||||
|
* a<sub>2</sub>×b<sub>2</sub> |
||||||
|
* @see #linearCombination(double, Object, double, Object, double, Object) |
||||||
|
* @see #linearCombination(double, Object, double, Object, double, Object, double, Object) |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(double a1, T b1, double a2, T b2); |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a1 first factor of the first term |
||||||
|
* @param b1 second factor of the first term |
||||||
|
* @param a2 first factor of the second term |
||||||
|
* @param b2 second factor of the second term |
||||||
|
* @param a3 first factor of the third term |
||||||
|
* @param b3 second factor of the third term |
||||||
|
* @return a<sub>1</sub>×b<sub>1</sub> + |
||||||
|
* a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> |
||||||
|
* @see #linearCombination(Object, Object, Object, Object) |
||||||
|
* @see #linearCombination(Object, Object, Object, Object, Object, Object, Object, Object) |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3); |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a1 first factor of the first term |
||||||
|
* @param b1 second factor of the first term |
||||||
|
* @param a2 first factor of the second term |
||||||
|
* @param b2 second factor of the second term |
||||||
|
* @param a3 first factor of the third term |
||||||
|
* @param b3 second factor of the third term |
||||||
|
* @return a<sub>1</sub>×b<sub>1</sub> + |
||||||
|
* a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> |
||||||
|
* @see #linearCombination(double, Object, double, Object) |
||||||
|
* @see #linearCombination(double, Object, double, Object, double, Object, double, Object) |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3); |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a1 first factor of the first term |
||||||
|
* @param b1 second factor of the first term |
||||||
|
* @param a2 first factor of the second term |
||||||
|
* @param b2 second factor of the second term |
||||||
|
* @param a3 first factor of the third term |
||||||
|
* @param b3 second factor of the third term |
||||||
|
* @param a4 first factor of the third term |
||||||
|
* @param b4 second factor of the third term |
||||||
|
* @return a<sub>1</sub>×b<sub>1</sub> + |
||||||
|
* a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> + |
||||||
|
* a<sub>4</sub>×b<sub>4</sub> |
||||||
|
* @see #linearCombination(Object, Object, Object, Object) |
||||||
|
* @see #linearCombination(Object, Object, Object, Object, Object, Object) |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3, T a4, T b4); |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute a linear combination. |
||||||
|
* @param a1 first factor of the first term |
||||||
|
* @param b1 second factor of the first term |
||||||
|
* @param a2 first factor of the second term |
||||||
|
* @param b2 second factor of the second term |
||||||
|
* @param a3 first factor of the third term |
||||||
|
* @param b3 second factor of the third term |
||||||
|
* @param a4 first factor of the third term |
||||||
|
* @param b4 second factor of the third term |
||||||
|
* @return a<sub>1</sub>×b<sub>1</sub> + |
||||||
|
* a<sub>2</sub>×b<sub>2</sub> + a<sub>3</sub>×b<sub>3</sub> + |
||||||
|
* a<sub>4</sub>×b<sub>4</sub> |
||||||
|
* @see #linearCombination(double, Object, double, Object) |
||||||
|
* @see #linearCombination(double, Object, double, Object, double, Object) |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3, double a4, T b4); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a bivariate real function. |
||||||
|
* |
||||||
|
* @since 2.1 |
||||||
|
*/ |
||||||
|
public interface BivariateFunction { |
||||||
|
/** |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
double value(double x, double y); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link MultivariateFunction} representing a differentiable |
||||||
|
* multivariate real function. |
||||||
|
* @since 2.0 |
||||||
|
* @deprecated as of 3.1 replaced by {@link MultivariateDifferentiableFunction} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public interface DifferentiableMultivariateFunction extends MultivariateFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the partial derivative of the function with respect to a point coordinate. |
||||||
|
* <p> |
||||||
|
* The partial derivative is defined with respect to point coordinate |
||||||
|
* x<sub>k</sub>. If the partial derivatives with respect to all coordinates are |
||||||
|
* needed, it may be more efficient to use the {@link #gradient()} method which will |
||||||
|
* compute them all at once. |
||||||
|
* </p> |
||||||
|
* @param k index of the coordinate with respect to which the partial |
||||||
|
* derivative is computed |
||||||
|
* @return the partial derivative function with respect to k<sup>th</sup> point coordinate |
||||||
|
*/ |
||||||
|
MultivariateFunction partialDerivative(int k); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the gradient function. |
||||||
|
* <p>If only one partial derivative with respect to a specific coordinate is |
||||||
|
* needed, it may be more efficient to use the {@link #partialDerivative(int)} method |
||||||
|
* which will compute only the specified component.</p> |
||||||
|
* @return the gradient function |
||||||
|
*/ |
||||||
|
MultivariateVectorFunction gradient(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link MultivariateVectorFunction} representing a differentiable |
||||||
|
* multivariate vectorial function. |
||||||
|
* @since 2.0 |
||||||
|
* @deprecated as of 3.1 replaced by {@link MultivariateDifferentiableVectorFunction} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public interface DifferentiableMultivariateVectorFunction |
||||||
|
extends MultivariateVectorFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the jacobian function. |
||||||
|
* @return the jacobian function |
||||||
|
*/ |
||||||
|
MultivariateMatrixFunction jacobian(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link UnivariateFunction} representing a differentiable univariate real function. |
||||||
|
* |
||||||
|
* @deprecated as of 3.1 replaced by {@link UnivariateDifferentiableFunction} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public interface DifferentiableUnivariateFunction |
||||||
|
extends UnivariateFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the derivative of the function |
||||||
|
* |
||||||
|
* @return the derivative function |
||||||
|
*/ |
||||||
|
UnivariateFunction derivative(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableMatrixFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link UnivariateMatrixFunction} representing a differentiable univariate matrix function. |
||||||
|
* |
||||||
|
* @since 2.0 |
||||||
|
* @deprecated as of 3.1 replaced by {@link UnivariateDifferentiableMatrixFunction} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public interface DifferentiableUnivariateMatrixFunction |
||||||
|
extends UnivariateMatrixFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the derivative of the function |
||||||
|
* |
||||||
|
* @return the derivative function |
||||||
|
*/ |
||||||
|
UnivariateMatrixFunction derivative(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableVectorFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link UnivariateVectorFunction} representing a differentiable univariate vectorial function. |
||||||
|
* |
||||||
|
* @since 2.0 |
||||||
|
* @deprecated as of 3.1 replaced by {@link UnivariateDifferentiableVectorFunction} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public interface DifferentiableUnivariateVectorFunction |
||||||
|
extends UnivariateVectorFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the derivative of the function |
||||||
|
* |
||||||
|
* @return the derivative function |
||||||
|
*/ |
||||||
|
UnivariateVectorFunction derivative(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,806 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.function.Identity; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooLargeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.util.LocalizedFormats; |
||||||
|
|
||||||
|
/** |
||||||
|
* Utilities for manipulating function objects. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class FunctionUtils { |
||||||
|
/** |
||||||
|
* Class only contains static methods. |
||||||
|
*/ |
||||||
|
private FunctionUtils() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes functions. |
||||||
|
* <p> |
||||||
|
* The functions in the argument list are composed sequentially, in the |
||||||
|
* given order. For example, compose(f1,f2,f3) acts like f1(f2(f3(x))).</p> |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return the composite function. |
||||||
|
*/ |
||||||
|
public static UnivariateFunction compose(final UnivariateFunction ... f) { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@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; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes functions. |
||||||
|
* <p> |
||||||
|
* The functions in the argument list are composed sequentially, in the |
||||||
|
* given order. For example, compose(f1,f2,f3) acts like f1(f2(f3(x))).</p> |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return the composite function. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public static UnivariateDifferentiableFunction compose(final UnivariateDifferentiableFunction ... f) { |
||||||
|
return new UnivariateDifferentiableFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double t) { |
||||||
|
double r = t; |
||||||
|
for (int i = f.length - 1; i >= 0; i--) { |
||||||
|
r = f[i].value(r); |
||||||
|
} |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
DerivativeStructure r = t; |
||||||
|
for (int i = f.length - 1; i >= 0; i--) { |
||||||
|
r = f[i].value(r); |
||||||
|
} |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Composes functions. |
||||||
|
* <p> |
||||||
|
* The functions in the argument list are composed sequentially, in the |
||||||
|
* given order. For example, compose(f1,f2,f3) acts like f1(f2(f3(x))).</p> |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return the composite function. |
||||||
|
* @deprecated as of 3.1 replaced by {@link #compose(UnivariateDifferentiableFunction...)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static DifferentiableUnivariateFunction compose(final DifferentiableUnivariateFunction ... f) { |
||||||
|
return new DifferentiableUnivariateFunction() { |
||||||
|
/** {@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 UnivariateFunction derivative() { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@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; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds functions. |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return a function that computes the sum of the functions. |
||||||
|
*/ |
||||||
|
public static UnivariateFunction add(final UnivariateFunction ... f) { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@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; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds functions. |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return a function that computes the sum of the functions. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public static UnivariateDifferentiableFunction add(final UnivariateDifferentiableFunction ... f) { |
||||||
|
return new UnivariateDifferentiableFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double t) { |
||||||
|
double r = f[0].value(t); |
||||||
|
for (int i = 1; i < f.length; i++) { |
||||||
|
r += f[i].value(t); |
||||||
|
} |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @throws DimensionMismatchException if functions are not consistent with each other |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws DimensionMismatchException { |
||||||
|
DerivativeStructure r = f[0].value(t); |
||||||
|
for (int i = 1; i < f.length; i++) { |
||||||
|
r = r.add(f[i].value(t)); |
||||||
|
} |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds functions. |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return a function that computes the sum of the functions. |
||||||
|
* @deprecated as of 3.1 replaced by {@link #add(UnivariateDifferentiableFunction...)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static DifferentiableUnivariateFunction add(final DifferentiableUnivariateFunction ... f) { |
||||||
|
return new DifferentiableUnivariateFunction() { |
||||||
|
/** {@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 UnivariateFunction derivative() { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@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; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiplies functions. |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return a function that computes the product of the functions. |
||||||
|
*/ |
||||||
|
public static UnivariateFunction multiply(final UnivariateFunction ... f) { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@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; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiplies functions. |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return a function that computes the product of the functions. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public static UnivariateDifferentiableFunction multiply(final UnivariateDifferentiableFunction ... f) { |
||||||
|
return new UnivariateDifferentiableFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double t) { |
||||||
|
double r = f[0].value(t); |
||||||
|
for (int i = 1; i < f.length; i++) { |
||||||
|
r *= f[i].value(t); |
||||||
|
} |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
DerivativeStructure r = f[0].value(t); |
||||||
|
for (int i = 1; i < f.length; i++) { |
||||||
|
r = r.multiply(f[i].value(t)); |
||||||
|
} |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiplies functions. |
||||||
|
* |
||||||
|
* @param f List of functions. |
||||||
|
* @return a function that computes the product of the functions. |
||||||
|
* @deprecated as of 3.1 replaced by {@link #multiply(UnivariateDifferentiableFunction...)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static DifferentiableUnivariateFunction multiply(final DifferentiableUnivariateFunction ... f) { |
||||||
|
return new DifferentiableUnivariateFunction() { |
||||||
|
/** {@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 UnivariateFunction derivative() { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@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 |
||||||
|
* {@code h(x) = combiner(f(x), g(x)).} |
||||||
|
* |
||||||
|
* @param combiner Combiner function. |
||||||
|
* @param f Function. |
||||||
|
* @param g Function. |
||||||
|
* @return the composite function. |
||||||
|
*/ |
||||||
|
public static UnivariateFunction combine(final BivariateFunction combiner, |
||||||
|
final UnivariateFunction f, |
||||||
|
final UnivariateFunction g) { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return combiner.value(f.value(x), g.value(x)); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a MultivariateFunction h(x[]) defined by <pre> <code> |
||||||
|
* h(x[]) = combiner(...combiner(combiner(initialValue,f(x[0])),f(x[1]))...),f(x[x.length-1])) |
||||||
|
* </code></pre> |
||||||
|
* |
||||||
|
* @param combiner Combiner function. |
||||||
|
* @param f Function. |
||||||
|
* @param initialValue Initial value. |
||||||
|
* @return a collector function. |
||||||
|
*/ |
||||||
|
public static MultivariateFunction collector(final BivariateFunction combiner, |
||||||
|
final UnivariateFunction f, |
||||||
|
final double initialValue) { |
||||||
|
return new MultivariateFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double[] point) { |
||||||
|
double result = combiner.value(initialValue, f.value(point[0])); |
||||||
|
for (int i = 1; i < point.length; i++) { |
||||||
|
result = combiner.value(result, f.value(point[i])); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a MultivariateFunction h(x[]) defined by <pre> <code> |
||||||
|
* h(x[]) = combiner(...combiner(combiner(initialValue,x[0]),x[1])...),x[x.length-1]) |
||||||
|
* </code></pre> |
||||||
|
* |
||||||
|
* @param combiner Combiner function. |
||||||
|
* @param initialValue Initial value. |
||||||
|
* @return a collector function. |
||||||
|
*/ |
||||||
|
public static MultivariateFunction collector(final BivariateFunction combiner, |
||||||
|
final double initialValue) { |
||||||
|
return collector(combiner, new Identity(), initialValue); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a unary function by fixing the first argument of a binary function. |
||||||
|
* |
||||||
|
* @param f Binary function. |
||||||
|
* @param fixed value to which the first argument of {@code f} is set. |
||||||
|
* @return the unary function h(x) = f(fixed, x) |
||||||
|
*/ |
||||||
|
public static UnivariateFunction fix1stArgument(final BivariateFunction f, |
||||||
|
final double fixed) { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return f.value(fixed, x); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
/** |
||||||
|
* Creates a unary function by fixing the second argument of a binary function. |
||||||
|
* |
||||||
|
* @param f Binary function. |
||||||
|
* @param fixed value to which the second argument of {@code f} is set. |
||||||
|
* @return the unary function h(x) = f(x, fixed) |
||||||
|
*/ |
||||||
|
public static UnivariateFunction fix2ndArgument(final BivariateFunction f, |
||||||
|
final double fixed) { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return f.value(x, fixed); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Samples the specified univariate real function on the specified interval. |
||||||
|
* <p> |
||||||
|
* The interval is divided equally into {@code n} sections and sample points |
||||||
|
* are taken from {@code min} to {@code max - (max - min) / n}; therefore |
||||||
|
* {@code f} is not sampled at the upper bound {@code max}.</p> |
||||||
|
* |
||||||
|
* @param f Function to be sampled |
||||||
|
* @param min Lower bound of the interval (included). |
||||||
|
* @param max Upper bound of the interval (excluded). |
||||||
|
* @param n Number of sample points. |
||||||
|
* @return the array of samples. |
||||||
|
* @throws NumberIsTooLargeException if the lower bound {@code min} is |
||||||
|
* greater than, or equal to the upper bound {@code max}. |
||||||
|
* @throws NotStrictlyPositiveException if the number of sample points |
||||||
|
* {@code n} is negative. |
||||||
|
*/ |
||||||
|
public static double[] sample(UnivariateFunction f, double min, double max, int n) |
||||||
|
throws NumberIsTooLargeException, NotStrictlyPositiveException { |
||||||
|
|
||||||
|
if (n <= 0) { |
||||||
|
throw new NotStrictlyPositiveException( |
||||||
|
LocalizedFormats.NOT_POSITIVE_NUMBER_OF_SAMPLES, |
||||||
|
Integer.valueOf(n)); |
||||||
|
} |
||||||
|
if (min >= max) { |
||||||
|
throw new NumberIsTooLargeException(min, max, false); |
||||||
|
} |
||||||
|
|
||||||
|
final double[] s = new double[n]; |
||||||
|
final double h = (max - min) / n; |
||||||
|
for (int i = 0; i < n; i++) { |
||||||
|
s[i] = f.value(min + i * h); |
||||||
|
} |
||||||
|
return s; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Convert a {@link UnivariateDifferentiableFunction} into a {@link DifferentiableUnivariateFunction}. |
||||||
|
* |
||||||
|
* @param f function to convert |
||||||
|
* @return converted function |
||||||
|
* @deprecated this conversion method is temporary in version 3.1, as the {@link |
||||||
|
* DifferentiableUnivariateFunction} interface itself is deprecated |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static DifferentiableUnivariateFunction toDifferentiableUnivariateFunction(final UnivariateDifferentiableFunction f) { |
||||||
|
return new DifferentiableUnivariateFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double x) { |
||||||
|
return f.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return new UnivariateFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double x) { |
||||||
|
return f.value(new DerivativeStructure(1, 1, 0, x)).getPartialDerivative(1); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Convert a {@link DifferentiableUnivariateFunction} into a {@link UnivariateDifferentiableFunction}. |
||||||
|
* <p> |
||||||
|
* Note that the converted function is able to handle {@link DerivativeStructure} up to order one. |
||||||
|
* If the function is called with higher order, a {@link NumberIsTooLargeException} is thrown. |
||||||
|
* </p> |
||||||
|
* @param f function to convert |
||||||
|
* @return converted function |
||||||
|
* @deprecated this conversion method is temporary in version 3.1, as the {@link |
||||||
|
* DifferentiableUnivariateFunction} interface itself is deprecated |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static UnivariateDifferentiableFunction toUnivariateDifferential(final DifferentiableUnivariateFunction f) { |
||||||
|
return new UnivariateDifferentiableFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double x) { |
||||||
|
return f.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @exception NumberIsTooLargeException if derivation order is greater than 1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws NumberIsTooLargeException { |
||||||
|
switch (t.getOrder()) { |
||||||
|
case 0 : |
||||||
|
return new DerivativeStructure(t.getFreeParameters(), 0, f.value(t.getValue())); |
||||||
|
case 1 : { |
||||||
|
final int parameters = t.getFreeParameters(); |
||||||
|
final double[] derivatives = new double[parameters + 1]; |
||||||
|
derivatives[0] = f.value(t.getValue()); |
||||||
|
final double fPrime = f.derivative().value(t.getValue()); |
||||||
|
int[] orders = new int[parameters]; |
||||||
|
for (int i = 0; i < parameters; ++i) { |
||||||
|
orders[i] = 1; |
||||||
|
derivatives[i + 1] = fPrime * t.getPartialDerivative(orders); |
||||||
|
orders[i] = 0; |
||||||
|
} |
||||||
|
return new DerivativeStructure(parameters, 1, derivatives); |
||||||
|
} |
||||||
|
default : |
||||||
|
throw new NumberIsTooLargeException(t.getOrder(), 1, true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Convert a {@link MultivariateDifferentiableFunction} into a {@link DifferentiableMultivariateFunction}. |
||||||
|
* |
||||||
|
* @param f function to convert |
||||||
|
* @return converted function |
||||||
|
* @deprecated this conversion method is temporary in version 3.1, as the {@link |
||||||
|
* DifferentiableMultivariateFunction} interface itself is deprecated |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static DifferentiableMultivariateFunction toDifferentiableMultivariateFunction(final MultivariateDifferentiableFunction f) { |
||||||
|
return new DifferentiableMultivariateFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double[] x) { |
||||||
|
return f.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public MultivariateFunction partialDerivative(final int k) { |
||||||
|
return new MultivariateFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double[] x) { |
||||||
|
|
||||||
|
final int n = x.length; |
||||||
|
|
||||||
|
// delegate computation to underlying function
|
||||||
|
final DerivativeStructure[] dsX = new DerivativeStructure[n]; |
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
if (i == k) { |
||||||
|
dsX[i] = new DerivativeStructure(1, 1, 0, x[i]); |
||||||
|
} else { |
||||||
|
dsX[i] = new DerivativeStructure(1, 1, x[i]); |
||||||
|
} |
||||||
|
} |
||||||
|
final DerivativeStructure y = f.value(dsX); |
||||||
|
|
||||||
|
// extract partial derivative
|
||||||
|
return y.getPartialDerivative(1); |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public MultivariateVectorFunction gradient() { |
||||||
|
return new MultivariateVectorFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[] value(final double[] x) { |
||||||
|
|
||||||
|
final int n = x.length; |
||||||
|
|
||||||
|
// delegate computation to underlying function
|
||||||
|
final DerivativeStructure[] dsX = new DerivativeStructure[n]; |
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
dsX[i] = new DerivativeStructure(n, 1, i, x[i]); |
||||||
|
} |
||||||
|
final DerivativeStructure y = f.value(dsX); |
||||||
|
|
||||||
|
// extract gradient
|
||||||
|
final double[] gradient = new double[n]; |
||||||
|
final int[] orders = new int[n]; |
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
orders[i] = 1; |
||||||
|
gradient[i] = y.getPartialDerivative(orders); |
||||||
|
orders[i] = 0; |
||||||
|
} |
||||||
|
|
||||||
|
return gradient; |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Convert a {@link DifferentiableMultivariateFunction} into a {@link MultivariateDifferentiableFunction}. |
||||||
|
* <p> |
||||||
|
* Note that the converted function is able to handle {@link DerivativeStructure} elements |
||||||
|
* that all have the same number of free parameters and order, and with order at most 1. |
||||||
|
* If the function is called with inconsistent numbers of free parameters or higher order, a |
||||||
|
* {@link DimensionMismatchException} or a {@link NumberIsTooLargeException} will be thrown. |
||||||
|
* </p> |
||||||
|
* @param f function to convert |
||||||
|
* @return converted function |
||||||
|
* @deprecated this conversion method is temporary in version 3.1, as the {@link |
||||||
|
* DifferentiableMultivariateFunction} interface itself is deprecated |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static MultivariateDifferentiableFunction toMultivariateDifferentiableFunction(final DifferentiableMultivariateFunction f) { |
||||||
|
return new MultivariateDifferentiableFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double[] x) { |
||||||
|
return f.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @exception NumberIsTooLargeException if derivation order is higher than 1 |
||||||
|
* @exception DimensionMismatchException if numbers of free parameters are inconsistent |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure[] t) |
||||||
|
throws DimensionMismatchException, NumberIsTooLargeException { |
||||||
|
|
||||||
|
// check parameters and orders limits
|
||||||
|
final int parameters = t[0].getFreeParameters(); |
||||||
|
final int order = t[0].getOrder(); |
||||||
|
final int n = t.length; |
||||||
|
if (order > 1) { |
||||||
|
throw new NumberIsTooLargeException(order, 1, true); |
||||||
|
} |
||||||
|
|
||||||
|
// check all elements in the array are consistent
|
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
if (t[i].getFreeParameters() != parameters) { |
||||||
|
throw new DimensionMismatchException(t[i].getFreeParameters(), parameters); |
||||||
|
} |
||||||
|
|
||||||
|
if (t[i].getOrder() != order) { |
||||||
|
throw new DimensionMismatchException(t[i].getOrder(), order); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// delegate computation to underlying function
|
||||||
|
final double[] point = new double[n]; |
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
point[i] = t[i].getValue(); |
||||||
|
} |
||||||
|
final double value = f.value(point); |
||||||
|
final double[] gradient = f.gradient().value(point); |
||||||
|
|
||||||
|
// merge value and gradient into one DerivativeStructure
|
||||||
|
final double[] derivatives = new double[parameters + 1]; |
||||||
|
derivatives[0] = value; |
||||||
|
final int[] orders = new int[parameters]; |
||||||
|
for (int i = 0; i < parameters; ++i) { |
||||||
|
orders[i] = 1; |
||||||
|
for (int j = 0; j < n; ++j) { |
||||||
|
derivatives[i + 1] += gradient[j] * t[j].getPartialDerivative(orders); |
||||||
|
} |
||||||
|
orders[i] = 0; |
||||||
|
} |
||||||
|
|
||||||
|
return new DerivativeStructure(parameters, order, derivatives); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Convert a {@link MultivariateDifferentiableVectorFunction} into a {@link DifferentiableMultivariateVectorFunction}. |
||||||
|
* |
||||||
|
* @param f function to convert |
||||||
|
* @return converted function |
||||||
|
* @deprecated this conversion method is temporary in version 3.1, as the {@link |
||||||
|
* DifferentiableMultivariateVectorFunction} interface itself is deprecated |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static DifferentiableMultivariateVectorFunction toDifferentiableMultivariateVectorFunction(final MultivariateDifferentiableVectorFunction f) { |
||||||
|
return new DifferentiableMultivariateVectorFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[] value(final double[] x) { |
||||||
|
return f.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public MultivariateMatrixFunction jacobian() { |
||||||
|
return new MultivariateMatrixFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[][] value(final double[] x) { |
||||||
|
|
||||||
|
final int n = x.length; |
||||||
|
|
||||||
|
// delegate computation to underlying function
|
||||||
|
final DerivativeStructure[] dsX = new DerivativeStructure[n]; |
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
dsX[i] = new DerivativeStructure(n, 1, i, x[i]); |
||||||
|
} |
||||||
|
final DerivativeStructure[] y = f.value(dsX); |
||||||
|
|
||||||
|
// extract Jacobian
|
||||||
|
final double[][] jacobian = new double[y.length][n]; |
||||||
|
final int[] orders = new int[n]; |
||||||
|
for (int i = 0; i < y.length; ++i) { |
||||||
|
for (int j = 0; j < n; ++j) { |
||||||
|
orders[j] = 1; |
||||||
|
jacobian[i][j] = y[i].getPartialDerivative(orders); |
||||||
|
orders[j] = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return jacobian; |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Convert a {@link DifferentiableMultivariateVectorFunction} into a {@link MultivariateDifferentiableVectorFunction}. |
||||||
|
* <p> |
||||||
|
* Note that the converted function is able to handle {@link DerivativeStructure} elements |
||||||
|
* that all have the same number of free parameters and order, and with order at most 1. |
||||||
|
* If the function is called with inconsistent numbers of free parameters or higher order, a |
||||||
|
* {@link DimensionMismatchException} or a {@link NumberIsTooLargeException} will be thrown. |
||||||
|
* </p> |
||||||
|
* @param f function to convert |
||||||
|
* @return converted function |
||||||
|
* @deprecated this conversion method is temporary in version 3.1, as the {@link |
||||||
|
* DifferentiableMultivariateFunction} interface itself is deprecated |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public static MultivariateDifferentiableVectorFunction toMultivariateDifferentiableVectorFunction(final DifferentiableMultivariateVectorFunction f) { |
||||||
|
return new MultivariateDifferentiableVectorFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[] value(final double[] x) { |
||||||
|
return f.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @exception NumberIsTooLargeException if derivation order is higher than 1 |
||||||
|
* @exception DimensionMismatchException if numbers of free parameters are inconsistent |
||||||
|
*/ |
||||||
|
public DerivativeStructure[] value(final DerivativeStructure[] t) |
||||||
|
throws DimensionMismatchException, NumberIsTooLargeException { |
||||||
|
|
||||||
|
// check parameters and orders limits
|
||||||
|
final int parameters = t[0].getFreeParameters(); |
||||||
|
final int order = t[0].getOrder(); |
||||||
|
final int n = t.length; |
||||||
|
if (order > 1) { |
||||||
|
throw new NumberIsTooLargeException(order, 1, true); |
||||||
|
} |
||||||
|
|
||||||
|
// check all elements in the array are consistent
|
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
if (t[i].getFreeParameters() != parameters) { |
||||||
|
throw new DimensionMismatchException(t[i].getFreeParameters(), parameters); |
||||||
|
} |
||||||
|
|
||||||
|
if (t[i].getOrder() != order) { |
||||||
|
throw new DimensionMismatchException(t[i].getOrder(), order); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// delegate computation to underlying function
|
||||||
|
final double[] point = new double[n]; |
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
point[i] = t[i].getValue(); |
||||||
|
} |
||||||
|
final double[] value = f.value(point); |
||||||
|
final double[][] jacobian = f.jacobian().value(point); |
||||||
|
|
||||||
|
// merge value and Jacobian into a DerivativeStructure array
|
||||||
|
final DerivativeStructure[] merged = new DerivativeStructure[value.length]; |
||||||
|
for (int k = 0; k < merged.length; ++k) { |
||||||
|
final double[] derivatives = new double[parameters + 1]; |
||||||
|
derivatives[0] = value[k]; |
||||||
|
final int[] orders = new int[parameters]; |
||||||
|
for (int i = 0; i < parameters; ++i) { |
||||||
|
orders[i] = 1; |
||||||
|
for (int j = 0; j < n; ++j) { |
||||||
|
derivatives[i + 1] += jacobian[k][j] * t[j].getPartialDerivative(orders); |
||||||
|
} |
||||||
|
orders[i] = 0; |
||||||
|
} |
||||||
|
merged[k] = new DerivativeStructure(parameters, order, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
return merged; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a multivariate real function. |
||||||
|
* |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
public interface MultivariateFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function at the given point. |
||||||
|
* |
||||||
|
* @param point Point at which the function must be evaluated. |
||||||
|
* @return the function value for the given point. |
||||||
|
* @throws DimensionMismatchException |
||||||
|
* if the parameter's dimension is wrong for the function being evaluated. |
||||||
|
* @throws MathIllegalArgumentException |
||||||
|
* when the activated method itself can ascertain that preconditions, |
||||||
|
* specified in the API expressed at the level of the activated method, |
||||||
|
* have been violated. In the vast majority of cases where Commons Math |
||||||
|
* throws this exception, it is the result of argument checking of actual |
||||||
|
* parameters immediately passed to a method. |
||||||
|
*/ |
||||||
|
double value(double[] point); |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a multivariate matrix function. |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
public interface MultivariateMatrixFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function at the given point. |
||||||
|
* @param point point at which the function must be evaluated |
||||||
|
* @return function value for the given point |
||||||
|
* @exception IllegalArgumentException if point's dimension is wrong |
||||||
|
*/ |
||||||
|
double[][] value(double[] point) |
||||||
|
throws IllegalArgumentException; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a multivariate vectorial function. |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
public interface MultivariateVectorFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function at the given point. |
||||||
|
* @param point point at which the function must be evaluated |
||||||
|
* @return function value for the given point |
||||||
|
* @exception IllegalArgumentException if point's dimension is wrong |
||||||
|
*/ |
||||||
|
double[] value(double[] point) |
||||||
|
throws IllegalArgumentException; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a real function that depends on one independent |
||||||
|
* variable plus some extra parameters. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public interface ParametricUnivariateFunction { |
||||||
|
/** |
||||||
|
* Compute the value of the function. |
||||||
|
* |
||||||
|
* @param x Point for which the function value should be computed. |
||||||
|
* @param parameters Function parameters. |
||||||
|
* @return the value. |
||||||
|
*/ |
||||||
|
double value(double x, double ... parameters); |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the gradient of the function with respect to its parameters. |
||||||
|
* |
||||||
|
* @param x Point for which the function value should be computed. |
||||||
|
* @param parameters Function parameters. |
||||||
|
* @return the value. |
||||||
|
*/ |
||||||
|
double[] gradient(double x, double ... parameters); |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.RealFieldElement; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a univariate real function. |
||||||
|
* <p> |
||||||
|
* When a <em>user-defined</em> function encounters an error during |
||||||
|
* evaluation, the {@link #value(RealFieldElement) value} method should throw a |
||||||
|
* <em>user-defined</em> unchecked exception.</p> |
||||||
|
* <p> |
||||||
|
* The following code excerpt shows the recommended way to do that using |
||||||
|
* a root solver as an example, but the same construct is applicable to |
||||||
|
* ODE integrators or optimizers.</p> |
||||||
|
* |
||||||
|
* <pre> |
||||||
|
* private static class LocalException extends RuntimeException { |
||||||
|
* // The x value that caused the problem.
|
||||||
|
* private final SomeFieldType x; |
||||||
|
* |
||||||
|
* public LocalException(SomeFieldType x) { |
||||||
|
* this.x = x; |
||||||
|
* } |
||||||
|
* |
||||||
|
* public double getX() { |
||||||
|
* return x; |
||||||
|
* } |
||||||
|
* } |
||||||
|
* |
||||||
|
* private static class MyFunction implements FieldUnivariateFunction<SomeFieldType> { |
||||||
|
* public SomeFieldType value(SomeFieldType x) { |
||||||
|
* SomeFieldType y = hugeFormula(x); |
||||||
|
* if (somethingBadHappens) { |
||||||
|
* throw new LocalException(x); |
||||||
|
* } |
||||||
|
* return y; |
||||||
|
* } |
||||||
|
* } |
||||||
|
* |
||||||
|
* public void compute() { |
||||||
|
* try { |
||||||
|
* solver.solve(maxEval, new MyFunction(a, b, c), min, max); |
||||||
|
* } catch (LocalException le) { |
||||||
|
* // Retrieve the x value.
|
||||||
|
* } |
||||||
|
* } |
||||||
|
* </pre> |
||||||
|
* |
||||||
|
* As shown, the exception is local to the user's code and it is guaranteed |
||||||
|
* that Apache Commons Math will not catch it. |
||||||
|
* |
||||||
|
* @param <T> the type of the field elements |
||||||
|
* @since 3.6 |
||||||
|
* @see UnivariateFunction |
||||||
|
*/ |
||||||
|
public interface RealFieldUnivariateFunction<T extends RealFieldElement<T>> { |
||||||
|
/** |
||||||
|
* Compute the value of the function. |
||||||
|
* |
||||||
|
* @param x Point at which the function value should be computed. |
||||||
|
* @return the value of the function. |
||||||
|
* @throws IllegalArgumentException when the activated method itself can |
||||||
|
* ascertain that a precondition, specified in the API expressed at the |
||||||
|
* level of the activated method, has been violated. |
||||||
|
* When Commons Math throws an {@code IllegalArgumentException}, it is |
||||||
|
* usually the consequence of checking the actual parameters passed to |
||||||
|
* the method. |
||||||
|
*/ |
||||||
|
T value(T x); |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a trivariate real function. |
||||||
|
* |
||||||
|
* @since 2.2 |
||||||
|
*/ |
||||||
|
public interface TrivariateFunction { |
||||||
|
/** |
||||||
|
* Compute the value for the function. |
||||||
|
* |
||||||
|
* @param x x-coordinate for which the function value should be computed. |
||||||
|
* @param y y-coordinate for which the function value should be computed. |
||||||
|
* @param z z-coordinate for which the function value should be computed. |
||||||
|
* @return the value. |
||||||
|
*/ |
||||||
|
double value(double x, double y, double z); |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a univariate real function. |
||||||
|
* <p> |
||||||
|
* When a <em>user-defined</em> function encounters an error during |
||||||
|
* evaluation, the {@link #value(double) value} method should throw a |
||||||
|
* <em>user-defined</em> unchecked exception.</p> |
||||||
|
* <p> |
||||||
|
* The following code excerpt shows the recommended way to do that using |
||||||
|
* a root solver as an example, but the same construct is applicable to |
||||||
|
* ODE integrators or optimizers.</p> |
||||||
|
* |
||||||
|
* <pre> |
||||||
|
* private static class LocalException extends RuntimeException { |
||||||
|
* // The x value that caused the problem.
|
||||||
|
* private final double x; |
||||||
|
* |
||||||
|
* public LocalException(double x) { |
||||||
|
* this.x = x; |
||||||
|
* } |
||||||
|
* |
||||||
|
* public double getX() { |
||||||
|
* return x; |
||||||
|
* } |
||||||
|
* } |
||||||
|
* |
||||||
|
* private static class MyFunction implements UnivariateFunction { |
||||||
|
* public double value(double x) { |
||||||
|
* double y = hugeFormula(x); |
||||||
|
* if (somethingBadHappens) { |
||||||
|
* throw new LocalException(x); |
||||||
|
* } |
||||||
|
* return y; |
||||||
|
* } |
||||||
|
* } |
||||||
|
* |
||||||
|
* public void compute() { |
||||||
|
* try { |
||||||
|
* solver.solve(maxEval, new MyFunction(a, b, c), min, max); |
||||||
|
* } catch (LocalException le) { |
||||||
|
* // Retrieve the x value.
|
||||||
|
* } |
||||||
|
* } |
||||||
|
* </pre> |
||||||
|
* |
||||||
|
* As shown, the exception is local to the user's code and it is guaranteed |
||||||
|
* that Apache Commons Math will not catch it. |
||||||
|
* |
||||||
|
*/ |
||||||
|
public interface UnivariateFunction { |
||||||
|
/** |
||||||
|
* Compute the value of the function. |
||||||
|
* |
||||||
|
* @param x Point at which the function value should be computed. |
||||||
|
* @return the value of the function. |
||||||
|
* @throws IllegalArgumentException when the activated method itself can |
||||||
|
* ascertain that a precondition, specified in the API expressed at the |
||||||
|
* level of the activated method, has been violated. |
||||||
|
* When Commons Math throws an {@code IllegalArgumentException}, it is |
||||||
|
* usually the consequence of checking the actual parameters passed to |
||||||
|
* the method. |
||||||
|
*/ |
||||||
|
double value(double x); |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a univariate matrix function. |
||||||
|
* |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
public interface UnivariateMatrixFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function. |
||||||
|
* @param x the point for which the function value should be computed |
||||||
|
* @return the value |
||||||
|
*/ |
||||||
|
double[][] value(double x); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface representing a univariate vectorial function. |
||||||
|
* |
||||||
|
* @since 2.0 |
||||||
|
*/ |
||||||
|
public interface UnivariateVectorFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function. |
||||||
|
* @param x the point for which the function value should be computed |
||||||
|
* @return the value |
||||||
|
*/ |
||||||
|
double[] value(double x); |
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,384 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooLargeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateMatrixFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateVectorFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** Univariate functions differentiator using finite differences. |
||||||
|
* <p> |
||||||
|
* This class creates some wrapper objects around regular |
||||||
|
* {@link UnivariateFunction univariate functions} (or {@link |
||||||
|
* UnivariateVectorFunction univariate vector functions} or {@link |
||||||
|
* UnivariateMatrixFunction univariate matrix functions}). These |
||||||
|
* wrapper objects compute derivatives in addition to function |
||||||
|
* values. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* The wrapper objects work by calling the underlying function on |
||||||
|
* a sampling grid around the current point and performing polynomial |
||||||
|
* interpolation. A finite differences scheme with n points is |
||||||
|
* theoretically able to compute derivatives up to order n-1, but |
||||||
|
* it is generally better to have a slight margin. The step size must |
||||||
|
* also be small enough in order for the polynomial approximation to |
||||||
|
* be good in the current point neighborhood, but it should not be too |
||||||
|
* small because numerical instability appears quickly (there are several |
||||||
|
* differences of close points). Choosing the number of points and |
||||||
|
* the step size is highly problem dependent. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* As an example of good and bad settings, lets consider the quintic |
||||||
|
* polynomial function {@code f(x) = (x-1)*(x-0.5)*x*(x+0.5)*(x+1)}. |
||||||
|
* Since it is a polynomial, finite differences with at least 6 points |
||||||
|
* should theoretically recover the exact same polynomial and hence |
||||||
|
* compute accurate derivatives for any order. However, due to numerical |
||||||
|
* errors, we get the following results for a 7 points finite differences |
||||||
|
* for abscissae in the [-10, 10] range: |
||||||
|
* <ul> |
||||||
|
* <li>step size = 0.25, second order derivative error about 9.97e-10</li> |
||||||
|
* <li>step size = 0.25, fourth order derivative error about 5.43e-8</li> |
||||||
|
* <li>step size = 1.0e-6, second order derivative error about 148</li> |
||||||
|
* <li>step size = 1.0e-6, fourth order derivative error about 6.35e+14</li> |
||||||
|
* </ul> |
||||||
|
* <p> |
||||||
|
* This example shows that the small step size is really bad, even simply |
||||||
|
* for second order derivative!</p> |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class FiniteDifferencesDifferentiator |
||||||
|
implements UnivariateFunctionDifferentiator, UnivariateVectorFunctionDifferentiator, |
||||||
|
UnivariateMatrixFunctionDifferentiator, Serializable { |
||||||
|
|
||||||
|
/** Serializable UID. */ |
||||||
|
private static final long serialVersionUID = 20120917L; |
||||||
|
|
||||||
|
/** Number of points to use. */ |
||||||
|
private final int nbPoints; |
||||||
|
|
||||||
|
/** Step size. */ |
||||||
|
private final double stepSize; |
||||||
|
|
||||||
|
/** Half sample span. */ |
||||||
|
private final double halfSampleSpan; |
||||||
|
|
||||||
|
/** Lower bound for independent variable. */ |
||||||
|
private final double tMin; |
||||||
|
|
||||||
|
/** Upper bound for independent variable. */ |
||||||
|
private final double tMax; |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a differentiator with number of points and step size when independent variable is unbounded. |
||||||
|
* <p> |
||||||
|
* Beware that wrong settings for the finite differences differentiator |
||||||
|
* can lead to highly unstable and inaccurate results, especially for |
||||||
|
* high derivation orders. Using very small step sizes is often a |
||||||
|
* <em>bad</em> idea. |
||||||
|
* </p> |
||||||
|
* @param nbPoints number of points to use |
||||||
|
* @param stepSize step size (gap between each point) |
||||||
|
* @exception NotPositiveException if {@code stepsize <= 0} (note that |
||||||
|
* {@link NotPositiveException} extends {@link NumberIsTooSmallException}) |
||||||
|
* @exception NumberIsTooSmallException {@code nbPoint <= 1} |
||||||
|
*/ |
||||||
|
public FiniteDifferencesDifferentiator(final int nbPoints, final double stepSize) |
||||||
|
throws NotPositiveException, NumberIsTooSmallException { |
||||||
|
this(nbPoints, stepSize, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a differentiator with number of points and step size when independent variable is bounded. |
||||||
|
* <p> |
||||||
|
* When the independent variable is bounded (tLower < t < tUpper), the sampling |
||||||
|
* points used for differentiation will be adapted to ensure the constraint holds |
||||||
|
* even near the boundaries. This means the sample will not be centered anymore in |
||||||
|
* these cases. At an extreme case, computing derivatives exactly at the lower bound |
||||||
|
* will lead the sample to be entirely on the right side of the derivation point. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* Note that the boundaries are considered to be excluded for function evaluation. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* Beware that wrong settings for the finite differences differentiator |
||||||
|
* can lead to highly unstable and inaccurate results, especially for |
||||||
|
* high derivation orders. Using very small step sizes is often a |
||||||
|
* <em>bad</em> idea. |
||||||
|
* </p> |
||||||
|
* @param nbPoints number of points to use |
||||||
|
* @param stepSize step size (gap between each point) |
||||||
|
* @param tLower lower bound for independent variable (may be {@code Double.NEGATIVE_INFINITY} |
||||||
|
* if there are no lower bounds) |
||||||
|
* @param tUpper upper bound for independent variable (may be {@code Double.POSITIVE_INFINITY} |
||||||
|
* if there are no upper bounds) |
||||||
|
* @exception NotPositiveException if {@code stepsize <= 0} (note that |
||||||
|
* {@link NotPositiveException} extends {@link NumberIsTooSmallException}) |
||||||
|
* @exception NumberIsTooSmallException {@code nbPoint <= 1} |
||||||
|
* @exception NumberIsTooLargeException {@code stepSize * (nbPoints - 1) >= tUpper - tLower} |
||||||
|
*/ |
||||||
|
public FiniteDifferencesDifferentiator(final int nbPoints, final double stepSize, |
||||||
|
final double tLower, final double tUpper) |
||||||
|
throws NotPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
|
||||||
|
if (nbPoints <= 1) { |
||||||
|
throw new NumberIsTooSmallException(stepSize, 1, false); |
||||||
|
} |
||||||
|
this.nbPoints = nbPoints; |
||||||
|
|
||||||
|
if (stepSize <= 0) { |
||||||
|
throw new NotPositiveException(stepSize); |
||||||
|
} |
||||||
|
this.stepSize = stepSize; |
||||||
|
|
||||||
|
halfSampleSpan = 0.5 * stepSize * (nbPoints - 1); |
||||||
|
if (2 * halfSampleSpan >= tUpper - tLower) { |
||||||
|
throw new NumberIsTooLargeException(2 * halfSampleSpan, tUpper - tLower, false); |
||||||
|
} |
||||||
|
final double safety = FastMath.ulp(halfSampleSpan); |
||||||
|
this.tMin = tLower + halfSampleSpan + safety; |
||||||
|
this.tMax = tUpper - halfSampleSpan - safety; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the number of points to use. |
||||||
|
* @return number of points to use |
||||||
|
*/ |
||||||
|
public int getNbPoints() { |
||||||
|
return nbPoints; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the step size. |
||||||
|
* @return step size |
||||||
|
*/ |
||||||
|
public double getStepSize() { |
||||||
|
return stepSize; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Evaluate derivatives from a sample. |
||||||
|
* <p> |
||||||
|
* Evaluation is done using divided differences. |
||||||
|
* </p> |
||||||
|
* @param t evaluation abscissa value and derivatives |
||||||
|
* @param t0 first sample point abscissa |
||||||
|
* @param y function values sample {@code y[i] = f(t[i]) = f(t0 + i * stepSize)} |
||||||
|
* @return value and derivatives at {@code t} |
||||||
|
* @exception NumberIsTooLargeException if the requested derivation order |
||||||
|
* is larger or equal to the number of points |
||||||
|
*/ |
||||||
|
private DerivativeStructure evaluate(final DerivativeStructure t, final double t0, |
||||||
|
final double[] y) |
||||||
|
throws NumberIsTooLargeException { |
||||||
|
|
||||||
|
// create divided differences diagonal arrays
|
||||||
|
final double[] top = new double[nbPoints]; |
||||||
|
final double[] bottom = new double[nbPoints]; |
||||||
|
|
||||||
|
for (int i = 0; i < nbPoints; ++i) { |
||||||
|
|
||||||
|
// update the bottom diagonal of the divided differences array
|
||||||
|
bottom[i] = y[i]; |
||||||
|
for (int j = 1; j <= i; ++j) { |
||||||
|
bottom[i - j] = (bottom[i - j + 1] - bottom[i - j]) / (j * stepSize); |
||||||
|
} |
||||||
|
|
||||||
|
// update the top diagonal of the divided differences array
|
||||||
|
top[i] = bottom[0]; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// evaluate interpolation polynomial (represented by top diagonal) at t
|
||||||
|
final int order = t.getOrder(); |
||||||
|
final int parameters = t.getFreeParameters(); |
||||||
|
final double[] derivatives = t.getAllDerivatives(); |
||||||
|
final double dt0 = t.getValue() - t0; |
||||||
|
DerivativeStructure interpolation = new DerivativeStructure(parameters, order, 0.0); |
||||||
|
DerivativeStructure monomial = null; |
||||||
|
for (int i = 0; i < nbPoints; ++i) { |
||||||
|
if (i == 0) { |
||||||
|
// start with monomial(t) = 1
|
||||||
|
monomial = new DerivativeStructure(parameters, order, 1.0); |
||||||
|
} else { |
||||||
|
// monomial(t) = (t - t0) * (t - t1) * ... * (t - t(i-1))
|
||||||
|
derivatives[0] = dt0 - (i - 1) * stepSize; |
||||||
|
final DerivativeStructure deltaX = new DerivativeStructure(parameters, order, derivatives); |
||||||
|
monomial = monomial.multiply(deltaX); |
||||||
|
} |
||||||
|
interpolation = interpolation.add(monomial.multiply(top[i])); |
||||||
|
} |
||||||
|
|
||||||
|
return interpolation; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* <p>The returned object cannot compute derivatives to arbitrary orders. The |
||||||
|
* value function will throw a {@link NumberIsTooLargeException} if the requested |
||||||
|
* derivation order is larger or equal to the number of points. |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
public UnivariateDifferentiableFunction differentiate(final UnivariateFunction function) { |
||||||
|
return new UnivariateDifferentiableFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double x) throws MathIllegalArgumentException { |
||||||
|
return function.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws MathIllegalArgumentException { |
||||||
|
|
||||||
|
// check we can achieve the requested derivation order with the sample
|
||||||
|
if (t.getOrder() >= nbPoints) { |
||||||
|
throw new NumberIsTooLargeException(t.getOrder(), nbPoints, false); |
||||||
|
} |
||||||
|
|
||||||
|
// compute sample position, trying to be centered if possible
|
||||||
|
final double t0 = FastMath.max(FastMath.min(t.getValue(), tMax), tMin) - halfSampleSpan; |
||||||
|
|
||||||
|
// compute sample points
|
||||||
|
final double[] y = new double[nbPoints]; |
||||||
|
for (int i = 0; i < nbPoints; ++i) { |
||||||
|
y[i] = function.value(t0 + i * stepSize); |
||||||
|
} |
||||||
|
|
||||||
|
// evaluate derivatives
|
||||||
|
return evaluate(t, t0, y); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* <p>The returned object cannot compute derivatives to arbitrary orders. The |
||||||
|
* value function will throw a {@link NumberIsTooLargeException} if the requested |
||||||
|
* derivation order is larger or equal to the number of points. |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
public UnivariateDifferentiableVectorFunction differentiate(final UnivariateVectorFunction function) { |
||||||
|
return new UnivariateDifferentiableVectorFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[]value(final double x) throws MathIllegalArgumentException { |
||||||
|
return function.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public DerivativeStructure[] value(final DerivativeStructure t) |
||||||
|
throws MathIllegalArgumentException { |
||||||
|
|
||||||
|
// check we can achieve the requested derivation order with the sample
|
||||||
|
if (t.getOrder() >= nbPoints) { |
||||||
|
throw new NumberIsTooLargeException(t.getOrder(), nbPoints, false); |
||||||
|
} |
||||||
|
|
||||||
|
// compute sample position, trying to be centered if possible
|
||||||
|
final double t0 = FastMath.max(FastMath.min(t.getValue(), tMax), tMin) - halfSampleSpan; |
||||||
|
|
||||||
|
// compute sample points
|
||||||
|
double[][] y = null; |
||||||
|
for (int i = 0; i < nbPoints; ++i) { |
||||||
|
final double[] v = function.value(t0 + i * stepSize); |
||||||
|
if (i == 0) { |
||||||
|
y = new double[v.length][nbPoints]; |
||||||
|
} |
||||||
|
for (int j = 0; j < v.length; ++j) { |
||||||
|
y[j][i] = v[j]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// evaluate derivatives
|
||||||
|
final DerivativeStructure[] value = new DerivativeStructure[y.length]; |
||||||
|
for (int j = 0; j < value.length; ++j) { |
||||||
|
value[j] = evaluate(t, t0, y[j]); |
||||||
|
} |
||||||
|
|
||||||
|
return value; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* <p>The returned object cannot compute derivatives to arbitrary orders. The |
||||||
|
* value function will throw a {@link NumberIsTooLargeException} if the requested |
||||||
|
* derivation order is larger or equal to the number of points. |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
public UnivariateDifferentiableMatrixFunction differentiate(final UnivariateMatrixFunction function) { |
||||||
|
return new UnivariateDifferentiableMatrixFunction() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[][] value(final double x) throws MathIllegalArgumentException { |
||||||
|
return function.value(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public DerivativeStructure[][] value(final DerivativeStructure t) |
||||||
|
throws MathIllegalArgumentException { |
||||||
|
|
||||||
|
// check we can achieve the requested derivation order with the sample
|
||||||
|
if (t.getOrder() >= nbPoints) { |
||||||
|
throw new NumberIsTooLargeException(t.getOrder(), nbPoints, false); |
||||||
|
} |
||||||
|
|
||||||
|
// compute sample position, trying to be centered if possible
|
||||||
|
final double t0 = FastMath.max(FastMath.min(t.getValue(), tMax), tMin) - halfSampleSpan; |
||||||
|
|
||||||
|
// compute sample points
|
||||||
|
double[][][] y = null; |
||||||
|
for (int i = 0; i < nbPoints; ++i) { |
||||||
|
final double[][] v = function.value(t0 + i * stepSize); |
||||||
|
if (i == 0) { |
||||||
|
y = new double[v.length][v[0].length][nbPoints]; |
||||||
|
} |
||||||
|
for (int j = 0; j < v.length; ++j) { |
||||||
|
for (int k = 0; k < v[j].length; ++k) { |
||||||
|
y[j][k][i] = v[j][k]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// evaluate derivatives
|
||||||
|
final DerivativeStructure[][] value = new DerivativeStructure[y.length][y[0].length]; |
||||||
|
for (int j = 0; j < value.length; ++j) { |
||||||
|
for (int k = 0; k < y[j].length; ++k) { |
||||||
|
value[j][k] = evaluate(t, t0, y[j][k]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return value; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.MultivariateVectorFunction; |
||||||
|
|
||||||
|
/** Class representing the gradient of a multivariate function. |
||||||
|
* <p> |
||||||
|
* The vectorial components of the function represent the derivatives |
||||||
|
* with respect to each function parameters. |
||||||
|
* </p> |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class GradientFunction implements MultivariateVectorFunction { |
||||||
|
|
||||||
|
/** Underlying real-valued function. */ |
||||||
|
private final MultivariateDifferentiableFunction f; |
||||||
|
|
||||||
|
/** Simple constructor. |
||||||
|
* @param f underlying real-valued function |
||||||
|
*/ |
||||||
|
public GradientFunction(final MultivariateDifferentiableFunction f) { |
||||||
|
this.f = f; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[] value(double[] point) { |
||||||
|
|
||||||
|
// set up parameters
|
||||||
|
final DerivativeStructure[] dsX = new DerivativeStructure[point.length]; |
||||||
|
for (int i = 0; i < point.length; ++i) { |
||||||
|
dsX[i] = new DerivativeStructure(point.length, 1, i, point[i]); |
||||||
|
} |
||||||
|
|
||||||
|
// compute the derivatives
|
||||||
|
final DerivativeStructure dsY = f.value(dsX); |
||||||
|
|
||||||
|
// extract the gradient
|
||||||
|
final double[] y = new double[point.length]; |
||||||
|
final int[] orders = new int[point.length]; |
||||||
|
for (int i = 0; i < point.length; ++i) { |
||||||
|
orders[i] = 1; |
||||||
|
y[i] = dsY.getPartialDerivative(orders); |
||||||
|
orders[i] = 0; |
||||||
|
} |
||||||
|
|
||||||
|
return y; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.MultivariateMatrixFunction; |
||||||
|
|
||||||
|
/** Class representing the Jacobian of a multivariate vector function. |
||||||
|
* <p> |
||||||
|
* The rows iterate on the model functions while the columns iterate on the parameters; thus, |
||||||
|
* the numbers of rows is equal to the dimension of the underlying function vector |
||||||
|
* value and the number of columns is equal to the number of free parameters of |
||||||
|
* the underlying function. |
||||||
|
* </p> |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class JacobianFunction implements MultivariateMatrixFunction { |
||||||
|
|
||||||
|
/** Underlying vector-valued function. */ |
||||||
|
private final MultivariateDifferentiableVectorFunction f; |
||||||
|
|
||||||
|
/** Simple constructor. |
||||||
|
* @param f underlying vector-valued function |
||||||
|
*/ |
||||||
|
public JacobianFunction(final MultivariateDifferentiableVectorFunction f) { |
||||||
|
this.f = f; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double[][] value(double[] point) { |
||||||
|
|
||||||
|
// set up parameters
|
||||||
|
final DerivativeStructure[] dsX = new DerivativeStructure[point.length]; |
||||||
|
for (int i = 0; i < point.length; ++i) { |
||||||
|
dsX[i] = new DerivativeStructure(point.length, 1, i, point[i]); |
||||||
|
} |
||||||
|
|
||||||
|
// compute the derivatives
|
||||||
|
final DerivativeStructure[] dsY = f.value(dsX); |
||||||
|
|
||||||
|
// extract the Jacobian
|
||||||
|
final double[][] y = new double[dsY.length][point.length]; |
||||||
|
final int[] orders = new int[point.length]; |
||||||
|
for (int i = 0; i < dsY.length; ++i) { |
||||||
|
for (int j = 0; j < point.length; ++j) { |
||||||
|
orders[j] = 1; |
||||||
|
y[i][j] = dsY[i].getPartialDerivative(orders); |
||||||
|
orders[j] = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return y; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.MultivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link MultivariateFunction} representing a |
||||||
|
* multivariate differentiable real function. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface MultivariateDifferentiableFunction extends MultivariateFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function at the given point. |
||||||
|
* |
||||||
|
* @param point Point at which the function must be evaluated. |
||||||
|
* @return the function value for the given point. |
||||||
|
* @exception MathIllegalArgumentException if {@code point} does not |
||||||
|
* satisfy the function's constraints (wrong dimension, argument out of bound, |
||||||
|
* or unsupported derivative order for example) |
||||||
|
*/ |
||||||
|
DerivativeStructure value(DerivativeStructure[] point) |
||||||
|
throws MathIllegalArgumentException; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.MultivariateVectorFunction; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link MultivariateVectorFunction} representing a |
||||||
|
* multivariate differentiable vectorial function. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface MultivariateDifferentiableVectorFunction |
||||||
|
extends MultivariateVectorFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function at the given point. |
||||||
|
* @param point point at which the function must be evaluated |
||||||
|
* @return function value for the given point |
||||||
|
* @exception MathIllegalArgumentException if {@code point} does not |
||||||
|
* satisfy the function's constraints (wrong dimension, argument out of bound, |
||||||
|
* or unsupported derivative order for example) |
||||||
|
*/ |
||||||
|
DerivativeStructure[] value(DerivativeStructure[] point) |
||||||
|
throws MathIllegalArgumentException; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,877 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.Field; |
||||||
|
import com.fr.third.org.apache.commons.math3.FieldElement; |
||||||
|
import com.fr.third.org.apache.commons.math3.RealFieldElement; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.MathArrays; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.MathUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Precision; |
||||||
|
|
||||||
|
/** |
||||||
|
* First derivative computation with large number of variables. |
||||||
|
* <p> |
||||||
|
* This class plays a similar role to {@link DerivativeStructure}, with |
||||||
|
* a focus on efficiency when dealing with large number of independent variables |
||||||
|
* and most computation depend only on a few of them, and when only first derivative |
||||||
|
* is desired. When these conditions are met, this class should be much faster than |
||||||
|
* {@link DerivativeStructure} and use less memory. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @since 3.3 |
||||||
|
*/ |
||||||
|
public class SparseGradient implements RealFieldElement<SparseGradient>, Serializable { |
||||||
|
|
||||||
|
/** Serializable UID. */ |
||||||
|
private static final long serialVersionUID = 20131025L; |
||||||
|
|
||||||
|
/** Value of the calculation. */ |
||||||
|
private double value; |
||||||
|
|
||||||
|
/** Stored derivative, each key representing a different independent variable. */ |
||||||
|
private final Map<Integer, Double> derivatives; |
||||||
|
|
||||||
|
/** Internal constructor. |
||||||
|
* @param value value of the function |
||||||
|
* @param derivatives derivatives map, a deep copy will be performed, |
||||||
|
* so the map given here will remain safe from changes in the new instance, |
||||||
|
* may be null to create an empty derivatives map, i.e. a constant value |
||||||
|
*/ |
||||||
|
private SparseGradient(final double value, final Map<Integer, Double> derivatives) { |
||||||
|
this.value = value; |
||||||
|
this.derivatives = new HashMap<Integer, Double>(); |
||||||
|
if (derivatives != null) { |
||||||
|
this.derivatives.putAll(derivatives); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** Internal constructor. |
||||||
|
* @param value value of the function |
||||||
|
* @param scale scaling factor to apply to all derivatives |
||||||
|
* @param derivatives derivatives map, a deep copy will be performed, |
||||||
|
* so the map given here will remain safe from changes in the new instance, |
||||||
|
* may be null to create an empty derivatives map, i.e. a constant value |
||||||
|
*/ |
||||||
|
private SparseGradient(final double value, final double scale, |
||||||
|
final Map<Integer, Double> derivatives) { |
||||||
|
this.value = value; |
||||||
|
this.derivatives = new HashMap<Integer, Double>(); |
||||||
|
if (derivatives != null) { |
||||||
|
for (final Map.Entry<Integer, Double> entry : derivatives.entrySet()) { |
||||||
|
this.derivatives.put(entry.getKey(), scale * entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** Factory method creating a constant. |
||||||
|
* @param value value of the constant |
||||||
|
* @return a new instance |
||||||
|
*/ |
||||||
|
public static SparseGradient createConstant(final double value) { |
||||||
|
return new SparseGradient(value, Collections.<Integer, Double> emptyMap()); |
||||||
|
} |
||||||
|
|
||||||
|
/** Factory method creating an independent variable. |
||||||
|
* @param idx index of the variable |
||||||
|
* @param value value of the variable |
||||||
|
* @return a new instance |
||||||
|
*/ |
||||||
|
public static SparseGradient createVariable(final int idx, final double value) { |
||||||
|
return new SparseGradient(value, Collections.singletonMap(idx, 1.0)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Find the number of variables. |
||||||
|
* @return number of variables |
||||||
|
*/ |
||||||
|
public int numVars() { |
||||||
|
return derivatives.size(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the derivative with respect to a particular index variable. |
||||||
|
* |
||||||
|
* @param index index to differentiate with. |
||||||
|
* @return derivative with respect to a particular index variable |
||||||
|
*/ |
||||||
|
public double getDerivative(final int index) { |
||||||
|
final Double out = derivatives.get(index); |
||||||
|
return (out == null) ? 0.0 : out; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the value of the function. |
||||||
|
* @return value of the function. |
||||||
|
*/ |
||||||
|
public double getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double getReal() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient add(final SparseGradient a) { |
||||||
|
final SparseGradient out = new SparseGradient(value + a.value, derivatives); |
||||||
|
for (Map.Entry<Integer, Double> entry : a.derivatives.entrySet()) { |
||||||
|
final int id = entry.getKey(); |
||||||
|
final Double old = out.derivatives.get(id); |
||||||
|
if (old == null) { |
||||||
|
out.derivatives.put(id, entry.getValue()); |
||||||
|
} else { |
||||||
|
out.derivatives.put(id, old + entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add in place. |
||||||
|
* <p> |
||||||
|
* This method is designed to be faster when used multiple times in a loop. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* The instance is changed here, in order to not change the |
||||||
|
* instance the {@link #add(SparseGradient)} method should |
||||||
|
* be used. |
||||||
|
* </p> |
||||||
|
* @param a instance to add |
||||||
|
*/ |
||||||
|
public void addInPlace(final SparseGradient a) { |
||||||
|
value += a.value; |
||||||
|
for (final Map.Entry<Integer, Double> entry : a.derivatives.entrySet()) { |
||||||
|
final int id = entry.getKey(); |
||||||
|
final Double old = derivatives.get(id); |
||||||
|
if (old == null) { |
||||||
|
derivatives.put(id, entry.getValue()); |
||||||
|
} else { |
||||||
|
derivatives.put(id, old + entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient add(final double c) { |
||||||
|
final SparseGradient out = new SparseGradient(value + c, derivatives); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient subtract(final SparseGradient a) { |
||||||
|
final SparseGradient out = new SparseGradient(value - a.value, derivatives); |
||||||
|
for (Map.Entry<Integer, Double> entry : a.derivatives.entrySet()) { |
||||||
|
final int id = entry.getKey(); |
||||||
|
final Double old = out.derivatives.get(id); |
||||||
|
if (old == null) { |
||||||
|
out.derivatives.put(id, -entry.getValue()); |
||||||
|
} else { |
||||||
|
out.derivatives.put(id, old - entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient subtract(double c) { |
||||||
|
return new SparseGradient(value - c, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient multiply(final SparseGradient a) { |
||||||
|
final SparseGradient out = |
||||||
|
new SparseGradient(value * a.value, Collections.<Integer, Double> emptyMap()); |
||||||
|
|
||||||
|
// Derivatives.
|
||||||
|
for (Map.Entry<Integer, Double> entry : derivatives.entrySet()) { |
||||||
|
out.derivatives.put(entry.getKey(), a.value * entry.getValue()); |
||||||
|
} |
||||||
|
for (Map.Entry<Integer, Double> entry : a.derivatives.entrySet()) { |
||||||
|
final int id = entry.getKey(); |
||||||
|
final Double old = out.derivatives.get(id); |
||||||
|
if (old == null) { |
||||||
|
out.derivatives.put(id, value * entry.getValue()); |
||||||
|
} else { |
||||||
|
out.derivatives.put(id, old + value * entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiply in place. |
||||||
|
* <p> |
||||||
|
* This method is designed to be faster when used multiple times in a loop. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* The instance is changed here, in order to not change the |
||||||
|
* instance the {@link #add(SparseGradient)} method should |
||||||
|
* be used. |
||||||
|
* </p> |
||||||
|
* @param a instance to multiply |
||||||
|
*/ |
||||||
|
public void multiplyInPlace(final SparseGradient a) { |
||||||
|
// Derivatives.
|
||||||
|
for (Map.Entry<Integer, Double> entry : derivatives.entrySet()) { |
||||||
|
derivatives.put(entry.getKey(), a.value * entry.getValue()); |
||||||
|
} |
||||||
|
for (Map.Entry<Integer, Double> entry : a.derivatives.entrySet()) { |
||||||
|
final int id = entry.getKey(); |
||||||
|
final Double old = derivatives.get(id); |
||||||
|
if (old == null) { |
||||||
|
derivatives.put(id, value * entry.getValue()); |
||||||
|
} else { |
||||||
|
derivatives.put(id, old + value * entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
value *= a.value; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient multiply(final double c) { |
||||||
|
return new SparseGradient(value * c, c, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient multiply(final int n) { |
||||||
|
return new SparseGradient(value * n, n, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient divide(final SparseGradient a) { |
||||||
|
final SparseGradient out = new SparseGradient(value / a.value, Collections.<Integer, Double> emptyMap()); |
||||||
|
|
||||||
|
// Derivatives.
|
||||||
|
for (Map.Entry<Integer, Double> entry : derivatives.entrySet()) { |
||||||
|
out.derivatives.put(entry.getKey(), entry.getValue() / a.value); |
||||||
|
} |
||||||
|
for (Map.Entry<Integer, Double> entry : a.derivatives.entrySet()) { |
||||||
|
final int id = entry.getKey(); |
||||||
|
final Double old = out.derivatives.get(id); |
||||||
|
if (old == null) { |
||||||
|
out.derivatives.put(id, -out.value / a.value * entry.getValue()); |
||||||
|
} else { |
||||||
|
out.derivatives.put(id, old - out.value / a.value * entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient divide(final double c) { |
||||||
|
return new SparseGradient(value / c, 1.0 / c, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient negate() { |
||||||
|
return new SparseGradient(-value, -1.0, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public Field<SparseGradient> getField() { |
||||||
|
return new Field<SparseGradient>() { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient getZero() { |
||||||
|
return createConstant(0); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient getOne() { |
||||||
|
return createConstant(1); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public Class<? extends FieldElement<SparseGradient>> getRuntimeClass() { |
||||||
|
return SparseGradient.class; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient remainder(final double a) { |
||||||
|
return new SparseGradient(FastMath.IEEEremainder(value, a), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient remainder(final SparseGradient a) { |
||||||
|
|
||||||
|
// compute k such that lhs % rhs = lhs - k rhs
|
||||||
|
final double rem = FastMath.IEEEremainder(value, a.value); |
||||||
|
final double k = FastMath.rint((value - rem) / a.value); |
||||||
|
|
||||||
|
return subtract(a.multiply(k)); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient abs() { |
||||||
|
if (Double.doubleToLongBits(value) < 0) { |
||||||
|
// we use the bits representation to also handle -0.0
|
||||||
|
return negate(); |
||||||
|
} else { |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient ceil() { |
||||||
|
return createConstant(FastMath.ceil(value)); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient floor() { |
||||||
|
return createConstant(FastMath.floor(value)); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient rint() { |
||||||
|
return createConstant(FastMath.rint(value)); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public long round() { |
||||||
|
return FastMath.round(value); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient signum() { |
||||||
|
return createConstant(FastMath.signum(value)); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient copySign(final SparseGradient sign) { |
||||||
|
final long m = Double.doubleToLongBits(value); |
||||||
|
final long s = Double.doubleToLongBits(sign.value); |
||||||
|
if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK
|
||||||
|
return this; |
||||||
|
} |
||||||
|
return negate(); // flip sign
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient copySign(final double sign) { |
||||||
|
final long m = Double.doubleToLongBits(value); |
||||||
|
final long s = Double.doubleToLongBits(sign); |
||||||
|
if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK
|
||||||
|
return this; |
||||||
|
} |
||||||
|
return negate(); // flip sign
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient scalb(final int n) { |
||||||
|
final SparseGradient out = new SparseGradient(FastMath.scalb(value, n), Collections.<Integer, Double> emptyMap()); |
||||||
|
for (Map.Entry<Integer, Double> entry : derivatives.entrySet()) { |
||||||
|
out.derivatives.put(entry.getKey(), FastMath.scalb(entry.getValue(), n)); |
||||||
|
} |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient hypot(final SparseGradient y) { |
||||||
|
if (Double.isInfinite(value) || Double.isInfinite(y.value)) { |
||||||
|
return createConstant(Double.POSITIVE_INFINITY); |
||||||
|
} else if (Double.isNaN(value) || Double.isNaN(y.value)) { |
||||||
|
return createConstant(Double.NaN); |
||||||
|
} else { |
||||||
|
|
||||||
|
final int expX = FastMath.getExponent(value); |
||||||
|
final int expY = FastMath.getExponent(y.value); |
||||||
|
if (expX > expY + 27) { |
||||||
|
// y is negligible with respect to x
|
||||||
|
return abs(); |
||||||
|
} else if (expY > expX + 27) { |
||||||
|
// x is negligible with respect to y
|
||||||
|
return y.abs(); |
||||||
|
} else { |
||||||
|
|
||||||
|
// find an intermediate scale to avoid both overflow and underflow
|
||||||
|
final int middleExp = (expX + expY) / 2; |
||||||
|
|
||||||
|
// scale parameters without losing precision
|
||||||
|
final SparseGradient scaledX = scalb(-middleExp); |
||||||
|
final SparseGradient scaledY = y.scalb(-middleExp); |
||||||
|
|
||||||
|
// compute scaled hypotenuse
|
||||||
|
final SparseGradient scaledH = |
||||||
|
scaledX.multiply(scaledX).add(scaledY.multiply(scaledY)).sqrt(); |
||||||
|
|
||||||
|
// remove scaling
|
||||||
|
return scaledH.scalb(middleExp); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the hypotenuse of a triangle with sides {@code x} and {@code y} |
||||||
|
* - sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>) |
||||||
|
* avoiding intermediate overflow or underflow. |
||||||
|
* |
||||||
|
* <ul> |
||||||
|
* <li> If either argument is infinite, then the result is positive infinity.</li> |
||||||
|
* <li> else, if either argument is NaN then the result is NaN.</li> |
||||||
|
* </ul> |
||||||
|
* |
||||||
|
* @param x a value |
||||||
|
* @param y a value |
||||||
|
* @return sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>) |
||||||
|
*/ |
||||||
|
public static SparseGradient hypot(final SparseGradient x, final SparseGradient y) { |
||||||
|
return x.hypot(y); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient reciprocal() { |
||||||
|
return new SparseGradient(1.0 / value, -1.0 / (value * value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient sqrt() { |
||||||
|
final double sqrt = FastMath.sqrt(value); |
||||||
|
return new SparseGradient(sqrt, 0.5 / sqrt, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient cbrt() { |
||||||
|
final double cbrt = FastMath.cbrt(value); |
||||||
|
return new SparseGradient(cbrt, 1.0 / (3 * cbrt * cbrt), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient rootN(final int n) { |
||||||
|
if (n == 2) { |
||||||
|
return sqrt(); |
||||||
|
} else if (n == 3) { |
||||||
|
return cbrt(); |
||||||
|
} else { |
||||||
|
final double root = FastMath.pow(value, 1.0 / n); |
||||||
|
return new SparseGradient(root, 1.0 / (n * FastMath.pow(root, n - 1)), derivatives); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient pow(final double p) { |
||||||
|
return new SparseGradient(FastMath.pow(value, p), p * FastMath.pow(value, p - 1), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient pow(final int n) { |
||||||
|
if (n == 0) { |
||||||
|
return getField().getOne(); |
||||||
|
} else { |
||||||
|
final double valueNm1 = FastMath.pow(value, n - 1); |
||||||
|
return new SparseGradient(value * valueNm1, n * valueNm1, derivatives); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient pow(final SparseGradient e) { |
||||||
|
return log().multiply(e).exp(); |
||||||
|
} |
||||||
|
|
||||||
|
/** Compute a<sup>x</sup> where a is a double and x a {@link SparseGradient} |
||||||
|
* @param a number to exponentiate |
||||||
|
* @param x power to apply |
||||||
|
* @return a<sup>x</sup> |
||||||
|
*/ |
||||||
|
public static SparseGradient pow(final double a, final SparseGradient x) { |
||||||
|
if (a == 0) { |
||||||
|
if (x.value == 0) { |
||||||
|
return x.compose(1.0, Double.NEGATIVE_INFINITY); |
||||||
|
} else if (x.value < 0) { |
||||||
|
return x.compose(Double.NaN, Double.NaN); |
||||||
|
} else { |
||||||
|
return x.getField().getZero(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
final double ax = FastMath.pow(a, x.value); |
||||||
|
return new SparseGradient(ax, ax * FastMath.log(a), x.derivatives); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient exp() { |
||||||
|
final double e = FastMath.exp(value); |
||||||
|
return new SparseGradient(e, e, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient expm1() { |
||||||
|
return new SparseGradient(FastMath.expm1(value), FastMath.exp(value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient log() { |
||||||
|
return new SparseGradient(FastMath.log(value), 1.0 / value, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** Base 10 logarithm. |
||||||
|
* @return base 10 logarithm of the instance |
||||||
|
*/ |
||||||
|
public SparseGradient log10() { |
||||||
|
return new SparseGradient(FastMath.log10(value), 1.0 / (FastMath.log(10.0) * value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient log1p() { |
||||||
|
return new SparseGradient(FastMath.log1p(value), 1.0 / (1.0 + value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient cos() { |
||||||
|
return new SparseGradient(FastMath.cos(value), -FastMath.sin(value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient sin() { |
||||||
|
return new SparseGradient(FastMath.sin(value), FastMath.cos(value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient tan() { |
||||||
|
final double t = FastMath.tan(value); |
||||||
|
return new SparseGradient(t, 1 + t * t, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient acos() { |
||||||
|
return new SparseGradient(FastMath.acos(value), -1.0 / FastMath.sqrt(1 - value * value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient asin() { |
||||||
|
return new SparseGradient(FastMath.asin(value), 1.0 / FastMath.sqrt(1 - value * value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient atan() { |
||||||
|
return new SparseGradient(FastMath.atan(value), 1.0 / (1 + value * value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient atan2(final SparseGradient x) { |
||||||
|
|
||||||
|
// compute r = sqrt(x^2+y^2)
|
||||||
|
final SparseGradient r = multiply(this).add(x.multiply(x)).sqrt(); |
||||||
|
|
||||||
|
final SparseGradient a; |
||||||
|
if (x.value >= 0) { |
||||||
|
|
||||||
|
// compute atan2(y, x) = 2 atan(y / (r + x))
|
||||||
|
a = divide(r.add(x)).atan().multiply(2); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
|
||||||
|
final SparseGradient tmp = divide(r.subtract(x)).atan().multiply(-2); |
||||||
|
a = tmp.add(tmp.value <= 0 ? -FastMath.PI : FastMath.PI); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// fix value to take special cases (+0/+0, +0/-0, -0/+0, -0/-0, +/-infinity) correctly
|
||||||
|
a.value = FastMath.atan2(value, x.value); |
||||||
|
|
||||||
|
return a; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** Two arguments arc tangent operation. |
||||||
|
* @param y first argument of the arc tangent |
||||||
|
* @param x second argument of the arc tangent |
||||||
|
* @return atan2(y, x) |
||||||
|
*/ |
||||||
|
public static SparseGradient atan2(final SparseGradient y, final SparseGradient x) { |
||||||
|
return y.atan2(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient cosh() { |
||||||
|
return new SparseGradient(FastMath.cosh(value), FastMath.sinh(value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient sinh() { |
||||||
|
return new SparseGradient(FastMath.sinh(value), FastMath.cosh(value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient tanh() { |
||||||
|
final double t = FastMath.tanh(value); |
||||||
|
return new SparseGradient(t, 1 - t * t, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient acosh() { |
||||||
|
return new SparseGradient(FastMath.acosh(value), 1.0 / FastMath.sqrt(value * value - 1.0), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient asinh() { |
||||||
|
return new SparseGradient(FastMath.asinh(value), 1.0 / FastMath.sqrt(value * value + 1.0), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient atanh() { |
||||||
|
return new SparseGradient(FastMath.atanh(value), 1.0 / (1.0 - value * value), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** Convert radians to degrees, with error of less than 0.5 ULP |
||||||
|
* @return instance converted into degrees |
||||||
|
*/ |
||||||
|
public SparseGradient toDegrees() { |
||||||
|
return new SparseGradient(FastMath.toDegrees(value), FastMath.toDegrees(1.0), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** Convert degrees to radians, with error of less than 0.5 ULP |
||||||
|
* @return instance converted into radians |
||||||
|
*/ |
||||||
|
public SparseGradient toRadians() { |
||||||
|
return new SparseGradient(FastMath.toRadians(value), FastMath.toRadians(1.0), derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** Evaluate Taylor expansion of a sparse gradient. |
||||||
|
* @param delta parameters offsets (Δx, Δy, ...) |
||||||
|
* @return value of the Taylor expansion at x + Δx, y + Δy, ... |
||||||
|
*/ |
||||||
|
public double taylor(final double ... delta) { |
||||||
|
double y = value; |
||||||
|
for (int i = 0; i < delta.length; ++i) { |
||||||
|
y += delta[i] * getDerivative(i); |
||||||
|
} |
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
/** Compute composition of the instance by a univariate function. |
||||||
|
* @param f0 value of the function at (i.e. f({@link #getValue()})) |
||||||
|
* @param f1 first derivative of the function at |
||||||
|
* the current point (i.e. f'({@link #getValue()})) |
||||||
|
* @return f(this) |
||||||
|
*/ |
||||||
|
public SparseGradient compose(final double f0, final double f1) { |
||||||
|
return new SparseGradient(f0, f1, derivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final SparseGradient[] a, |
||||||
|
final SparseGradient[] b) |
||||||
|
throws DimensionMismatchException { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = a[0].getField().getZero(); |
||||||
|
for (int i = 0; i < a.length; ++i) { |
||||||
|
out = out.add(a[i].multiply(b[i])); |
||||||
|
} |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
final double[] aDouble = new double[a.length]; |
||||||
|
for (int i = 0; i < a.length; ++i) { |
||||||
|
aDouble[i] = a[i].getValue(); |
||||||
|
} |
||||||
|
final double[] bDouble = new double[b.length]; |
||||||
|
for (int i = 0; i < b.length; ++i) { |
||||||
|
bDouble[i] = b[i].getValue(); |
||||||
|
} |
||||||
|
out.value = MathArrays.linearCombination(aDouble, bDouble); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final double[] a, final SparseGradient[] b) { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = b[0].getField().getZero(); |
||||||
|
for (int i = 0; i < a.length; ++i) { |
||||||
|
out = out.add(b[i].multiply(a[i])); |
||||||
|
} |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
final double[] bDouble = new double[b.length]; |
||||||
|
for (int i = 0; i < b.length; ++i) { |
||||||
|
bDouble[i] = b[i].getValue(); |
||||||
|
} |
||||||
|
out.value = MathArrays.linearCombination(a, bDouble); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final SparseGradient a1, final SparseGradient b1, |
||||||
|
final SparseGradient a2, final SparseGradient b2) { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = a1.multiply(b1).add(a2.multiply(b2)); |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
out.value = MathArrays.linearCombination(a1.value, b1.value, a2.value, b2.value); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final double a1, final SparseGradient b1, |
||||||
|
final double a2, final SparseGradient b2) { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = b1.multiply(a1).add(b2.multiply(a2)); |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
out.value = MathArrays.linearCombination(a1, b1.value, a2, b2.value); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final SparseGradient a1, final SparseGradient b1, |
||||||
|
final SparseGradient a2, final SparseGradient b2, |
||||||
|
final SparseGradient a3, final SparseGradient b3) { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3)); |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
out.value = MathArrays.linearCombination(a1.value, b1.value, |
||||||
|
a2.value, b2.value, |
||||||
|
a3.value, b3.value); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final double a1, final SparseGradient b1, |
||||||
|
final double a2, final SparseGradient b2, |
||||||
|
final double a3, final SparseGradient b3) { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3)); |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
out.value = MathArrays.linearCombination(a1, b1.value, |
||||||
|
a2, b2.value, |
||||||
|
a3, b3.value); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final SparseGradient a1, final SparseGradient b1, |
||||||
|
final SparseGradient a2, final SparseGradient b2, |
||||||
|
final SparseGradient a3, final SparseGradient b3, |
||||||
|
final SparseGradient a4, final SparseGradient b4) { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = a1.multiply(b1).add(a2.multiply(b2)).add(a3.multiply(b3)).add(a4.multiply(b4)); |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
out.value = MathArrays.linearCombination(a1.value, b1.value, |
||||||
|
a2.value, b2.value, |
||||||
|
a3.value, b3.value, |
||||||
|
a4.value, b4.value); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public SparseGradient linearCombination(final double a1, final SparseGradient b1, |
||||||
|
final double a2, final SparseGradient b2, |
||||||
|
final double a3, final SparseGradient b3, |
||||||
|
final double a4, final SparseGradient b4) { |
||||||
|
|
||||||
|
// compute a simple value, with all partial derivatives
|
||||||
|
SparseGradient out = b1.multiply(a1).add(b2.multiply(a2)).add(b3.multiply(a3)).add(b4.multiply(a4)); |
||||||
|
|
||||||
|
// recompute an accurate value, taking care of cancellations
|
||||||
|
out.value = MathArrays.linearCombination(a1, b1.value, |
||||||
|
a2, b2.value, |
||||||
|
a3, b3.value, |
||||||
|
a4, b4.value); |
||||||
|
|
||||||
|
return out; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Test for the equality of two sparse gradients. |
||||||
|
* <p> |
||||||
|
* Sparse gradients are considered equal if they have the same value |
||||||
|
* and the same derivatives. |
||||||
|
* </p> |
||||||
|
* @param other Object to test for equality to this |
||||||
|
* @return true if two sparse gradients are equal |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public boolean equals(Object other) { |
||||||
|
|
||||||
|
if (this == other) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
if (other instanceof SparseGradient) { |
||||||
|
final SparseGradient rhs = (SparseGradient)other; |
||||||
|
if (!Precision.equals(value, rhs.value, 1)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (derivatives.size() != rhs.derivatives.size()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
for (final Map.Entry<Integer, Double> entry : derivatives.entrySet()) { |
||||||
|
if (!rhs.derivatives.containsKey(entry.getKey())) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (!Precision.equals(entry.getValue(), rhs.derivatives.get(entry.getKey()), 1)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get a hashCode for the derivative structure. |
||||||
|
* @return a hash code value for this object |
||||||
|
* @since 3.2 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
return 743 + 809 * MathUtils.hash(value) + 167 * derivatives.hashCode(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
|
||||||
|
/** Interface for univariate functions derivatives. |
||||||
|
* <p>This interface represents a simple function which computes |
||||||
|
* both the value and the first derivative of a mathematical function. |
||||||
|
* The derivative is computed with respect to the input variable.</p> |
||||||
|
* @see UnivariateDifferentiableFunction |
||||||
|
* @see UnivariateFunctionDifferentiator |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface UnivariateDifferentiableFunction extends UnivariateFunction { |
||||||
|
|
||||||
|
/** Simple mathematical function. |
||||||
|
* <p>{@link UnivariateDifferentiableFunction} classes compute both the |
||||||
|
* value and the first derivative of the function.</p> |
||||||
|
* @param t function input value |
||||||
|
* @return function result |
||||||
|
* @exception DimensionMismatchException if t is inconsistent with the |
||||||
|
* function's free parameters or order |
||||||
|
*/ |
||||||
|
DerivativeStructure value(DerivativeStructure t) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
} |
@ -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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateMatrixFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link UnivariateMatrixFunction} representing a univariate differentiable matrix function. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface UnivariateDifferentiableMatrixFunction |
||||||
|
extends UnivariateMatrixFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function. |
||||||
|
* @param x the point for which the function value should be computed |
||||||
|
* @return the value |
||||||
|
* @exception MathIllegalArgumentException if {@code x} does not |
||||||
|
* satisfy the function's constraints (argument out of bound, or unsupported |
||||||
|
* derivative order for example) |
||||||
|
*/ |
||||||
|
DerivativeStructure[][] value(DerivativeStructure x) throws MathIllegalArgumentException; |
||||||
|
|
||||||
|
} |
@ -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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateVectorFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of {@link UnivariateVectorFunction} representing a univariate differentiable vectorial function. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface UnivariateDifferentiableVectorFunction |
||||||
|
extends UnivariateVectorFunction { |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value for the function. |
||||||
|
* @param x the point for which the function value should be computed |
||||||
|
* @return the value |
||||||
|
* @exception MathIllegalArgumentException if {@code x} does not |
||||||
|
* satisfy the function's constraints (argument out of bound, or unsupported |
||||||
|
* derivative order for example) |
||||||
|
*/ |
||||||
|
DerivativeStructure[] value(DerivativeStructure x) throws MathIllegalArgumentException; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
|
||||||
|
/** Interface defining the function differentiation operation. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface UnivariateFunctionDifferentiator { |
||||||
|
|
||||||
|
/** Create an implementation of a {@link UnivariateDifferentiableFunction |
||||||
|
* differential} from a regular {@link UnivariateFunction function}. |
||||||
|
* @param function function to differentiate |
||||||
|
* @return differential function |
||||||
|
*/ |
||||||
|
UnivariateDifferentiableFunction differentiate(UnivariateFunction function); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateMatrixFunction; |
||||||
|
|
||||||
|
/** Interface defining the function differentiation operation. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface UnivariateMatrixFunctionDifferentiator { |
||||||
|
|
||||||
|
/** Create an implementation of a {@link UnivariateDifferentiableMatrixFunction |
||||||
|
* differential} from a regular {@link UnivariateMatrixFunction matrix function}. |
||||||
|
* @param function function to differentiate |
||||||
|
* @return differential function |
||||||
|
*/ |
||||||
|
UnivariateDifferentiableMatrixFunction differentiate(UnivariateMatrixFunction function); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.differentiation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateVectorFunction; |
||||||
|
|
||||||
|
/** Interface defining the function differentiation operation. |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface UnivariateVectorFunctionDifferentiator { |
||||||
|
|
||||||
|
/** Create an implementation of a {@link UnivariateDifferentiableVectorFunction |
||||||
|
* differential} from a regular {@link UnivariateVectorFunction vector function}. |
||||||
|
* @param function function to differentiate |
||||||
|
* @return differential function |
||||||
|
*/ |
||||||
|
UnivariateDifferentiableVectorFunction differentiate(UnivariateVectorFunction function); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
/** |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* This package holds the main interfaces and basic building block classes |
||||||
|
* dealing with differentiation. |
||||||
|
* The core class is {@link com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure |
||||||
|
* DerivativeStructure} which holds the value and the differentials of a function. This class
|
||||||
|
* handles some arbitrary number of free parameters and arbitrary differentiation order. It is used |
||||||
|
* both as the input and the output type for the {@link |
||||||
|
* com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction |
||||||
|
* UnivariateDifferentiableFunction} interface. Any differentiable function should implement this |
||||||
|
* interface. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* The {@link com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateFunctionDifferentiator |
||||||
|
* UnivariateFunctionDifferentiator} interface defines a way to differentiate a simple {@link |
||||||
|
* com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction UnivariateFunction} and get a {@link |
||||||
|
* com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction |
||||||
|
* UnivariateDifferentiableFunction}. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* Similar interfaces also exist for multivariate functions and for vector or matrix valued functions. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.fr.third.org.apache.commons.math3.analysis.differentiation; |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Absolute value function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Abs implements UnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.abs(x); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Arc-cosine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Acos implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.acos(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.acos(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Hyperbolic arc-cosine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Acosh implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.acosh(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.acosh(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Add the two operands. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Add implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return x + y; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Arc-sine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Asin implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.asin(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.asin(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Hyperbolic arc-sine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Asinh implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.asinh(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.asinh(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Arc-tangent function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Atan implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.atan(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.atan(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Arc-tangent function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Atan2 implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return FastMath.atan2(x, y); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Hyperbolic arc-tangent function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Atanh implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.atanh(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.atanh(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Cube root function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Cbrt implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.cbrt(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.cbrt(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@code ceil} function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Ceil implements UnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.ceil(x); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constant function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Constant implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** Constant. */ |
||||||
|
private final double c; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param c Constant. |
||||||
|
*/ |
||||||
|
public Constant(double c) { |
||||||
|
this.c = c; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public DifferentiableUnivariateFunction derivative() { |
||||||
|
return new Constant(0); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return new DerivativeStructure(t.getFreeParameters(), t.getOrder(), c); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Cosine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Cos implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.cos(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.cos(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Hyperbolic cosine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Cosh implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.cosh(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public DifferentiableUnivariateFunction derivative() { |
||||||
|
return new Sinh(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.cosh(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Divide the first operand by the second. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Divide implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return x / y; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Exponential function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Exp implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.exp(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.exp(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>e<sup>x</sup>-1</code> function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Expm1 implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.expm1(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.expm1(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@code floor} function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Floor implements UnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.floor(x); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,259 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.ParametricUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Precision; |
||||||
|
|
||||||
|
/** |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Gaussian_function"> |
||||||
|
* Gaussian</a> function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Gaussian implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** Mean. */ |
||||||
|
private final double mean; |
||||||
|
/** Inverse of the standard deviation. */ |
||||||
|
private final double is; |
||||||
|
/** Inverse of twice the square of the standard deviation. */ |
||||||
|
private final double i2s2; |
||||||
|
/** Normalization factor. */ |
||||||
|
private final double norm; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gaussian with given normalization factor, mean and standard deviation. |
||||||
|
* |
||||||
|
* @param norm Normalization factor. |
||||||
|
* @param mean Mean. |
||||||
|
* @param sigma Standard deviation. |
||||||
|
* @throws NotStrictlyPositiveException if {@code sigma <= 0}. |
||||||
|
*/ |
||||||
|
public Gaussian(double norm, |
||||||
|
double mean, |
||||||
|
double sigma) |
||||||
|
throws NotStrictlyPositiveException { |
||||||
|
if (sigma <= 0) { |
||||||
|
throw new NotStrictlyPositiveException(sigma); |
||||||
|
} |
||||||
|
|
||||||
|
this.norm = norm; |
||||||
|
this.mean = mean; |
||||||
|
this.is = 1 / sigma; |
||||||
|
this.i2s2 = 0.5 * is * is; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Normalized gaussian with given mean and standard deviation. |
||||||
|
* |
||||||
|
* @param mean Mean. |
||||||
|
* @param sigma Standard deviation. |
||||||
|
* @throws NotStrictlyPositiveException if {@code sigma <= 0}. |
||||||
|
*/ |
||||||
|
public Gaussian(double mean, |
||||||
|
double sigma) |
||||||
|
throws NotStrictlyPositiveException { |
||||||
|
this(1 / (sigma * FastMath.sqrt(2 * Math.PI)), mean, sigma); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Normalized gaussian with zero mean and unit standard deviation. |
||||||
|
*/ |
||||||
|
public Gaussian() { |
||||||
|
this(0, 1); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return value(x - mean, norm, i2s2); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Parametric function where the input array contains the parameters of |
||||||
|
* the Gaussian, ordered as follows: |
||||||
|
* <ul> |
||||||
|
* <li>Norm</li> |
||||||
|
* <li>Mean</li> |
||||||
|
* <li>Standard deviation</li> |
||||||
|
* </ul> |
||||||
|
*/ |
||||||
|
public static class Parametric implements ParametricUnivariateFunction { |
||||||
|
/** |
||||||
|
* Computes the value of the Gaussian at {@code x}. |
||||||
|
* |
||||||
|
* @param x Value for which the function must be computed. |
||||||
|
* @param param Values of norm, mean and standard deviation. |
||||||
|
* @return the value of the function. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 3. |
||||||
|
* @throws NotStrictlyPositiveException if {@code param[2]} is negative. |
||||||
|
*/ |
||||||
|
public double value(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException, |
||||||
|
NotStrictlyPositiveException { |
||||||
|
validateParameters(param); |
||||||
|
|
||||||
|
final double diff = x - param[1]; |
||||||
|
final double i2s2 = 1 / (2 * param[2] * param[2]); |
||||||
|
return Gaussian.value(diff, param[0], i2s2); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes the value of the gradient at {@code x}. |
||||||
|
* The components of the gradient vector are the partial |
||||||
|
* derivatives of the function with respect to each of the |
||||||
|
* <em>parameters</em> (norm, mean and standard deviation). |
||||||
|
* |
||||||
|
* @param x Value at which the gradient must be computed. |
||||||
|
* @param param Values of norm, mean and standard deviation. |
||||||
|
* @return the gradient vector at {@code x}. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 3. |
||||||
|
* @throws NotStrictlyPositiveException if {@code param[2]} is negative. |
||||||
|
*/ |
||||||
|
public double[] gradient(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException, |
||||||
|
NotStrictlyPositiveException { |
||||||
|
validateParameters(param); |
||||||
|
|
||||||
|
final double norm = param[0]; |
||||||
|
final double diff = x - param[1]; |
||||||
|
final double sigma = param[2]; |
||||||
|
final double i2s2 = 1 / (2 * sigma * sigma); |
||||||
|
|
||||||
|
final double n = Gaussian.value(diff, 1, i2s2); |
||||||
|
final double m = norm * n * 2 * i2s2 * diff; |
||||||
|
final double s = m * diff / sigma; |
||||||
|
|
||||||
|
return new double[] { n, m, s }; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validates parameters to ensure they are appropriate for the evaluation of |
||||||
|
* the {@link #value(double,double[])} and {@link #gradient(double,double[])} |
||||||
|
* methods. |
||||||
|
* |
||||||
|
* @param param Values of norm, mean and standard deviation. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 3. |
||||||
|
* @throws NotStrictlyPositiveException if {@code param[2]} is negative. |
||||||
|
*/ |
||||||
|
private void validateParameters(double[] param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException, |
||||||
|
NotStrictlyPositiveException { |
||||||
|
if (param == null) { |
||||||
|
throw new NullArgumentException(); |
||||||
|
} |
||||||
|
if (param.length != 3) { |
||||||
|
throw new DimensionMismatchException(param.length, 3); |
||||||
|
} |
||||||
|
if (param[2] <= 0) { |
||||||
|
throw new NotStrictlyPositiveException(param[2]); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param xMinusMean {@code x - mean}. |
||||||
|
* @param norm Normalization factor. |
||||||
|
* @param i2s2 Inverse of twice the square of the standard deviation. |
||||||
|
* @return the value of the Gaussian at {@code x}. |
||||||
|
*/ |
||||||
|
private static double value(double xMinusMean, |
||||||
|
double norm, |
||||||
|
double i2s2) { |
||||||
|
return norm * FastMath.exp(-xMinusMean * xMinusMean * i2s2); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws DimensionMismatchException { |
||||||
|
|
||||||
|
final double u = is * (t.getValue() - mean); |
||||||
|
double[] f = new double[t.getOrder() + 1]; |
||||||
|
|
||||||
|
// the nth order derivative of the Gaussian has the form:
|
||||||
|
// dn(g(x)/dxn = (norm / s^n) P_n(u) exp(-u^2/2) with u=(x-m)/s
|
||||||
|
// where P_n(u) is a degree n polynomial with same parity as n
|
||||||
|
// P_0(u) = 1, P_1(u) = -u, P_2(u) = u^2 - 1, P_3(u) = -u^3 + 3 u...
|
||||||
|
// the general recurrence relation for P_n is:
|
||||||
|
// P_n(u) = P_(n-1)'(u) - u P_(n-1)(u)
|
||||||
|
// as per polynomial parity, we can store coefficients of both P_(n-1) and P_n in the same array
|
||||||
|
final double[] p = new double[f.length]; |
||||||
|
p[0] = 1; |
||||||
|
final double u2 = u * u; |
||||||
|
double coeff = norm * FastMath.exp(-0.5 * u2); |
||||||
|
if (coeff <= Precision.SAFE_MIN) { |
||||||
|
Arrays.fill(f, 0.0); |
||||||
|
} else { |
||||||
|
f[0] = coeff; |
||||||
|
for (int n = 1; n < f.length; ++n) { |
||||||
|
|
||||||
|
// update and evaluate polynomial P_n(x)
|
||||||
|
double v = 0; |
||||||
|
p[n] = -p[n - 1]; |
||||||
|
for (int k = n; k >= 0; k -= 2) { |
||||||
|
v = v * u2 + p[k]; |
||||||
|
if (k > 2) { |
||||||
|
p[k - 2] = (k - 1) * p[k - 1] - p[k - 3]; |
||||||
|
} else if (k == 2) { |
||||||
|
p[0] = p[1]; |
||||||
|
} |
||||||
|
} |
||||||
|
if ((n & 0x1) == 1) { |
||||||
|
v *= u; |
||||||
|
} |
||||||
|
|
||||||
|
coeff *= is; |
||||||
|
f[n] = coeff * v; |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return t.compose(f); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,183 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.ParametricUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Harmonic_oscillator"> |
||||||
|
* simple harmonic oscillator</a> function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class HarmonicOscillator implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** Amplitude. */ |
||||||
|
private final double amplitude; |
||||||
|
/** Angular frequency. */ |
||||||
|
private final double omega; |
||||||
|
/** Phase. */ |
||||||
|
private final double phase; |
||||||
|
|
||||||
|
/** |
||||||
|
* Harmonic oscillator function. |
||||||
|
* |
||||||
|
* @param amplitude Amplitude. |
||||||
|
* @param omega Angular frequency. |
||||||
|
* @param phase Phase. |
||||||
|
*/ |
||||||
|
public HarmonicOscillator(double amplitude, |
||||||
|
double omega, |
||||||
|
double phase) { |
||||||
|
this.amplitude = amplitude; |
||||||
|
this.omega = omega; |
||||||
|
this.phase = phase; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return value(omega * x + phase, amplitude); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Parametric function where the input array contains the parameters of |
||||||
|
* the harmonic oscillator function, ordered as follows: |
||||||
|
* <ul> |
||||||
|
* <li>Amplitude</li> |
||||||
|
* <li>Angular frequency</li> |
||||||
|
* <li>Phase</li> |
||||||
|
* </ul> |
||||||
|
*/ |
||||||
|
public static class Parametric implements ParametricUnivariateFunction { |
||||||
|
/** |
||||||
|
* Computes the value of the harmonic oscillator at {@code x}. |
||||||
|
* |
||||||
|
* @param x Value for which the function must be computed. |
||||||
|
* @param param Values of norm, mean and standard deviation. |
||||||
|
* @return the value of the function. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 3. |
||||||
|
*/ |
||||||
|
public double value(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
validateParameters(param); |
||||||
|
return HarmonicOscillator.value(x * param[1] + param[2], param[0]); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes the value of the gradient at {@code x}. |
||||||
|
* The components of the gradient vector are the partial |
||||||
|
* derivatives of the function with respect to each of the |
||||||
|
* <em>parameters</em> (amplitude, angular frequency and phase). |
||||||
|
* |
||||||
|
* @param x Value at which the gradient must be computed. |
||||||
|
* @param param Values of amplitude, angular frequency and phase. |
||||||
|
* @return the gradient vector at {@code x}. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 3. |
||||||
|
*/ |
||||||
|
public double[] gradient(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
validateParameters(param); |
||||||
|
|
||||||
|
final double amplitude = param[0]; |
||||||
|
final double omega = param[1]; |
||||||
|
final double phase = param[2]; |
||||||
|
|
||||||
|
final double xTimesOmegaPlusPhase = omega * x + phase; |
||||||
|
final double a = HarmonicOscillator.value(xTimesOmegaPlusPhase, 1); |
||||||
|
final double p = -amplitude * FastMath.sin(xTimesOmegaPlusPhase); |
||||||
|
final double w = p * x; |
||||||
|
|
||||||
|
return new double[] { a, w, p }; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validates parameters to ensure they are appropriate for the evaluation of |
||||||
|
* the {@link #value(double,double[])} and {@link #gradient(double,double[])} |
||||||
|
* methods. |
||||||
|
* |
||||||
|
* @param param Values of norm, mean and standard deviation. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 3. |
||||||
|
*/ |
||||||
|
private void validateParameters(double[] param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
if (param == null) { |
||||||
|
throw new NullArgumentException(); |
||||||
|
} |
||||||
|
if (param.length != 3) { |
||||||
|
throw new DimensionMismatchException(param.length, 3); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param xTimesOmegaPlusPhase {@code omega * x + phase}. |
||||||
|
* @param amplitude Amplitude. |
||||||
|
* @return the value of the harmonic oscillator function at {@code x}. |
||||||
|
*/ |
||||||
|
private static double value(double xTimesOmegaPlusPhase, |
||||||
|
double amplitude) { |
||||||
|
return amplitude * FastMath.cos(xTimesOmegaPlusPhase); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws DimensionMismatchException { |
||||||
|
final double x = t.getValue(); |
||||||
|
double[] f = new double[t.getOrder() + 1]; |
||||||
|
|
||||||
|
final double alpha = omega * x + phase; |
||||||
|
f[0] = amplitude * FastMath.cos(alpha); |
||||||
|
if (f.length > 1) { |
||||||
|
f[1] = -amplitude * omega * FastMath.sin(alpha); |
||||||
|
final double mo2 = - omega * omega; |
||||||
|
for (int i = 2; i < f.length; ++i) { |
||||||
|
f[i] = mo2 * f[i - 2]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return t.compose(f); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Identity function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Identity implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return x; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public DifferentiableUnivariateFunction derivative() { |
||||||
|
return new Constant(1); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Inverse function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Inverse implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return 1 / x; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.reciprocal(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Natural logarithm function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Log implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.log(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.log(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Base 10 logarithm function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Log10 implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.log10(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.log10(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>log(1 + p)</code> function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Log1p implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.log1p(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.log1p(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,228 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.ParametricUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Generalised_logistic_function"> |
||||||
|
* Generalised logistic</a> function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Logistic implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** Lower asymptote. */ |
||||||
|
private final double a; |
||||||
|
/** Upper asymptote. */ |
||||||
|
private final double k; |
||||||
|
/** Growth rate. */ |
||||||
|
private final double b; |
||||||
|
/** Parameter that affects near which asymptote maximum growth occurs. */ |
||||||
|
private final double oneOverN; |
||||||
|
/** Parameter that affects the position of the curve along the ordinate axis. */ |
||||||
|
private final double q; |
||||||
|
/** Abscissa of maximum growth. */ |
||||||
|
private final double m; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param k If {@code b > 0}, value of the function for x going towards +∞. |
||||||
|
* If {@code b < 0}, value of the function for x going towards -∞. |
||||||
|
* @param m Abscissa of maximum growth. |
||||||
|
* @param b Growth rate. |
||||||
|
* @param q Parameter that affects the position of the curve along the |
||||||
|
* ordinate axis. |
||||||
|
* @param a If {@code b > 0}, value of the function for x going towards -∞. |
||||||
|
* If {@code b < 0}, value of the function for x going towards +∞. |
||||||
|
* @param n Parameter that affects near which asymptote the maximum |
||||||
|
* growth occurs. |
||||||
|
* @throws NotStrictlyPositiveException if {@code n <= 0}. |
||||||
|
*/ |
||||||
|
public Logistic(double k, |
||||||
|
double m, |
||||||
|
double b, |
||||||
|
double q, |
||||||
|
double a, |
||||||
|
double n) |
||||||
|
throws NotStrictlyPositiveException { |
||||||
|
if (n <= 0) { |
||||||
|
throw new NotStrictlyPositiveException(n); |
||||||
|
} |
||||||
|
|
||||||
|
this.k = k; |
||||||
|
this.m = m; |
||||||
|
this.b = b; |
||||||
|
this.q = q; |
||||||
|
this.a = a; |
||||||
|
oneOverN = 1 / n; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return value(m - x, k, b, q, a, oneOverN); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Parametric function where the input array contains the parameters of |
||||||
|
* the {@link Logistic#Logistic(double,double,double,double,double,double) |
||||||
|
* logistic function}, ordered as follows: |
||||||
|
* <ul> |
||||||
|
* <li>k</li> |
||||||
|
* <li>m</li> |
||||||
|
* <li>b</li> |
||||||
|
* <li>q</li> |
||||||
|
* <li>a</li> |
||||||
|
* <li>n</li> |
||||||
|
* </ul> |
||||||
|
*/ |
||||||
|
public static class Parametric implements ParametricUnivariateFunction { |
||||||
|
/** |
||||||
|
* Computes the value of the sigmoid at {@code x}. |
||||||
|
* |
||||||
|
* @param x Value for which the function must be computed. |
||||||
|
* @param param Values for {@code k}, {@code m}, {@code b}, {@code q}, |
||||||
|
* {@code a} and {@code n}. |
||||||
|
* @return the value of the function. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 6. |
||||||
|
* @throws NotStrictlyPositiveException if {@code param[5] <= 0}. |
||||||
|
*/ |
||||||
|
public double value(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException, |
||||||
|
NotStrictlyPositiveException { |
||||||
|
validateParameters(param); |
||||||
|
return Logistic.value(param[1] - x, param[0], |
||||||
|
param[2], param[3], |
||||||
|
param[4], 1 / param[5]); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes the value of the gradient at {@code x}. |
||||||
|
* The components of the gradient vector are the partial |
||||||
|
* derivatives of the function with respect to each of the |
||||||
|
* <em>parameters</em>. |
||||||
|
* |
||||||
|
* @param x Value at which the gradient must be computed. |
||||||
|
* @param param Values for {@code k}, {@code m}, {@code b}, {@code q}, |
||||||
|
* {@code a} and {@code n}. |
||||||
|
* @return the gradient vector at {@code x}. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 6. |
||||||
|
* @throws NotStrictlyPositiveException if {@code param[5] <= 0}. |
||||||
|
*/ |
||||||
|
public double[] gradient(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException, |
||||||
|
NotStrictlyPositiveException { |
||||||
|
validateParameters(param); |
||||||
|
|
||||||
|
final double b = param[2]; |
||||||
|
final double q = param[3]; |
||||||
|
|
||||||
|
final double mMinusX = param[1] - x; |
||||||
|
final double oneOverN = 1 / param[5]; |
||||||
|
final double exp = FastMath.exp(b * mMinusX); |
||||||
|
final double qExp = q * exp; |
||||||
|
final double qExp1 = qExp + 1; |
||||||
|
final double factor1 = (param[0] - param[4]) * oneOverN / FastMath.pow(qExp1, oneOverN); |
||||||
|
final double factor2 = -factor1 / qExp1; |
||||||
|
|
||||||
|
// Components of the gradient.
|
||||||
|
final double gk = Logistic.value(mMinusX, 1, b, q, 0, oneOverN); |
||||||
|
final double gm = factor2 * b * qExp; |
||||||
|
final double gb = factor2 * mMinusX * qExp; |
||||||
|
final double gq = factor2 * exp; |
||||||
|
final double ga = Logistic.value(mMinusX, 0, b, q, 1, oneOverN); |
||||||
|
final double gn = factor1 * FastMath.log(qExp1) * oneOverN; |
||||||
|
|
||||||
|
return new double[] { gk, gm, gb, gq, ga, gn }; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validates parameters to ensure they are appropriate for the evaluation of |
||||||
|
* the {@link #value(double,double[])} and {@link #gradient(double,double[])} |
||||||
|
* methods. |
||||||
|
* |
||||||
|
* @param param Values for {@code k}, {@code m}, {@code b}, {@code q}, |
||||||
|
* {@code a} and {@code n}. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 6. |
||||||
|
* @throws NotStrictlyPositiveException if {@code param[5] <= 0}. |
||||||
|
*/ |
||||||
|
private void validateParameters(double[] param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException, |
||||||
|
NotStrictlyPositiveException { |
||||||
|
if (param == null) { |
||||||
|
throw new NullArgumentException(); |
||||||
|
} |
||||||
|
if (param.length != 6) { |
||||||
|
throw new DimensionMismatchException(param.length, 6); |
||||||
|
} |
||||||
|
if (param[5] <= 0) { |
||||||
|
throw new NotStrictlyPositiveException(param[5]); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param mMinusX {@code m - x}. |
||||||
|
* @param k {@code k}. |
||||||
|
* @param b {@code b}. |
||||||
|
* @param q {@code q}. |
||||||
|
* @param a {@code a}. |
||||||
|
* @param oneOverN {@code 1 / n}. |
||||||
|
* @return the value of the function. |
||||||
|
*/ |
||||||
|
private static double value(double mMinusX, |
||||||
|
double k, |
||||||
|
double b, |
||||||
|
double q, |
||||||
|
double a, |
||||||
|
double oneOverN) { |
||||||
|
return a + (k - a) / FastMath.pow(1 + q * FastMath.exp(b * mMinusX), oneOverN); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.negate().add(m).multiply(b).exp().multiply(q).add(1).pow(oneOverN).reciprocal().multiply(k - a).add(a); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,212 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.OutOfRangeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.ParametricUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Logit"> |
||||||
|
* Logit</a> function. |
||||||
|
* It is the inverse of the {@link Sigmoid sigmoid} function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Logit implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** Lower bound. */ |
||||||
|
private final double lo; |
||||||
|
/** Higher bound. */ |
||||||
|
private final double hi; |
||||||
|
|
||||||
|
/** |
||||||
|
* Usual logit function, where the lower bound is 0 and the higher |
||||||
|
* bound is 1. |
||||||
|
*/ |
||||||
|
public Logit() { |
||||||
|
this(0, 1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Logit function. |
||||||
|
* |
||||||
|
* @param lo Lower bound of the function domain. |
||||||
|
* @param hi Higher bound of the function domain. |
||||||
|
*/ |
||||||
|
public Logit(double lo, |
||||||
|
double hi) { |
||||||
|
this.lo = lo; |
||||||
|
this.hi = hi; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) |
||||||
|
throws OutOfRangeException { |
||||||
|
return value(x, lo, hi); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Parametric function where the input array contains the parameters of |
||||||
|
* the logit function, ordered as follows: |
||||||
|
* <ul> |
||||||
|
* <li>Lower bound</li> |
||||||
|
* <li>Higher bound</li> |
||||||
|
* </ul> |
||||||
|
*/ |
||||||
|
public static class Parametric implements ParametricUnivariateFunction { |
||||||
|
/** |
||||||
|
* Computes the value of the logit at {@code x}. |
||||||
|
* |
||||||
|
* @param x Value for which the function must be computed. |
||||||
|
* @param param Values of lower bound and higher bounds. |
||||||
|
* @return the value of the function. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 2. |
||||||
|
*/ |
||||||
|
public double value(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
validateParameters(param); |
||||||
|
return Logit.value(x, param[0], param[1]); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes the value of the gradient at {@code x}. |
||||||
|
* The components of the gradient vector are the partial |
||||||
|
* derivatives of the function with respect to each of the |
||||||
|
* <em>parameters</em> (lower bound and higher bound). |
||||||
|
* |
||||||
|
* @param x Value at which the gradient must be computed. |
||||||
|
* @param param Values for lower and higher bounds. |
||||||
|
* @return the gradient vector at {@code x}. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 2. |
||||||
|
*/ |
||||||
|
public double[] gradient(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
validateParameters(param); |
||||||
|
|
||||||
|
final double lo = param[0]; |
||||||
|
final double hi = param[1]; |
||||||
|
|
||||||
|
return new double[] { 1 / (lo - x), 1 / (hi - x) }; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validates parameters to ensure they are appropriate for the evaluation of |
||||||
|
* the {@link #value(double,double[])} and {@link #gradient(double,double[])} |
||||||
|
* methods. |
||||||
|
* |
||||||
|
* @param param Values for lower and higher bounds. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 2. |
||||||
|
*/ |
||||||
|
private void validateParameters(double[] param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
if (param == null) { |
||||||
|
throw new NullArgumentException(); |
||||||
|
} |
||||||
|
if (param.length != 2) { |
||||||
|
throw new DimensionMismatchException(param.length, 2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param x Value at which to compute the logit. |
||||||
|
* @param lo Lower bound. |
||||||
|
* @param hi Higher bound. |
||||||
|
* @return the value of the logit function at {@code x}. |
||||||
|
* @throws OutOfRangeException if {@code x < lo} or {@code x > hi}. |
||||||
|
*/ |
||||||
|
private static double value(double x, |
||||||
|
double lo, |
||||||
|
double hi) |
||||||
|
throws OutOfRangeException { |
||||||
|
if (x < lo || x > hi) { |
||||||
|
throw new OutOfRangeException(x, lo, hi); |
||||||
|
} |
||||||
|
return FastMath.log((x - lo) / (hi - x)); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
* @exception OutOfRangeException if parameter is outside of function domain |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws OutOfRangeException { |
||||||
|
final double x = t.getValue(); |
||||||
|
if (x < lo || x > hi) { |
||||||
|
throw new OutOfRangeException(x, lo, hi); |
||||||
|
} |
||||||
|
double[] f = new double[t.getOrder() + 1]; |
||||||
|
|
||||||
|
// function value
|
||||||
|
f[0] = FastMath.log((x - lo) / (hi - x)); |
||||||
|
|
||||||
|
if (Double.isInfinite(f[0])) { |
||||||
|
|
||||||
|
if (f.length > 1) { |
||||||
|
f[1] = Double.POSITIVE_INFINITY; |
||||||
|
} |
||||||
|
// fill the array with infinities
|
||||||
|
// (for x close to lo the signs will flip between -inf and +inf,
|
||||||
|
// for x close to hi the signs will always be +inf)
|
||||||
|
// this is probably overkill, since the call to compose at the end
|
||||||
|
// of the method will transform most infinities into NaN ...
|
||||||
|
for (int i = 2; i < f.length; ++i) { |
||||||
|
f[i] = f[i - 2]; |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// function derivatives
|
||||||
|
final double invL = 1.0 / (x - lo); |
||||||
|
double xL = invL; |
||||||
|
final double invH = 1.0 / (hi - x); |
||||||
|
double xH = invH; |
||||||
|
for (int i = 1; i < f.length; ++i) { |
||||||
|
f[i] = xL + xH; |
||||||
|
xL *= -i * invL; |
||||||
|
xH *= i * invH; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return t.compose(f); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Maximum function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Max implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return FastMath.max(x, y); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Minimum function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Min implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return FastMath.min(x, y); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Minus function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Minus implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return -x; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public DifferentiableUnivariateFunction derivative() { |
||||||
|
return new Constant(-1); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.negate(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiply the two operands. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Multiply implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return x * y; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Power function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Pow implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return FastMath.pow(x, y); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Power function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Power implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** Power. */ |
||||||
|
private final double p; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param p Power. |
||||||
|
*/ |
||||||
|
public Power(double p) { |
||||||
|
this.p = p; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.pow(x, p); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.pow(p); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@code rint} function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Rint implements UnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.rint(x); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,218 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.ParametricUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Sigmoid_function"> |
||||||
|
* Sigmoid</a> function. |
||||||
|
* It is the inverse of the {@link Logit logit} function. |
||||||
|
* A more flexible version, the generalised logistic, is implemented |
||||||
|
* by the {@link Logistic} class. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Sigmoid implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** Lower asymptote. */ |
||||||
|
private final double lo; |
||||||
|
/** Higher asymptote. */ |
||||||
|
private final double hi; |
||||||
|
|
||||||
|
/** |
||||||
|
* Usual sigmoid function, where the lower asymptote is 0 and the higher |
||||||
|
* asymptote is 1. |
||||||
|
*/ |
||||||
|
public Sigmoid() { |
||||||
|
this(0, 1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sigmoid function. |
||||||
|
* |
||||||
|
* @param lo Lower asymptote. |
||||||
|
* @param hi Higher asymptote. |
||||||
|
*/ |
||||||
|
public Sigmoid(double lo, |
||||||
|
double hi) { |
||||||
|
this.lo = lo; |
||||||
|
this.hi = hi; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return value(x, lo, hi); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Parametric function where the input array contains the parameters of |
||||||
|
* the {@link Sigmoid#Sigmoid(double,double) sigmoid function}, ordered |
||||||
|
* as follows: |
||||||
|
* <ul> |
||||||
|
* <li>Lower asymptote</li> |
||||||
|
* <li>Higher asymptote</li> |
||||||
|
* </ul> |
||||||
|
*/ |
||||||
|
public static class Parametric implements ParametricUnivariateFunction { |
||||||
|
/** |
||||||
|
* Computes the value of the sigmoid at {@code x}. |
||||||
|
* |
||||||
|
* @param x Value for which the function must be computed. |
||||||
|
* @param param Values of lower asymptote and higher asymptote. |
||||||
|
* @return the value of the function. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 2. |
||||||
|
*/ |
||||||
|
public double value(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
validateParameters(param); |
||||||
|
return Sigmoid.value(x, param[0], param[1]); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes the value of the gradient at {@code x}. |
||||||
|
* The components of the gradient vector are the partial |
||||||
|
* derivatives of the function with respect to each of the |
||||||
|
* <em>parameters</em> (lower asymptote and higher asymptote). |
||||||
|
* |
||||||
|
* @param x Value at which the gradient must be computed. |
||||||
|
* @param param Values for lower asymptote and higher asymptote. |
||||||
|
* @return the gradient vector at {@code x}. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 2. |
||||||
|
*/ |
||||||
|
public double[] gradient(double x, double ... param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
validateParameters(param); |
||||||
|
|
||||||
|
final double invExp1 = 1 / (1 + FastMath.exp(-x)); |
||||||
|
|
||||||
|
return new double[] { 1 - invExp1, invExp1 }; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validates parameters to ensure they are appropriate for the evaluation of |
||||||
|
* the {@link #value(double,double[])} and {@link #gradient(double,double[])} |
||||||
|
* methods. |
||||||
|
* |
||||||
|
* @param param Values for lower and higher asymptotes. |
||||||
|
* @throws NullArgumentException if {@code param} is {@code null}. |
||||||
|
* @throws DimensionMismatchException if the size of {@code param} is |
||||||
|
* not 2. |
||||||
|
*/ |
||||||
|
private void validateParameters(double[] param) |
||||||
|
throws NullArgumentException, |
||||||
|
DimensionMismatchException { |
||||||
|
if (param == null) { |
||||||
|
throw new NullArgumentException(); |
||||||
|
} |
||||||
|
if (param.length != 2) { |
||||||
|
throw new DimensionMismatchException(param.length, 2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param x Value at which to compute the sigmoid. |
||||||
|
* @param lo Lower asymptote. |
||||||
|
* @param hi Higher asymptote. |
||||||
|
* @return the value of the sigmoid function at {@code x}. |
||||||
|
*/ |
||||||
|
private static double value(double x, |
||||||
|
double lo, |
||||||
|
double hi) { |
||||||
|
return lo + (hi - lo) / (1 + FastMath.exp(-x)); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws DimensionMismatchException { |
||||||
|
|
||||||
|
double[] f = new double[t.getOrder() + 1]; |
||||||
|
final double exp = FastMath.exp(-t.getValue()); |
||||||
|
if (Double.isInfinite(exp)) { |
||||||
|
|
||||||
|
// special handling near lower boundary, to avoid NaN
|
||||||
|
f[0] = lo; |
||||||
|
Arrays.fill(f, 1, f.length, 0.0); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// the nth order derivative of sigmoid has the form:
|
||||||
|
// dn(sigmoid(x)/dxn = P_n(exp(-x)) / (1+exp(-x))^(n+1)
|
||||||
|
// where P_n(t) is a degree n polynomial with normalized higher term
|
||||||
|
// P_0(t) = 1, P_1(t) = t, P_2(t) = t^2 - t, P_3(t) = t^3 - 4 t^2 + t...
|
||||||
|
// the general recurrence relation for P_n is:
|
||||||
|
// P_n(x) = n t P_(n-1)(t) - t (1 + t) P_(n-1)'(t)
|
||||||
|
final double[] p = new double[f.length]; |
||||||
|
|
||||||
|
final double inv = 1 / (1 + exp); |
||||||
|
double coeff = hi - lo; |
||||||
|
for (int n = 0; n < f.length; ++n) { |
||||||
|
|
||||||
|
// update and evaluate polynomial P_n(t)
|
||||||
|
double v = 0; |
||||||
|
p[n] = 1; |
||||||
|
for (int k = n; k >= 0; --k) { |
||||||
|
v = v * exp + p[k]; |
||||||
|
if (k > 1) { |
||||||
|
p[k - 1] = (n - k + 2) * p[k - 2] - (k - 1) * p[k - 1]; |
||||||
|
} else { |
||||||
|
p[0] = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
coeff *= inv; |
||||||
|
f[n] = coeff * v; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// fix function value
|
||||||
|
f[0] += lo; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return t.compose(f); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@code signum} function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Signum implements UnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.signum(x); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Sine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Sin implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.sin(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public DifferentiableUnivariateFunction derivative() { |
||||||
|
return new Cos(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.sin(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,205 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Sinc_function">Sinc</a> function, |
||||||
|
* defined by |
||||||
|
* <pre><code> |
||||||
|
* sinc(x) = 1 if x = 0, |
||||||
|
* sin(x) / x otherwise. |
||||||
|
* </code></pre> |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Sinc implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** |
||||||
|
* Value below which the computations are done using Taylor series. |
||||||
|
* <p> |
||||||
|
* The Taylor series for sinc even order derivatives are: |
||||||
|
* <pre> |
||||||
|
* d^(2n)sinc/dx^(2n) = Sum_(k>=0) (-1)^(n+k) / ((2k)!(2n+2k+1)) x^(2k) |
||||||
|
* = (-1)^n [ 1/(2n+1) - x^2/(4n+6) + x^4/(48n+120) - x^6/(1440n+5040) + O(x^8) ] |
||||||
|
* </pre> |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* The Taylor series for sinc odd order derivatives are: |
||||||
|
* <pre> |
||||||
|
* d^(2n+1)sinc/dx^(2n+1) = Sum_(k>=0) (-1)^(n+k+1) / ((2k+1)!(2n+2k+3)) x^(2k+1) |
||||||
|
* = (-1)^(n+1) [ x/(2n+3) - x^3/(12n+30) + x^5/(240n+840) - x^7/(10080n+45360) + O(x^9) ] |
||||||
|
* </pre> |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* So the ratio of the fourth term with respect to the first term |
||||||
|
* is always smaller than x^6/720, for all derivative orders. |
||||||
|
* This implies that neglecting this term and using only the first three terms induces |
||||||
|
* a relative error bounded by x^6/720. The SHORTCUT value is chosen such that this |
||||||
|
* relative error is below double precision accuracy when |x| <= SHORTCUT. |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
private static final double SHORTCUT = 6.0e-3; |
||||||
|
/** For normalized sinc function. */ |
||||||
|
private final boolean normalized; |
||||||
|
|
||||||
|
/** |
||||||
|
* The sinc function, {@code sin(x) / x}. |
||||||
|
*/ |
||||||
|
public Sinc() { |
||||||
|
this(false); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Instantiates the sinc function. |
||||||
|
* |
||||||
|
* @param normalized If {@code true}, the function is |
||||||
|
* <code> sin(πx) / πx</code>, otherwise {@code sin(x) / x}. |
||||||
|
*/ |
||||||
|
public Sinc(boolean normalized) { |
||||||
|
this.normalized = normalized; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(final double x) { |
||||||
|
final double scaledX = normalized ? FastMath.PI * x : x; |
||||||
|
if (FastMath.abs(scaledX) <= SHORTCUT) { |
||||||
|
// use Taylor series
|
||||||
|
final double scaledX2 = scaledX * scaledX; |
||||||
|
return ((scaledX2 - 20) * scaledX2 + 120) / 120; |
||||||
|
} else { |
||||||
|
// use definition expression
|
||||||
|
return FastMath.sin(scaledX) / scaledX; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) |
||||||
|
throws DimensionMismatchException { |
||||||
|
|
||||||
|
final double scaledX = (normalized ? FastMath.PI : 1) * t.getValue(); |
||||||
|
final double scaledX2 = scaledX * scaledX; |
||||||
|
|
||||||
|
double[] f = new double[t.getOrder() + 1]; |
||||||
|
|
||||||
|
if (FastMath.abs(scaledX) <= SHORTCUT) { |
||||||
|
|
||||||
|
for (int i = 0; i < f.length; ++i) { |
||||||
|
final int k = i / 2; |
||||||
|
if ((i & 0x1) == 0) { |
||||||
|
// even derivation order
|
||||||
|
f[i] = (((k & 0x1) == 0) ? 1 : -1) * |
||||||
|
(1.0 / (i + 1) - scaledX2 * (1.0 / (2 * i + 6) - scaledX2 / (24 * i + 120))); |
||||||
|
} else { |
||||||
|
// odd derivation order
|
||||||
|
f[i] = (((k & 0x1) == 0) ? -scaledX : scaledX) * |
||||||
|
(1.0 / (i + 2) - scaledX2 * (1.0 / (6 * i + 24) - scaledX2 / (120 * i + 720))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
final double inv = 1 / scaledX; |
||||||
|
final double cos = FastMath.cos(scaledX); |
||||||
|
final double sin = FastMath.sin(scaledX); |
||||||
|
|
||||||
|
f[0] = inv * sin; |
||||||
|
|
||||||
|
// the nth order derivative of sinc has the form:
|
||||||
|
// dn(sinc(x)/dxn = [S_n(x) sin(x) + C_n(x) cos(x)] / x^(n+1)
|
||||||
|
// where S_n(x) is an even polynomial with degree n-1 or n (depending on parity)
|
||||||
|
// and C_n(x) is an odd polynomial with degree n-1 or n (depending on parity)
|
||||||
|
// S_0(x) = 1, S_1(x) = -1, S_2(x) = -x^2 + 2, S_3(x) = 3x^2 - 6...
|
||||||
|
// C_0(x) = 0, C_1(x) = x, C_2(x) = -2x, C_3(x) = -x^3 + 6x...
|
||||||
|
// the general recurrence relations for S_n and C_n are:
|
||||||
|
// S_n(x) = x S_(n-1)'(x) - n S_(n-1)(x) - x C_(n-1)(x)
|
||||||
|
// C_n(x) = x C_(n-1)'(x) - n C_(n-1)(x) + x S_(n-1)(x)
|
||||||
|
// as per polynomials parity, we can store both S_n and C_n in the same array
|
||||||
|
final double[] sc = new double[f.length]; |
||||||
|
sc[0] = 1; |
||||||
|
|
||||||
|
double coeff = inv; |
||||||
|
for (int n = 1; n < f.length; ++n) { |
||||||
|
|
||||||
|
double s = 0; |
||||||
|
double c = 0; |
||||||
|
|
||||||
|
// update and evaluate polynomials S_n(x) and C_n(x)
|
||||||
|
final int kStart; |
||||||
|
if ((n & 0x1) == 0) { |
||||||
|
// even derivation order, S_n is degree n and C_n is degree n-1
|
||||||
|
sc[n] = 0; |
||||||
|
kStart = n; |
||||||
|
} else { |
||||||
|
// odd derivation order, S_n is degree n-1 and C_n is degree n
|
||||||
|
sc[n] = sc[n - 1]; |
||||||
|
c = sc[n]; |
||||||
|
kStart = n - 1; |
||||||
|
} |
||||||
|
|
||||||
|
// in this loop, k is always even
|
||||||
|
for (int k = kStart; k > 1; k -= 2) { |
||||||
|
|
||||||
|
// sine part
|
||||||
|
sc[k] = (k - n) * sc[k] - sc[k - 1]; |
||||||
|
s = s * scaledX2 + sc[k]; |
||||||
|
|
||||||
|
// cosine part
|
||||||
|
sc[k - 1] = (k - 1 - n) * sc[k - 1] + sc[k -2]; |
||||||
|
c = c * scaledX2 + sc[k - 1]; |
||||||
|
|
||||||
|
} |
||||||
|
sc[0] *= -n; |
||||||
|
s = s * scaledX2 + sc[0]; |
||||||
|
|
||||||
|
coeff *= inv; |
||||||
|
f[n] = coeff * (s * sin + c * scaledX * cos); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if (normalized) { |
||||||
|
double scale = FastMath.PI; |
||||||
|
for (int i = 1; i < f.length; ++i) { |
||||||
|
f[i] *= scale; |
||||||
|
scale *= FastMath.PI; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return t.compose(f); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Hyperbolic sine function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Sinh implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.sinh(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public DifferentiableUnivariateFunction derivative() { |
||||||
|
return new Cosh(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.sinh(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Square-root function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Sqrt implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.sqrt(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.sqrt(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,101 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NoDataException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NonMonotonicSequenceException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.MathArrays; |
||||||
|
|
||||||
|
/** |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Step_function"> |
||||||
|
* Step function</a>. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class StepFunction implements UnivariateFunction { |
||||||
|
/** Abscissae. */ |
||||||
|
private final double[] abscissa; |
||||||
|
/** Ordinates. */ |
||||||
|
private final double[] ordinate; |
||||||
|
|
||||||
|
/** |
||||||
|
* Builds a step function from a list of arguments and the corresponding |
||||||
|
* values. Specifically, returns the function h(x) defined by <pre><code> |
||||||
|
* h(x) = y[0] for all x < x[1] |
||||||
|
* y[1] for x[1] ≤ x < x[2] |
||||||
|
* ... |
||||||
|
* y[y.length - 1] for x ≥ x[x.length - 1] |
||||||
|
* </code></pre> |
||||||
|
* The value of {@code x[0]} is ignored, but it must be strictly less than |
||||||
|
* {@code x[1]}. |
||||||
|
* |
||||||
|
* @param x Domain values where the function changes value. |
||||||
|
* @param y Values of the function. |
||||||
|
* @throws NonMonotonicSequenceException |
||||||
|
* if the {@code x} array is not sorted in strictly increasing order. |
||||||
|
* @throws NullArgumentException if {@code x} or {@code y} are {@code null}. |
||||||
|
* @throws NoDataException if {@code x} or {@code y} are zero-length. |
||||||
|
* @throws DimensionMismatchException if {@code x} and {@code y} do not |
||||||
|
* have the same length. |
||||||
|
*/ |
||||||
|
public StepFunction(double[] x, |
||||||
|
double[] y) |
||||||
|
throws NullArgumentException, NoDataException, |
||||||
|
DimensionMismatchException, NonMonotonicSequenceException { |
||||||
|
if (x == null || |
||||||
|
y == null) { |
||||||
|
throw new NullArgumentException(); |
||||||
|
} |
||||||
|
if (x.length == 0 || |
||||||
|
y.length == 0) { |
||||||
|
throw new NoDataException(); |
||||||
|
} |
||||||
|
if (y.length != x.length) { |
||||||
|
throw new DimensionMismatchException(y.length, x.length); |
||||||
|
} |
||||||
|
MathArrays.checkOrder(x); |
||||||
|
|
||||||
|
abscissa = MathArrays.copyOf(x); |
||||||
|
ordinate = MathArrays.copyOf(y); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
int index = Arrays.binarySearch(abscissa, x); |
||||||
|
double fx = 0; |
||||||
|
|
||||||
|
if (index < -1) { |
||||||
|
// "x" is between "abscissa[-index-2]" and "abscissa[-index-1]".
|
||||||
|
fx = ordinate[-index-2]; |
||||||
|
} else if (index >= 0) { |
||||||
|
// "x" is exactly "abscissa[index]".
|
||||||
|
fx = ordinate[index]; |
||||||
|
} else { |
||||||
|
// Otherwise, "x" is smaller than the first value in "abscissa"
|
||||||
|
// (hence the returned value should be "ordinate[0]").
|
||||||
|
fx = ordinate[0]; |
||||||
|
} |
||||||
|
|
||||||
|
return fx; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Subtract the second operand from the first. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Subtract implements BivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x, double y) { |
||||||
|
return x - y; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Tangent function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Tan implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.tan(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.tan(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.DerivativeStructure; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.FunctionUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.DifferentiableUnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Hyperbolic tangent function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Tanh implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.tanh(x); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public UnivariateFunction derivative() { |
||||||
|
return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public DerivativeStructure value(final DerivativeStructure t) { |
||||||
|
return t.tanh(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.function; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@code ulp} function. |
||||||
|
* |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class Ulp implements UnivariateFunction { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) { |
||||||
|
return FastMath.ulp(x); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
/** |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* The {@code function} package contains function objects that wrap the |
||||||
|
* methods contained in {@link java.lang.Math}, as well as common |
||||||
|
* mathematical functions such as the gaussian and sinc functions. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.fr.third.org.apache.commons.math3.analysis.function; |
@ -0,0 +1,299 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.solvers.UnivariateSolverUtils; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Incrementor; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.IntegerSequence; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Precision; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.MathUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provide a default implementation for several generic functions. |
||||||
|
* |
||||||
|
* @since 1.2 |
||||||
|
*/ |
||||||
|
public abstract class BaseAbstractUnivariateIntegrator implements UnivariateIntegrator { |
||||||
|
|
||||||
|
/** Default absolute accuracy. */ |
||||||
|
public static final double DEFAULT_ABSOLUTE_ACCURACY = 1.0e-15; |
||||||
|
|
||||||
|
/** Default relative accuracy. */ |
||||||
|
public static final double DEFAULT_RELATIVE_ACCURACY = 1.0e-6; |
||||||
|
|
||||||
|
/** Default minimal iteration count. */ |
||||||
|
public static final int DEFAULT_MIN_ITERATIONS_COUNT = 3; |
||||||
|
|
||||||
|
/** Default maximal iteration count. */ |
||||||
|
public static final int DEFAULT_MAX_ITERATIONS_COUNT = Integer.MAX_VALUE; |
||||||
|
|
||||||
|
/** The iteration count. |
||||||
|
* @deprecated as of 3.6, this field has been replaced with {@link #incrementCount()} |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
protected Incrementor iterations; |
||||||
|
|
||||||
|
/** The iteration count. */ |
||||||
|
private IntegerSequence.Incrementor count; |
||||||
|
|
||||||
|
/** Maximum absolute error. */ |
||||||
|
private final double absoluteAccuracy; |
||||||
|
|
||||||
|
/** Maximum relative error. */ |
||||||
|
private final double relativeAccuracy; |
||||||
|
|
||||||
|
/** minimum number of iterations */ |
||||||
|
private final int minimalIterationCount; |
||||||
|
|
||||||
|
/** The functions evaluation count. */ |
||||||
|
private IntegerSequence.Incrementor evaluations; |
||||||
|
|
||||||
|
/** Function to integrate. */ |
||||||
|
private UnivariateFunction function; |
||||||
|
|
||||||
|
/** Lower bound for the interval. */ |
||||||
|
private double min; |
||||||
|
|
||||||
|
/** Upper bound for the interval. */ |
||||||
|
private double max; |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct an integrator with given accuracies and iteration counts. |
||||||
|
* <p> |
||||||
|
* The meanings of the various parameters are: |
||||||
|
* <ul> |
||||||
|
* <li>relative accuracy: |
||||||
|
* this is used to stop iterations if the absolute accuracy can't be |
||||||
|
* achieved due to large values or short mantissa length. If this |
||||||
|
* should be the primary criterion for convergence rather then a |
||||||
|
* safety measure, set the absolute accuracy to a ridiculously small value, |
||||||
|
* like {@link Precision#SAFE_MIN Precision.SAFE_MIN}.</li> |
||||||
|
* <li>absolute accuracy: |
||||||
|
* The default is usually chosen so that results in the interval |
||||||
|
* -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the |
||||||
|
* expected absolute value of your results is of much smaller magnitude, set |
||||||
|
* this to a smaller value.</li> |
||||||
|
* <li>minimum number of iterations: |
||||||
|
* minimal iteration is needed to avoid false early convergence, e.g. |
||||||
|
* the sample points happen to be zeroes of the function. Users can |
||||||
|
* use the default value or choose one that they see as appropriate.</li> |
||||||
|
* <li>maximum number of iterations: |
||||||
|
* usually a high iteration count indicates convergence problems. However, |
||||||
|
* the "reasonable value" varies widely for different algorithms. Users are |
||||||
|
* advised to use the default value supplied by the algorithm.</li> |
||||||
|
* </ul> |
||||||
|
* |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
*/ |
||||||
|
protected BaseAbstractUnivariateIntegrator(final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException { |
||||||
|
|
||||||
|
// accuracy settings
|
||||||
|
this.relativeAccuracy = relativeAccuracy; |
||||||
|
this.absoluteAccuracy = absoluteAccuracy; |
||||||
|
|
||||||
|
// iterations count settings
|
||||||
|
if (minimalIterationCount <= 0) { |
||||||
|
throw new NotStrictlyPositiveException(minimalIterationCount); |
||||||
|
} |
||||||
|
if (maximalIterationCount <= minimalIterationCount) { |
||||||
|
throw new NumberIsTooSmallException(maximalIterationCount, minimalIterationCount, false); |
||||||
|
} |
||||||
|
this.minimalIterationCount = minimalIterationCount; |
||||||
|
this.count = IntegerSequence.Incrementor.create().withMaximalCount(maximalIterationCount); |
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") |
||||||
|
Incrementor wrapped = |
||||||
|
Incrementor.wrap(count); |
||||||
|
this.iterations = wrapped; |
||||||
|
|
||||||
|
// prepare evaluations counter, but do not set it yet
|
||||||
|
evaluations = IntegerSequence.Incrementor.create(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct an integrator with given accuracies. |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
*/ |
||||||
|
protected BaseAbstractUnivariateIntegrator(final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy) { |
||||||
|
this(relativeAccuracy, absoluteAccuracy, |
||||||
|
DEFAULT_MIN_ITERATIONS_COUNT, DEFAULT_MAX_ITERATIONS_COUNT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct an integrator with given iteration counts. |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
*/ |
||||||
|
protected BaseAbstractUnivariateIntegrator(final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException { |
||||||
|
this(DEFAULT_RELATIVE_ACCURACY, DEFAULT_ABSOLUTE_ACCURACY, |
||||||
|
minimalIterationCount, maximalIterationCount); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double getRelativeAccuracy() { |
||||||
|
return relativeAccuracy; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double getAbsoluteAccuracy() { |
||||||
|
return absoluteAccuracy; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public int getMinimalIterationCount() { |
||||||
|
return minimalIterationCount; |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public int getMaximalIterationCount() { |
||||||
|
return count.getMaximalCount(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public int getEvaluations() { |
||||||
|
return evaluations.getCount(); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public int getIterations() { |
||||||
|
return count.getCount(); |
||||||
|
} |
||||||
|
|
||||||
|
/** Increment the number of iterations. |
||||||
|
* @exception MaxCountExceededException if the number of iterations |
||||||
|
* exceeds the allowed maximum number |
||||||
|
*/ |
||||||
|
protected void incrementCount() throws MaxCountExceededException { |
||||||
|
count.increment(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the lower bound. |
||||||
|
*/ |
||||||
|
protected double getMin() { |
||||||
|
return min; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @return the upper bound. |
||||||
|
*/ |
||||||
|
protected double getMax() { |
||||||
|
return max; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the objective function value. |
||||||
|
* |
||||||
|
* @param point Point at which the objective function must be evaluated. |
||||||
|
* @return the objective function value at specified point. |
||||||
|
* @throws TooManyEvaluationsException if the maximal number of function |
||||||
|
* evaluations is exceeded. |
||||||
|
*/ |
||||||
|
protected double computeObjectiveValue(final double point) |
||||||
|
throws TooManyEvaluationsException { |
||||||
|
try { |
||||||
|
evaluations.increment(); |
||||||
|
} catch (MaxCountExceededException e) { |
||||||
|
throw new TooManyEvaluationsException(e.getMax()); |
||||||
|
} |
||||||
|
return function.value(point); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Prepare for computation. |
||||||
|
* Subclasses must call this method if they override any of the |
||||||
|
* {@code solve} methods. |
||||||
|
* |
||||||
|
* @param maxEval Maximum number of evaluations. |
||||||
|
* @param f the integrand function |
||||||
|
* @param lower the min bound for the interval |
||||||
|
* @param upper the upper bound for the interval |
||||||
|
* @throws NullArgumentException if {@code f} is {@code null}. |
||||||
|
* @throws MathIllegalArgumentException if {@code min >= max}. |
||||||
|
*/ |
||||||
|
protected void setup(final int maxEval, |
||||||
|
final UnivariateFunction f, |
||||||
|
final double lower, final double upper) |
||||||
|
throws NullArgumentException, MathIllegalArgumentException { |
||||||
|
|
||||||
|
// Checks.
|
||||||
|
MathUtils.checkNotNull(f); |
||||||
|
UnivariateSolverUtils.verifyInterval(lower, upper); |
||||||
|
|
||||||
|
// Reset.
|
||||||
|
min = lower; |
||||||
|
max = upper; |
||||||
|
function = f; |
||||||
|
evaluations = evaluations.withMaximalCount(maxEval).withStart(0); |
||||||
|
count = count.withStart(0); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double integrate(final int maxEval, final UnivariateFunction f, |
||||||
|
final double lower, final double upper) |
||||||
|
throws TooManyEvaluationsException, MaxCountExceededException, |
||||||
|
MathIllegalArgumentException, NullArgumentException { |
||||||
|
|
||||||
|
// Initialization.
|
||||||
|
setup(maxEval, f, lower, upper); |
||||||
|
|
||||||
|
// Perform computation.
|
||||||
|
return doIntegrate(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Method for implementing actual integration algorithms in derived |
||||||
|
* classes. |
||||||
|
* |
||||||
|
* @return the root. |
||||||
|
* @throws TooManyEvaluationsException if the maximal number of evaluations |
||||||
|
* is exceeded. |
||||||
|
* @throws MaxCountExceededException if the maximum iteration count is exceeded |
||||||
|
* or the integrator detects convergence problems otherwise |
||||||
|
*/ |
||||||
|
protected abstract double doIntegrate() |
||||||
|
throws TooManyEvaluationsException, MaxCountExceededException; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,183 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.util.LocalizedFormats; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.integration.gauss.GaussIntegratorFactory; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.integration.gauss.GaussIntegrator; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* This algorithm divides the integration interval into equally-sized |
||||||
|
* sub-interval and on each of them performs a |
||||||
|
* <a href="http://mathworld.wolfram.com/Legendre-GaussQuadrature.html"> |
||||||
|
* Legendre-Gauss</a> quadrature. |
||||||
|
* Because of its <em>non-adaptive</em> nature, this algorithm can |
||||||
|
* converge to a wrong value for the integral (for example, if the |
||||||
|
* function is significantly different from zero toward the ends of the |
||||||
|
* integration interval). |
||||||
|
* In particular, a change of variables aimed at estimating integrals |
||||||
|
* over infinite intervals as proposed |
||||||
|
* <a href="http://en.wikipedia.org/w/index.php?title=Numerical_integration#Integrals_over_infinite_intervals"> |
||||||
|
* here</a> should be avoided when using this class. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
|
||||||
|
public class IterativeLegendreGaussIntegrator |
||||||
|
extends BaseAbstractUnivariateIntegrator { |
||||||
|
/** Factory that computes the points and weights. */ |
||||||
|
private static final GaussIntegratorFactory FACTORY |
||||||
|
= new GaussIntegratorFactory(); |
||||||
|
/** Number of integration points (per interval). */ |
||||||
|
private final int numberOfPoints; |
||||||
|
|
||||||
|
/** |
||||||
|
* Builds an integrator with given accuracies and iterations counts. |
||||||
|
* |
||||||
|
* @param n Number of integration points. |
||||||
|
* @param relativeAccuracy Relative accuracy of the result. |
||||||
|
* @param absoluteAccuracy Absolute accuracy of the result. |
||||||
|
* @param minimalIterationCount Minimum number of iterations. |
||||||
|
* @param maximalIterationCount Maximum number of iterations. |
||||||
|
* @throws NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* or number of points are not strictly positive. |
||||||
|
* @throws NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is smaller than or equal to the minimal number of iterations. |
||||||
|
*/ |
||||||
|
public IterativeLegendreGaussIntegrator(final int n, |
||||||
|
final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException { |
||||||
|
super(relativeAccuracy, absoluteAccuracy, minimalIterationCount, maximalIterationCount); |
||||||
|
if (n <= 0) { |
||||||
|
throw new NotStrictlyPositiveException(LocalizedFormats.NUMBER_OF_POINTS, n); |
||||||
|
} |
||||||
|
numberOfPoints = n; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Builds an integrator with given accuracies. |
||||||
|
* |
||||||
|
* @param n Number of integration points. |
||||||
|
* @param relativeAccuracy Relative accuracy of the result. |
||||||
|
* @param absoluteAccuracy Absolute accuracy of the result. |
||||||
|
* @throws NotStrictlyPositiveException if {@code n < 1}. |
||||||
|
*/ |
||||||
|
public IterativeLegendreGaussIntegrator(final int n, |
||||||
|
final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy) |
||||||
|
throws NotStrictlyPositiveException { |
||||||
|
this(n, relativeAccuracy, absoluteAccuracy, |
||||||
|
DEFAULT_MIN_ITERATIONS_COUNT, DEFAULT_MAX_ITERATIONS_COUNT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Builds an integrator with given iteration counts. |
||||||
|
* |
||||||
|
* @param n Number of integration points. |
||||||
|
* @param minimalIterationCount Minimum number of iterations. |
||||||
|
* @param maximalIterationCount Maximum number of iterations. |
||||||
|
* @throws NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive. |
||||||
|
* @throws NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is smaller than or equal to the minimal number of iterations. |
||||||
|
* @throws NotStrictlyPositiveException if {@code n < 1}. |
||||||
|
*/ |
||||||
|
public IterativeLegendreGaussIntegrator(final int n, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException { |
||||||
|
this(n, DEFAULT_RELATIVE_ACCURACY, DEFAULT_ABSOLUTE_ACCURACY, |
||||||
|
minimalIterationCount, maximalIterationCount); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected double doIntegrate() |
||||||
|
throws MathIllegalArgumentException, TooManyEvaluationsException, MaxCountExceededException { |
||||||
|
// Compute first estimate with a single step.
|
||||||
|
double oldt = stage(1); |
||||||
|
|
||||||
|
int n = 2; |
||||||
|
while (true) { |
||||||
|
// Improve integral with a larger number of steps.
|
||||||
|
final double t = stage(n); |
||||||
|
|
||||||
|
// Estimate the error.
|
||||||
|
final double delta = FastMath.abs(t - oldt); |
||||||
|
final double limit = |
||||||
|
FastMath.max(getAbsoluteAccuracy(), |
||||||
|
getRelativeAccuracy() * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5); |
||||||
|
|
||||||
|
// check convergence
|
||||||
|
if (getIterations() + 1 >= getMinimalIterationCount() && |
||||||
|
delta <= limit) { |
||||||
|
return t; |
||||||
|
} |
||||||
|
|
||||||
|
// Prepare next iteration.
|
||||||
|
final double ratio = FastMath.min(4, FastMath.pow(delta / limit, 0.5 / numberOfPoints)); |
||||||
|
n = FastMath.max((int) (ratio * n), n + 1); |
||||||
|
oldt = t; |
||||||
|
incrementCount(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the n-th stage integral. |
||||||
|
* |
||||||
|
* @param n Number of steps. |
||||||
|
* @return the value of n-th stage integral. |
||||||
|
* @throws TooManyEvaluationsException if the maximum number of evaluations |
||||||
|
* is exceeded. |
||||||
|
*/ |
||||||
|
private double stage(final int n) |
||||||
|
throws TooManyEvaluationsException { |
||||||
|
// Function to be integrated is stored in the base class.
|
||||||
|
final UnivariateFunction f = new UnivariateFunction() { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
public double value(double x) |
||||||
|
throws MathIllegalArgumentException, TooManyEvaluationsException { |
||||||
|
return computeObjectiveValue(x); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
final double min = getMin(); |
||||||
|
final double max = getMax(); |
||||||
|
final double step = (max - min) / n; |
||||||
|
|
||||||
|
double sum = 0; |
||||||
|
for (int i = 0; i < n; i++) { |
||||||
|
// Integrate over each sub-interval [a, b].
|
||||||
|
final double a = min + i * step; |
||||||
|
final double b = a + step; |
||||||
|
final GaussIntegrator g = FACTORY.legendreHighPrecision(numberOfPoints, a, b); |
||||||
|
sum += g.integrate(f); |
||||||
|
} |
||||||
|
|
||||||
|
return sum; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,265 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.util.LocalizedFormats; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements the <a href="http://mathworld.wolfram.com/Legendre-GaussQuadrature.html"> |
||||||
|
* Legendre-Gauss</a> quadrature formula. |
||||||
|
* <p> |
||||||
|
* Legendre-Gauss integrators are efficient integrators that can |
||||||
|
* accurately integrate functions with few function evaluations. A |
||||||
|
* Legendre-Gauss integrator using an n-points quadrature formula can |
||||||
|
* integrate 2n-1 degree polynomials exactly. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* These integrators evaluate the function on n carefully chosen |
||||||
|
* abscissas in each step interval (mapped to the canonical [-1,1] interval). |
||||||
|
* The evaluation abscissas are not evenly spaced and none of them are |
||||||
|
* at the interval endpoints. This implies the function integrated can be |
||||||
|
* undefined at integration interval endpoints. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* The evaluation abscissas x<sub>i</sub> are the roots of the degree n |
||||||
|
* Legendre polynomial. The weights a<sub>i</sub> of the quadrature formula |
||||||
|
* integrals from -1 to +1 ∫ Li<sup>2</sup> where Li (x) = |
||||||
|
* ∏ (x-x<sub>k</sub>)/(x<sub>i</sub>-x<sub>k</sub>) for k != i. |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* @since 1.2 |
||||||
|
* @deprecated As of 3.1 (to be removed in 4.0). Please use |
||||||
|
* {@link IterativeLegendreGaussIntegrator} instead. |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public class LegendreGaussIntegrator extends BaseAbstractUnivariateIntegrator { |
||||||
|
|
||||||
|
/** Abscissas for the 2 points method. */ |
||||||
|
private static final double[] ABSCISSAS_2 = { |
||||||
|
-1.0 / FastMath.sqrt(3.0), |
||||||
|
1.0 / FastMath.sqrt(3.0) |
||||||
|
}; |
||||||
|
|
||||||
|
/** Weights for the 2 points method. */ |
||||||
|
private static final double[] WEIGHTS_2 = { |
||||||
|
1.0, |
||||||
|
1.0 |
||||||
|
}; |
||||||
|
|
||||||
|
/** Abscissas for the 3 points method. */ |
||||||
|
private static final double[] ABSCISSAS_3 = { |
||||||
|
-FastMath.sqrt(0.6), |
||||||
|
0.0, |
||||||
|
FastMath.sqrt(0.6) |
||||||
|
}; |
||||||
|
|
||||||
|
/** Weights for the 3 points method. */ |
||||||
|
private static final double[] WEIGHTS_3 = { |
||||||
|
5.0 / 9.0, |
||||||
|
8.0 / 9.0, |
||||||
|
5.0 / 9.0 |
||||||
|
}; |
||||||
|
|
||||||
|
/** Abscissas for the 4 points method. */ |
||||||
|
private static final double[] ABSCISSAS_4 = { |
||||||
|
-FastMath.sqrt((15.0 + 2.0 * FastMath.sqrt(30.0)) / 35.0), |
||||||
|
-FastMath.sqrt((15.0 - 2.0 * FastMath.sqrt(30.0)) / 35.0), |
||||||
|
FastMath.sqrt((15.0 - 2.0 * FastMath.sqrt(30.0)) / 35.0), |
||||||
|
FastMath.sqrt((15.0 + 2.0 * FastMath.sqrt(30.0)) / 35.0) |
||||||
|
}; |
||||||
|
|
||||||
|
/** Weights for the 4 points method. */ |
||||||
|
private static final double[] WEIGHTS_4 = { |
||||||
|
(90.0 - 5.0 * FastMath.sqrt(30.0)) / 180.0, |
||||||
|
(90.0 + 5.0 * FastMath.sqrt(30.0)) / 180.0, |
||||||
|
(90.0 + 5.0 * FastMath.sqrt(30.0)) / 180.0, |
||||||
|
(90.0 - 5.0 * FastMath.sqrt(30.0)) / 180.0 |
||||||
|
}; |
||||||
|
|
||||||
|
/** Abscissas for the 5 points method. */ |
||||||
|
private static final double[] ABSCISSAS_5 = { |
||||||
|
-FastMath.sqrt((35.0 + 2.0 * FastMath.sqrt(70.0)) / 63.0), |
||||||
|
-FastMath.sqrt((35.0 - 2.0 * FastMath.sqrt(70.0)) / 63.0), |
||||||
|
0.0, |
||||||
|
FastMath.sqrt((35.0 - 2.0 * FastMath.sqrt(70.0)) / 63.0), |
||||||
|
FastMath.sqrt((35.0 + 2.0 * FastMath.sqrt(70.0)) / 63.0) |
||||||
|
}; |
||||||
|
|
||||||
|
/** Weights for the 5 points method. */ |
||||||
|
private static final double[] WEIGHTS_5 = { |
||||||
|
(322.0 - 13.0 * FastMath.sqrt(70.0)) / 900.0, |
||||||
|
(322.0 + 13.0 * FastMath.sqrt(70.0)) / 900.0, |
||||||
|
128.0 / 225.0, |
||||||
|
(322.0 + 13.0 * FastMath.sqrt(70.0)) / 900.0, |
||||||
|
(322.0 - 13.0 * FastMath.sqrt(70.0)) / 900.0 |
||||||
|
}; |
||||||
|
|
||||||
|
/** Abscissas for the current method. */ |
||||||
|
private final double[] abscissas; |
||||||
|
|
||||||
|
/** Weights for the current method. */ |
||||||
|
private final double[] weights; |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a Legendre-Gauss integrator with given accuracies and iterations counts. |
||||||
|
* @param n number of points desired (must be between 2 and 5 inclusive) |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* @exception MathIllegalArgumentException if number of points is out of [2; 5] |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
*/ |
||||||
|
public LegendreGaussIntegrator(final int n, |
||||||
|
final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws MathIllegalArgumentException, NotStrictlyPositiveException, NumberIsTooSmallException { |
||||||
|
super(relativeAccuracy, absoluteAccuracy, minimalIterationCount, maximalIterationCount); |
||||||
|
switch(n) { |
||||||
|
case 2 : |
||||||
|
abscissas = ABSCISSAS_2; |
||||||
|
weights = WEIGHTS_2; |
||||||
|
break; |
||||||
|
case 3 : |
||||||
|
abscissas = ABSCISSAS_3; |
||||||
|
weights = WEIGHTS_3; |
||||||
|
break; |
||||||
|
case 4 : |
||||||
|
abscissas = ABSCISSAS_4; |
||||||
|
weights = WEIGHTS_4; |
||||||
|
break; |
||||||
|
case 5 : |
||||||
|
abscissas = ABSCISSAS_5; |
||||||
|
weights = WEIGHTS_5; |
||||||
|
break; |
||||||
|
default : |
||||||
|
throw new MathIllegalArgumentException( |
||||||
|
LocalizedFormats.N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED, |
||||||
|
n, 2, 5); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a Legendre-Gauss integrator with given accuracies. |
||||||
|
* @param n number of points desired (must be between 2 and 5 inclusive) |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
* @exception MathIllegalArgumentException if number of points is out of [2; 5] |
||||||
|
*/ |
||||||
|
public LegendreGaussIntegrator(final int n, |
||||||
|
final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy) |
||||||
|
throws MathIllegalArgumentException { |
||||||
|
this(n, relativeAccuracy, absoluteAccuracy, |
||||||
|
DEFAULT_MIN_ITERATIONS_COUNT, DEFAULT_MAX_ITERATIONS_COUNT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a Legendre-Gauss integrator with given iteration counts. |
||||||
|
* @param n number of points desired (must be between 2 and 5 inclusive) |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* @exception MathIllegalArgumentException if number of points is out of [2; 5] |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
*/ |
||||||
|
public LegendreGaussIntegrator(final int n, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws MathIllegalArgumentException { |
||||||
|
this(n, DEFAULT_RELATIVE_ACCURACY, DEFAULT_ABSOLUTE_ACCURACY, |
||||||
|
minimalIterationCount, maximalIterationCount); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected double doIntegrate() |
||||||
|
throws MathIllegalArgumentException, TooManyEvaluationsException, MaxCountExceededException { |
||||||
|
|
||||||
|
// compute first estimate with a single step
|
||||||
|
double oldt = stage(1); |
||||||
|
|
||||||
|
int n = 2; |
||||||
|
while (true) { |
||||||
|
|
||||||
|
// improve integral with a larger number of steps
|
||||||
|
final double t = stage(n); |
||||||
|
|
||||||
|
// estimate error
|
||||||
|
final double delta = FastMath.abs(t - oldt); |
||||||
|
final double limit = |
||||||
|
FastMath.max(getAbsoluteAccuracy(), |
||||||
|
getRelativeAccuracy() * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5); |
||||||
|
|
||||||
|
// check convergence
|
||||||
|
if ((getIterations() + 1 >= getMinimalIterationCount()) && (delta <= limit)) { |
||||||
|
return t; |
||||||
|
} |
||||||
|
|
||||||
|
// prepare next iteration
|
||||||
|
double ratio = FastMath.min(4, FastMath.pow(delta / limit, 0.5 / abscissas.length)); |
||||||
|
n = FastMath.max((int) (ratio * n), n + 1); |
||||||
|
oldt = t; |
||||||
|
incrementCount(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the n-th stage integral. |
||||||
|
* @param n number of steps |
||||||
|
* @return the value of n-th stage integral |
||||||
|
* @throws TooManyEvaluationsException if the maximum number of evaluations |
||||||
|
* is exceeded. |
||||||
|
*/ |
||||||
|
private double stage(final int n) |
||||||
|
throws TooManyEvaluationsException { |
||||||
|
|
||||||
|
// set up the step for the current stage
|
||||||
|
final double step = (getMax() - getMin()) / n; |
||||||
|
final double halfStep = step / 2.0; |
||||||
|
|
||||||
|
// integrate over all elementary steps
|
||||||
|
double midPoint = getMin() + halfStep; |
||||||
|
double sum = 0.0; |
||||||
|
for (int i = 0; i < n; ++i) { |
||||||
|
for (int j = 0; j < abscissas.length; ++j) { |
||||||
|
sum += weights[j] * computeObjectiveValue(midPoint + halfStep * abscissas[j]); |
||||||
|
} |
||||||
|
midPoint += step; |
||||||
|
} |
||||||
|
|
||||||
|
return halfStep * sum; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,169 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooLargeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements the <a href="http://en.wikipedia.org/wiki/Midpoint_method"> |
||||||
|
* Midpoint Rule</a> for integration of real univariate functions. For |
||||||
|
* reference, see <b>Numerical Mathematics</b>, ISBN 0387989595, |
||||||
|
* chapter 9.2. |
||||||
|
* <p> |
||||||
|
* The function should be integrable.</p> |
||||||
|
* |
||||||
|
* @since 3.3 |
||||||
|
*/ |
||||||
|
public class MidPointIntegrator extends BaseAbstractUnivariateIntegrator { |
||||||
|
|
||||||
|
/** Maximum number of iterations for midpoint. */ |
||||||
|
public static final int MIDPOINT_MAX_ITERATIONS_COUNT = 64; |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a midpoint integrator with given accuracies and iterations counts. |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #MIDPOINT_MAX_ITERATIONS_COUNT} |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #MIDPOINT_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public MidPointIntegrator(final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(relativeAccuracy, absoluteAccuracy, minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > MIDPOINT_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
MIDPOINT_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a midpoint integrator with given iteration counts. |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #MIDPOINT_MAX_ITERATIONS_COUNT} |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #MIDPOINT_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public MidPointIntegrator(final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > MIDPOINT_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
MIDPOINT_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct a midpoint integrator with default settings. |
||||||
|
* (max iteration count set to {@link #MIDPOINT_MAX_ITERATIONS_COUNT}) |
||||||
|
*/ |
||||||
|
public MidPointIntegrator() { |
||||||
|
super(DEFAULT_MIN_ITERATIONS_COUNT, MIDPOINT_MAX_ITERATIONS_COUNT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the n-th stage integral of midpoint rule. |
||||||
|
* This function should only be called by API <code>integrate()</code> in the package. |
||||||
|
* To save time it does not verify arguments - caller does. |
||||||
|
* <p> |
||||||
|
* The interval is divided equally into 2^n sections rather than an |
||||||
|
* arbitrary m sections because this configuration can best utilize the |
||||||
|
* already computed values.</p> |
||||||
|
* |
||||||
|
* @param n the stage of 1/2 refinement. Must be larger than 0. |
||||||
|
* @param previousStageResult Result from the previous call to the |
||||||
|
* {@code stage} method. |
||||||
|
* @param min Lower bound of the integration interval. |
||||||
|
* @param diffMaxMin Difference between the lower bound and upper bound |
||||||
|
* of the integration interval. |
||||||
|
* @return the value of n-th stage integral |
||||||
|
* @throws TooManyEvaluationsException if the maximal number of evaluations |
||||||
|
* is exceeded. |
||||||
|
*/ |
||||||
|
private double stage(final int n, |
||||||
|
double previousStageResult, |
||||||
|
double min, |
||||||
|
double diffMaxMin) |
||||||
|
throws TooManyEvaluationsException { |
||||||
|
|
||||||
|
// number of new points in this stage
|
||||||
|
final long np = 1L << (n - 1); |
||||||
|
double sum = 0; |
||||||
|
|
||||||
|
// spacing between adjacent new points
|
||||||
|
final double spacing = diffMaxMin / np; |
||||||
|
|
||||||
|
// the first new point
|
||||||
|
double x = min + 0.5 * spacing; |
||||||
|
for (long i = 0; i < np; i++) { |
||||||
|
sum += computeObjectiveValue(x); |
||||||
|
x += spacing; |
||||||
|
} |
||||||
|
// add the new sum to previously calculated result
|
||||||
|
return 0.5 * (previousStageResult + sum * spacing); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected double doIntegrate() |
||||||
|
throws MathIllegalArgumentException, TooManyEvaluationsException, MaxCountExceededException { |
||||||
|
|
||||||
|
final double min = getMin(); |
||||||
|
final double diff = getMax() - min; |
||||||
|
final double midPoint = min + 0.5 * diff; |
||||||
|
|
||||||
|
double oldt = diff * computeObjectiveValue(midPoint); |
||||||
|
|
||||||
|
while (true) { |
||||||
|
incrementCount(); |
||||||
|
final int i = getIterations(); |
||||||
|
final double t = stage(i, oldt, min, diff); |
||||||
|
if (i >= getMinimalIterationCount()) { |
||||||
|
final double delta = FastMath.abs(t - oldt); |
||||||
|
final double rLimit = |
||||||
|
getRelativeAccuracy() * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5; |
||||||
|
if ((delta <= rLimit) || (delta <= getAbsoluteAccuracy())) { |
||||||
|
return t; |
||||||
|
} |
||||||
|
} |
||||||
|
oldt = t; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,142 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooLargeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements the <a href="http://mathworld.wolfram.com/RombergIntegration.html"> |
||||||
|
* Romberg Algorithm</a> for integration of real univariate functions. For |
||||||
|
* reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, |
||||||
|
* chapter 3. |
||||||
|
* <p> |
||||||
|
* Romberg integration employs k successive refinements of the trapezoid |
||||||
|
* rule to remove error terms less than order O(N^(-2k)). Simpson's rule |
||||||
|
* is a special case of k = 2.</p> |
||||||
|
* |
||||||
|
* @since 1.2 |
||||||
|
*/ |
||||||
|
public class RombergIntegrator extends BaseAbstractUnivariateIntegrator { |
||||||
|
|
||||||
|
/** Maximal number of iterations for Romberg. */ |
||||||
|
public static final int ROMBERG_MAX_ITERATIONS_COUNT = 32; |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a Romberg integrator with given accuracies and iterations counts. |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #ROMBERG_MAX_ITERATIONS_COUNT}) |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #ROMBERG_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public RombergIntegrator(final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(relativeAccuracy, absoluteAccuracy, minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > ROMBERG_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
ROMBERG_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a Romberg integrator with given iteration counts. |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #ROMBERG_MAX_ITERATIONS_COUNT}) |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #ROMBERG_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public RombergIntegrator(final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > ROMBERG_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
ROMBERG_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct a Romberg integrator with default settings |
||||||
|
* (max iteration count set to {@link #ROMBERG_MAX_ITERATIONS_COUNT}) |
||||||
|
*/ |
||||||
|
public RombergIntegrator() { |
||||||
|
super(DEFAULT_MIN_ITERATIONS_COUNT, ROMBERG_MAX_ITERATIONS_COUNT); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected double doIntegrate() |
||||||
|
throws TooManyEvaluationsException, MaxCountExceededException { |
||||||
|
|
||||||
|
final int m = getMaximalIterationCount() + 1; |
||||||
|
double previousRow[] = new double[m]; |
||||||
|
double currentRow[] = new double[m]; |
||||||
|
|
||||||
|
TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); |
||||||
|
currentRow[0] = qtrap.stage(this, 0); |
||||||
|
incrementCount(); |
||||||
|
double olds = currentRow[0]; |
||||||
|
while (true) { |
||||||
|
|
||||||
|
final int i = getIterations(); |
||||||
|
|
||||||
|
// switch rows
|
||||||
|
final double[] tmpRow = previousRow; |
||||||
|
previousRow = currentRow; |
||||||
|
currentRow = tmpRow; |
||||||
|
|
||||||
|
currentRow[0] = qtrap.stage(this, i); |
||||||
|
incrementCount(); |
||||||
|
for (int j = 1; j <= i; j++) { |
||||||
|
// Richardson extrapolation coefficient
|
||||||
|
final double r = (1L << (2 * j)) - 1; |
||||||
|
final double tIJm1 = currentRow[j - 1]; |
||||||
|
currentRow[j] = tIJm1 + (tIJm1 - previousRow[j - 1]) / r; |
||||||
|
} |
||||||
|
final double s = currentRow[i]; |
||||||
|
if (i >= getMinimalIterationCount()) { |
||||||
|
final double delta = FastMath.abs(s - olds); |
||||||
|
final double rLimit = getRelativeAccuracy() * (FastMath.abs(olds) + FastMath.abs(s)) * 0.5; |
||||||
|
if ((delta <= rLimit) || (delta <= getAbsoluteAccuracy())) { |
||||||
|
return s; |
||||||
|
} |
||||||
|
} |
||||||
|
olds = s; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,129 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooLargeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements <a href="http://mathworld.wolfram.com/SimpsonsRule.html"> |
||||||
|
* Simpson's Rule</a> for integration of real univariate functions. For |
||||||
|
* reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, |
||||||
|
* chapter 3. |
||||||
|
* <p> |
||||||
|
* This implementation employs the basic trapezoid rule to calculate Simpson's |
||||||
|
* rule.</p> |
||||||
|
* |
||||||
|
* @since 1.2 |
||||||
|
*/ |
||||||
|
public class SimpsonIntegrator extends BaseAbstractUnivariateIntegrator { |
||||||
|
|
||||||
|
/** Maximal number of iterations for Simpson. */ |
||||||
|
public static final int SIMPSON_MAX_ITERATIONS_COUNT = 64; |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a Simpson integrator with given accuracies and iterations counts. |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #SIMPSON_MAX_ITERATIONS_COUNT}) |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #SIMPSON_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public SimpsonIntegrator(final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(relativeAccuracy, absoluteAccuracy, minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > SIMPSON_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
SIMPSON_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a Simpson integrator with given iteration counts. |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #SIMPSON_MAX_ITERATIONS_COUNT}) |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #SIMPSON_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public SimpsonIntegrator(final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > SIMPSON_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
SIMPSON_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct an integrator with default settings. |
||||||
|
* (max iteration count set to {@link #SIMPSON_MAX_ITERATIONS_COUNT}) |
||||||
|
*/ |
||||||
|
public SimpsonIntegrator() { |
||||||
|
super(DEFAULT_MIN_ITERATIONS_COUNT, SIMPSON_MAX_ITERATIONS_COUNT); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected double doIntegrate() |
||||||
|
throws TooManyEvaluationsException, MaxCountExceededException { |
||||||
|
|
||||||
|
TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); |
||||||
|
if (getMinimalIterationCount() == 1) { |
||||||
|
return (4 * qtrap.stage(this, 1) - qtrap.stage(this, 0)) / 3.0; |
||||||
|
} |
||||||
|
|
||||||
|
// Simpson's rule requires at least two trapezoid stages.
|
||||||
|
double olds = 0; |
||||||
|
double oldt = qtrap.stage(this, 0); |
||||||
|
while (true) { |
||||||
|
final double t = qtrap.stage(this, getIterations()); |
||||||
|
incrementCount(); |
||||||
|
final double s = (4 * t - oldt) / 3.0; |
||||||
|
if (getIterations() >= getMinimalIterationCount()) { |
||||||
|
final double delta = FastMath.abs(s - olds); |
||||||
|
final double rLimit = |
||||||
|
getRelativeAccuracy() * (FastMath.abs(olds) + FastMath.abs(s)) * 0.5; |
||||||
|
if ((delta <= rLimit) || (delta <= getAbsoluteAccuracy())) { |
||||||
|
return s; |
||||||
|
} |
||||||
|
} |
||||||
|
olds = s; |
||||||
|
oldt = t; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,168 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooLargeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements the <a href="http://mathworld.wolfram.com/TrapezoidalRule.html"> |
||||||
|
* Trapezoid Rule</a> for integration of real univariate functions. For |
||||||
|
* reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, |
||||||
|
* chapter 3. |
||||||
|
* <p> |
||||||
|
* The function should be integrable.</p> |
||||||
|
* |
||||||
|
* @since 1.2 |
||||||
|
*/ |
||||||
|
public class TrapezoidIntegrator extends BaseAbstractUnivariateIntegrator { |
||||||
|
|
||||||
|
/** Maximum number of iterations for trapezoid. */ |
||||||
|
public static final int TRAPEZOID_MAX_ITERATIONS_COUNT = 64; |
||||||
|
|
||||||
|
/** Intermediate result. */ |
||||||
|
private double s; |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a trapezoid integrator with given accuracies and iterations counts. |
||||||
|
* @param relativeAccuracy relative accuracy of the result |
||||||
|
* @param absoluteAccuracy absolute accuracy of the result |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #TRAPEZOID_MAX_ITERATIONS_COUNT} |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #TRAPEZOID_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public TrapezoidIntegrator(final double relativeAccuracy, |
||||||
|
final double absoluteAccuracy, |
||||||
|
final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(relativeAccuracy, absoluteAccuracy, minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > TRAPEZOID_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
TRAPEZOID_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Build a trapezoid integrator with given iteration counts. |
||||||
|
* @param minimalIterationCount minimum number of iterations |
||||||
|
* @param maximalIterationCount maximum number of iterations |
||||||
|
* (must be less than or equal to {@link #TRAPEZOID_MAX_ITERATIONS_COUNT} |
||||||
|
* @exception NotStrictlyPositiveException if minimal number of iterations |
||||||
|
* is not strictly positive |
||||||
|
* @exception NumberIsTooSmallException if maximal number of iterations |
||||||
|
* is lesser than or equal to the minimal number of iterations |
||||||
|
* @exception NumberIsTooLargeException if maximal number of iterations |
||||||
|
* is greater than {@link #TRAPEZOID_MAX_ITERATIONS_COUNT} |
||||||
|
*/ |
||||||
|
public TrapezoidIntegrator(final int minimalIterationCount, |
||||||
|
final int maximalIterationCount) |
||||||
|
throws NotStrictlyPositiveException, NumberIsTooSmallException, NumberIsTooLargeException { |
||||||
|
super(minimalIterationCount, maximalIterationCount); |
||||||
|
if (maximalIterationCount > TRAPEZOID_MAX_ITERATIONS_COUNT) { |
||||||
|
throw new NumberIsTooLargeException(maximalIterationCount, |
||||||
|
TRAPEZOID_MAX_ITERATIONS_COUNT, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct a trapezoid integrator with default settings. |
||||||
|
* (max iteration count set to {@link #TRAPEZOID_MAX_ITERATIONS_COUNT}) |
||||||
|
*/ |
||||||
|
public TrapezoidIntegrator() { |
||||||
|
super(DEFAULT_MIN_ITERATIONS_COUNT, TRAPEZOID_MAX_ITERATIONS_COUNT); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the n-th stage integral of trapezoid rule. This function |
||||||
|
* should only be called by API <code>integrate()</code> in the package. |
||||||
|
* To save time it does not verify arguments - caller does. |
||||||
|
* <p> |
||||||
|
* The interval is divided equally into 2^n sections rather than an |
||||||
|
* arbitrary m sections because this configuration can best utilize the |
||||||
|
* already computed values.</p> |
||||||
|
* |
||||||
|
* @param baseIntegrator integrator holding integration parameters |
||||||
|
* @param n the stage of 1/2 refinement, n = 0 is no refinement |
||||||
|
* @return the value of n-th stage integral |
||||||
|
* @throws TooManyEvaluationsException if the maximal number of evaluations |
||||||
|
* is exceeded. |
||||||
|
*/ |
||||||
|
double stage(final BaseAbstractUnivariateIntegrator baseIntegrator, final int n) |
||||||
|
throws TooManyEvaluationsException { |
||||||
|
|
||||||
|
if (n == 0) { |
||||||
|
final double max = baseIntegrator.getMax(); |
||||||
|
final double min = baseIntegrator.getMin(); |
||||||
|
s = 0.5 * (max - min) * |
||||||
|
(baseIntegrator.computeObjectiveValue(min) + |
||||||
|
baseIntegrator.computeObjectiveValue(max)); |
||||||
|
return s; |
||||||
|
} else { |
||||||
|
final long np = 1L << (n-1); // number of new points in this stage
|
||||||
|
double sum = 0; |
||||||
|
final double max = baseIntegrator.getMax(); |
||||||
|
final double min = baseIntegrator.getMin(); |
||||||
|
// spacing between adjacent new points
|
||||||
|
final double spacing = (max - min) / np; |
||||||
|
double x = min + 0.5 * spacing; // the first new point
|
||||||
|
for (long i = 0; i < np; i++) { |
||||||
|
sum += baseIntegrator.computeObjectiveValue(x); |
||||||
|
x += spacing; |
||||||
|
} |
||||||
|
// add the new sum to previously calculated result
|
||||||
|
s = 0.5 * (s + sum * spacing); |
||||||
|
return s; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected double doIntegrate() |
||||||
|
throws MathIllegalArgumentException, TooManyEvaluationsException, MaxCountExceededException { |
||||||
|
|
||||||
|
double oldt = stage(this, 0); |
||||||
|
incrementCount(); |
||||||
|
while (true) { |
||||||
|
final int i = getIterations(); |
||||||
|
final double t = stage(this, i); |
||||||
|
if (i >= getMinimalIterationCount()) { |
||||||
|
final double delta = FastMath.abs(t - oldt); |
||||||
|
final double rLimit = |
||||||
|
getRelativeAccuracy() * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5; |
||||||
|
if ((delta <= rLimit) || (delta <= getAbsoluteAccuracy())) { |
||||||
|
return t; |
||||||
|
} |
||||||
|
} |
||||||
|
oldt = t; |
||||||
|
incrementCount(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MathIllegalArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.MaxCountExceededException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.TooManyEvaluationsException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* Interface for univariate real integration algorithms. |
||||||
|
* |
||||||
|
* @since 1.2 |
||||||
|
*/ |
||||||
|
public interface UnivariateIntegrator { |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the relative accuracy. |
||||||
|
* |
||||||
|
* @return the accuracy |
||||||
|
*/ |
||||||
|
double getRelativeAccuracy(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the absolute accuracy. |
||||||
|
* |
||||||
|
* @return the accuracy |
||||||
|
*/ |
||||||
|
double getAbsoluteAccuracy(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the min limit for the number of iterations. |
||||||
|
* |
||||||
|
* @return the actual min limit |
||||||
|
*/ |
||||||
|
int getMinimalIterationCount(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the upper limit for the number of iterations. |
||||||
|
* |
||||||
|
* @return the actual upper limit |
||||||
|
*/ |
||||||
|
int getMaximalIterationCount(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Integrate the function in the given interval. |
||||||
|
* |
||||||
|
* @param maxEval Maximum number of evaluations. |
||||||
|
* @param f the integrand function |
||||||
|
* @param min the lower bound for the interval |
||||||
|
* @param max the upper bound for the interval |
||||||
|
* @return the value of integral |
||||||
|
* @throws TooManyEvaluationsException if the maximum number of function |
||||||
|
* evaluations is exceeded |
||||||
|
* @throws MaxCountExceededException if the maximum iteration count is exceeded |
||||||
|
* or the integrator detects convergence problems otherwise |
||||||
|
* @throws MathIllegalArgumentException if {@code min > max} or the endpoints do not |
||||||
|
* satisfy the requirements specified by the integrator |
||||||
|
* @throws NullArgumentException if {@code f} is {@code null}. |
||||||
|
*/ |
||||||
|
double integrate(int maxEval, UnivariateFunction f, double min, |
||||||
|
double max) |
||||||
|
throws TooManyEvaluationsException, MaxCountExceededException, |
||||||
|
MathIllegalArgumentException, NullArgumentException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the number of function evaluations of the last run of the integrator. |
||||||
|
* |
||||||
|
* @return number of function evaluations |
||||||
|
*/ |
||||||
|
int getEvaluations(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the number of iterations of the last run of the integrator. |
||||||
|
* |
||||||
|
* @return number of iterations |
||||||
|
*/ |
||||||
|
int getIterations(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,154 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
import java.util.TreeMap; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.util.LocalizedFormats; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Pair; |
||||||
|
|
||||||
|
/** |
||||||
|
* Base class for rules that determines the integration nodes and their |
||||||
|
* weights. |
||||||
|
* Subclasses must implement the {@link #computeRule(int) computeRule} method. |
||||||
|
* |
||||||
|
* @param <T> Type of the number used to represent the points and weights of |
||||||
|
* the quadrature rules. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public abstract class BaseRuleFactory<T extends Number> { |
||||||
|
/** List of points and weights, indexed by the order of the rule. */ |
||||||
|
private final Map<Integer, Pair<T[], T[]>> pointsAndWeights |
||||||
|
= new TreeMap<Integer, Pair<T[], T[]>>(); |
||||||
|
/** Cache for double-precision rules. */ |
||||||
|
private final Map<Integer, Pair<double[], double[]>> pointsAndWeightsDouble |
||||||
|
= new TreeMap<Integer, Pair<double[], double[]>>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets a copy of the quadrature rule with the given number of integration |
||||||
|
* points. |
||||||
|
* |
||||||
|
* @param numberOfPoints Number of integration points. |
||||||
|
* @return a copy of the integration rule. |
||||||
|
* @throws NotStrictlyPositiveException if {@code numberOfPoints < 1}. |
||||||
|
* @throws DimensionMismatchException if the elements of the rule pair do not |
||||||
|
* have the same length. |
||||||
|
*/ |
||||||
|
public Pair<double[], double[]> getRule(int numberOfPoints) |
||||||
|
throws NotStrictlyPositiveException, DimensionMismatchException { |
||||||
|
|
||||||
|
if (numberOfPoints <= 0) { |
||||||
|
throw new NotStrictlyPositiveException(LocalizedFormats.NUMBER_OF_POINTS, |
||||||
|
numberOfPoints); |
||||||
|
} |
||||||
|
|
||||||
|
// Try to obtain the rule from the cache.
|
||||||
|
Pair<double[], double[]> cached = pointsAndWeightsDouble.get(numberOfPoints); |
||||||
|
|
||||||
|
if (cached == null) { |
||||||
|
// Rule not computed yet.
|
||||||
|
|
||||||
|
// Compute the rule.
|
||||||
|
final Pair<T[], T[]> rule = getRuleInternal(numberOfPoints); |
||||||
|
cached = convertToDouble(rule); |
||||||
|
|
||||||
|
// Cache it.
|
||||||
|
pointsAndWeightsDouble.put(numberOfPoints, cached); |
||||||
|
} |
||||||
|
|
||||||
|
// Return a copy.
|
||||||
|
return new Pair<double[], double[]>(cached.getFirst().clone(), |
||||||
|
cached.getSecond().clone()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets a rule. |
||||||
|
* Synchronization ensures that rules will be computed and added to the |
||||||
|
* cache at most once. |
||||||
|
* The returned rule is a reference into the cache. |
||||||
|
* |
||||||
|
* @param numberOfPoints Order of the rule to be retrieved. |
||||||
|
* @return the points and weights corresponding to the given order. |
||||||
|
* @throws DimensionMismatchException if the elements of the rule pair do not |
||||||
|
* have the same length. |
||||||
|
*/ |
||||||
|
protected synchronized Pair<T[], T[]> getRuleInternal(int numberOfPoints) |
||||||
|
throws DimensionMismatchException { |
||||||
|
final Pair<T[], T[]> rule = pointsAndWeights.get(numberOfPoints); |
||||||
|
if (rule == null) { |
||||||
|
addRule(computeRule(numberOfPoints)); |
||||||
|
// The rule should be available now.
|
||||||
|
return getRuleInternal(numberOfPoints); |
||||||
|
} |
||||||
|
return rule; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Stores a rule. |
||||||
|
* |
||||||
|
* @param rule Rule to be stored. |
||||||
|
* @throws DimensionMismatchException if the elements of the pair do not |
||||||
|
* have the same length. |
||||||
|
*/ |
||||||
|
protected void addRule(Pair<T[], T[]> rule) throws DimensionMismatchException { |
||||||
|
if (rule.getFirst().length != rule.getSecond().length) { |
||||||
|
throw new DimensionMismatchException(rule.getFirst().length, |
||||||
|
rule.getSecond().length); |
||||||
|
} |
||||||
|
|
||||||
|
pointsAndWeights.put(rule.getFirst().length, rule); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes the rule for the given order. |
||||||
|
* |
||||||
|
* @param numberOfPoints Order of the rule to be computed. |
||||||
|
* @return the computed rule. |
||||||
|
* @throws DimensionMismatchException if the elements of the pair do not |
||||||
|
* have the same length. |
||||||
|
*/ |
||||||
|
protected abstract Pair<T[], T[]> computeRule(int numberOfPoints) |
||||||
|
throws DimensionMismatchException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Converts the from the actual {@code Number} type to {@code double} |
||||||
|
* |
||||||
|
* @param <T> Type of the number used to represent the points and |
||||||
|
* weights of the quadrature rules. |
||||||
|
* @param rule Points and weights. |
||||||
|
* @return points and weights as {@code double}s. |
||||||
|
*/ |
||||||
|
private static <T extends Number> Pair<double[], double[]> convertToDouble(Pair<T[], T[]> rule) { |
||||||
|
final T[] pT = rule.getFirst(); |
||||||
|
final T[] wT = rule.getSecond(); |
||||||
|
|
||||||
|
final int len = pT.length; |
||||||
|
final double[] pD = new double[len]; |
||||||
|
final double[] wD = new double[len]; |
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) { |
||||||
|
pD[i] = pT[i].doubleValue(); |
||||||
|
wD[i] = wT[i].doubleValue(); |
||||||
|
} |
||||||
|
|
||||||
|
return new Pair<double[], double[]>(pD, wD); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,129 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NonMonotonicSequenceException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.MathArrays; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Pair; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class that implements the Gaussian rule for |
||||||
|
* {@link #integrate(UnivariateFunction) integrating} a weighted |
||||||
|
* function. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class GaussIntegrator { |
||||||
|
/** Nodes. */ |
||||||
|
private final double[] points; |
||||||
|
/** Nodes weights. */ |
||||||
|
private final double[] weights; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates an integrator from the given {@code points} and {@code weights}. |
||||||
|
* The integration interval is defined by the first and last value of |
||||||
|
* {@code points} which must be sorted in increasing order. |
||||||
|
* |
||||||
|
* @param points Integration points. |
||||||
|
* @param weights Weights of the corresponding integration nodes. |
||||||
|
* @throws NonMonotonicSequenceException if the {@code points} are not |
||||||
|
* sorted in increasing order. |
||||||
|
* @throws DimensionMismatchException if points and weights don't have the same length |
||||||
|
*/ |
||||||
|
public GaussIntegrator(double[] points, |
||||||
|
double[] weights) |
||||||
|
throws NonMonotonicSequenceException, DimensionMismatchException { |
||||||
|
if (points.length != weights.length) { |
||||||
|
throw new DimensionMismatchException(points.length, |
||||||
|
weights.length); |
||||||
|
} |
||||||
|
|
||||||
|
MathArrays.checkOrder(points, MathArrays.OrderDirection.INCREASING, true, true); |
||||||
|
|
||||||
|
this.points = points.clone(); |
||||||
|
this.weights = weights.clone(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates an integrator from the given pair of points (first element of |
||||||
|
* the pair) and weights (second element of the pair. |
||||||
|
* |
||||||
|
* @param pointsAndWeights Integration points and corresponding weights. |
||||||
|
* @throws NonMonotonicSequenceException if the {@code points} are not |
||||||
|
* sorted in increasing order. |
||||||
|
* |
||||||
|
* @see #GaussIntegrator(double[], double[]) |
||||||
|
*/ |
||||||
|
public GaussIntegrator(Pair<double[], double[]> pointsAndWeights) |
||||||
|
throws NonMonotonicSequenceException { |
||||||
|
this(pointsAndWeights.getFirst(), pointsAndWeights.getSecond()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns an estimate of the integral of {@code f(x) * w(x)}, |
||||||
|
* where {@code w} is a weight function that depends on the actual |
||||||
|
* flavor of the Gauss integration scheme. |
||||||
|
* The algorithm uses the points and associated weights, as passed |
||||||
|
* to the {@link #GaussIntegrator(double[],double[]) constructor}. |
||||||
|
* |
||||||
|
* @param f Function to integrate. |
||||||
|
* @return the integral of the weighted function. |
||||||
|
*/ |
||||||
|
public double integrate(UnivariateFunction f) { |
||||||
|
double s = 0; |
||||||
|
double c = 0; |
||||||
|
for (int i = 0; i < points.length; i++) { |
||||||
|
final double x = points[i]; |
||||||
|
final double w = weights[i]; |
||||||
|
final double y = w * f.value(x) - c; |
||||||
|
final double t = s + y; |
||||||
|
c = (t - s) - y; |
||||||
|
s = t; |
||||||
|
} |
||||||
|
return s; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the order of the integration rule (the number of integration |
||||||
|
* points). |
||||||
|
*/ |
||||||
|
public int getNumberOfPoints() { |
||||||
|
return points.length; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the integration point at the given index. |
||||||
|
* The index must be in the valid range but no check is performed. |
||||||
|
* @param index index of the integration point |
||||||
|
* @return the integration point. |
||||||
|
*/ |
||||||
|
public double getPoint(int index) { |
||||||
|
return points[index]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the weight of the integration point at the given index. |
||||||
|
* The index must be in the valid range but no check is performed. |
||||||
|
* @param index index of the integration point |
||||||
|
* @return the weight. |
||||||
|
*/ |
||||||
|
public double getWeight(int index) { |
||||||
|
return weights[index]; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,168 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NotStrictlyPositiveException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Pair; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class that provides different ways to compute the nodes and weights to be |
||||||
|
* used by the {@link GaussIntegrator Gaussian integration rule}. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class GaussIntegratorFactory { |
||||||
|
/** Generator of Gauss-Legendre integrators. */ |
||||||
|
private final BaseRuleFactory<Double> legendre = new LegendreRuleFactory(); |
||||||
|
/** Generator of Gauss-Legendre integrators. */ |
||||||
|
private final BaseRuleFactory<BigDecimal> legendreHighPrecision = new LegendreHighPrecisionRuleFactory(); |
||||||
|
/** Generator of Gauss-Hermite integrators. */ |
||||||
|
private final BaseRuleFactory<Double> hermite = new HermiteRuleFactory(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a Gauss-Legendre integrator of the given order. |
||||||
|
* The call to the |
||||||
|
* {@link GaussIntegrator#integrate(UnivariateFunction) |
||||||
|
* integrate} method will perform an integration on the natural interval |
||||||
|
* {@code [-1 , 1]}. |
||||||
|
* |
||||||
|
* @param numberOfPoints Order of the integration rule. |
||||||
|
* @return a Gauss-Legendre integrator. |
||||||
|
*/ |
||||||
|
public GaussIntegrator legendre(int numberOfPoints) { |
||||||
|
return new GaussIntegrator(getRule(legendre, numberOfPoints)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a Gauss-Legendre integrator of the given order. |
||||||
|
* The call to the |
||||||
|
* {@link GaussIntegrator#integrate(UnivariateFunction) |
||||||
|
* integrate} method will perform an integration on the given interval. |
||||||
|
* |
||||||
|
* @param numberOfPoints Order of the integration rule. |
||||||
|
* @param lowerBound Lower bound of the integration interval. |
||||||
|
* @param upperBound Upper bound of the integration interval. |
||||||
|
* @return a Gauss-Legendre integrator. |
||||||
|
* @throws NotStrictlyPositiveException if number of points is not positive |
||||||
|
*/ |
||||||
|
public GaussIntegrator legendre(int numberOfPoints, |
||||||
|
double lowerBound, |
||||||
|
double upperBound) |
||||||
|
throws NotStrictlyPositiveException { |
||||||
|
return new GaussIntegrator(transform(getRule(legendre, numberOfPoints), |
||||||
|
lowerBound, upperBound)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a Gauss-Legendre integrator of the given order. |
||||||
|
* The call to the |
||||||
|
* {@link GaussIntegrator#integrate(UnivariateFunction) |
||||||
|
* integrate} method will perform an integration on the natural interval |
||||||
|
* {@code [-1 , 1]}. |
||||||
|
* |
||||||
|
* @param numberOfPoints Order of the integration rule. |
||||||
|
* @return a Gauss-Legendre integrator. |
||||||
|
* @throws NotStrictlyPositiveException if number of points is not positive |
||||||
|
*/ |
||||||
|
public GaussIntegrator legendreHighPrecision(int numberOfPoints) |
||||||
|
throws NotStrictlyPositiveException { |
||||||
|
return new GaussIntegrator(getRule(legendreHighPrecision, numberOfPoints)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates an integrator of the given order, and whose call to the |
||||||
|
* {@link GaussIntegrator#integrate(UnivariateFunction) |
||||||
|
* integrate} method will perform an integration on the given interval. |
||||||
|
* |
||||||
|
* @param numberOfPoints Order of the integration rule. |
||||||
|
* @param lowerBound Lower bound of the integration interval. |
||||||
|
* @param upperBound Upper bound of the integration interval. |
||||||
|
* @return a Gauss-Legendre integrator. |
||||||
|
* @throws NotStrictlyPositiveException if number of points is not positive |
||||||
|
*/ |
||||||
|
public GaussIntegrator legendreHighPrecision(int numberOfPoints, |
||||||
|
double lowerBound, |
||||||
|
double upperBound) |
||||||
|
throws NotStrictlyPositiveException { |
||||||
|
return new GaussIntegrator(transform(getRule(legendreHighPrecision, numberOfPoints), |
||||||
|
lowerBound, upperBound)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a Gauss-Hermite integrator of the given order. |
||||||
|
* The call to the |
||||||
|
* {@link SymmetricGaussIntegrator#integrate(UnivariateFunction) |
||||||
|
* integrate} method will perform a weighted integration on the interval |
||||||
|
* \([-\infty, +\infty]\): the computed value is the improper integral of |
||||||
|
* \(e^{-x^2}f(x)\) |
||||||
|
* where \(f(x)\) is the function passed to the |
||||||
|
* {@link SymmetricGaussIntegrator#integrate(UnivariateFunction) |
||||||
|
* integrate} method. |
||||||
|
* |
||||||
|
* @param numberOfPoints Order of the integration rule. |
||||||
|
* @return a Gauss-Hermite integrator. |
||||||
|
*/ |
||||||
|
public SymmetricGaussIntegrator hermite(int numberOfPoints) { |
||||||
|
return new SymmetricGaussIntegrator(getRule(hermite, numberOfPoints)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param factory Integration rule factory. |
||||||
|
* @param numberOfPoints Order of the integration rule. |
||||||
|
* @return the integration nodes and weights. |
||||||
|
* @throws NotStrictlyPositiveException if number of points is not positive |
||||||
|
* @throws DimensionMismatchException if the elements of the rule pair do not |
||||||
|
* have the same length. |
||||||
|
*/ |
||||||
|
private static Pair<double[], double[]> getRule(BaseRuleFactory<? extends Number> factory, |
||||||
|
int numberOfPoints) |
||||||
|
throws NotStrictlyPositiveException, DimensionMismatchException { |
||||||
|
return factory.getRule(numberOfPoints); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Performs a change of variable so that the integration can be performed |
||||||
|
* on an arbitrary interval {@code [a, b]}. |
||||||
|
* It is assumed that the natural interval is {@code [-1, 1]}. |
||||||
|
* |
||||||
|
* @param rule Original points and weights. |
||||||
|
* @param a Lower bound of the integration interval. |
||||||
|
* @param b Lower bound of the integration interval. |
||||||
|
* @return the points and weights adapted to the new interval. |
||||||
|
*/ |
||||||
|
private static Pair<double[], double[]> transform(Pair<double[], double[]> rule, |
||||||
|
double a, |
||||||
|
double b) { |
||||||
|
final double[] points = rule.getFirst(); |
||||||
|
final double[] weights = rule.getSecond(); |
||||||
|
|
||||||
|
// Scaling
|
||||||
|
final double scale = (b - a) / 2; |
||||||
|
final double shift = a + scale; |
||||||
|
|
||||||
|
for (int i = 0; i < points.length; i++) { |
||||||
|
points[i] = points[i] * scale + shift; |
||||||
|
weights[i] *= scale; |
||||||
|
} |
||||||
|
|
||||||
|
return new Pair<double[], double[]>(points, weights); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,177 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Pair; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Factory that creates a |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Gauss-Hermite_quadrature"> |
||||||
|
* Gauss-type quadrature rule using Hermite polynomials</a> |
||||||
|
* of the first kind. |
||||||
|
* Such a quadrature rule allows the calculation of improper integrals |
||||||
|
* of a function |
||||||
|
* <p> |
||||||
|
* \(f(x) e^{-x^2}\) |
||||||
|
* </p><p> |
||||||
|
* Recurrence relation and weights computation follow |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Abramowitz_and_Stegun"> |
||||||
|
* Abramowitz and Stegun, 1964</a>. |
||||||
|
* </p><p> |
||||||
|
* The coefficients of the standard Hermite polynomials grow very rapidly. |
||||||
|
* In order to avoid overflows, each Hermite polynomial is normalized with |
||||||
|
* respect to the underlying scalar product. |
||||||
|
* The initial interval for the application of the bisection method is |
||||||
|
* based on the roots of the previous Hermite polynomial (interlacing). |
||||||
|
* Upper and lower bounds of these roots are provided by </p> |
||||||
|
* <blockquote> |
||||||
|
* I. Krasikov, |
||||||
|
* <em>Nonnegative quadratic forms and bounds on orthogonal polynomials</em>, |
||||||
|
* Journal of Approximation theory <b>111</b>, 31-49 |
||||||
|
* </blockquote> |
||||||
|
* |
||||||
|
* @since 3.3 |
||||||
|
*/ |
||||||
|
public class HermiteRuleFactory extends BaseRuleFactory<Double> { |
||||||
|
/** π<sup>1/2</sup> */ |
||||||
|
private static final double SQRT_PI = 1.77245385090551602729; |
||||||
|
/** π<sup>-1/4</sup> */ |
||||||
|
private static final double H0 = 7.5112554446494248286e-1; |
||||||
|
/** π<sup>-1/4</sup> √2 */ |
||||||
|
private static final double H1 = 1.0622519320271969145; |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected Pair<Double[], Double[]> computeRule(int numberOfPoints) |
||||||
|
throws DimensionMismatchException { |
||||||
|
|
||||||
|
if (numberOfPoints == 1) { |
||||||
|
// Break recursion.
|
||||||
|
return new Pair<Double[], Double[]>(new Double[] { 0d }, |
||||||
|
new Double[] { SQRT_PI }); |
||||||
|
} |
||||||
|
|
||||||
|
// Get previous rule.
|
||||||
|
// If it has not been computed yet it will trigger a recursive call
|
||||||
|
// to this method.
|
||||||
|
final int lastNumPoints = numberOfPoints - 1; |
||||||
|
final Double[] previousPoints = getRuleInternal(lastNumPoints).getFirst(); |
||||||
|
|
||||||
|
// Compute next rule.
|
||||||
|
final Double[] points = new Double[numberOfPoints]; |
||||||
|
final Double[] weights = new Double[numberOfPoints]; |
||||||
|
|
||||||
|
final double sqrtTwoTimesLastNumPoints = FastMath.sqrt(2 * lastNumPoints); |
||||||
|
final double sqrtTwoTimesNumPoints = FastMath.sqrt(2 * numberOfPoints); |
||||||
|
|
||||||
|
// Find i-th root of H[n+1] by bracketing.
|
||||||
|
final int iMax = numberOfPoints / 2; |
||||||
|
for (int i = 0; i < iMax; i++) { |
||||||
|
// Lower-bound of the interval.
|
||||||
|
double a = (i == 0) ? -sqrtTwoTimesLastNumPoints : previousPoints[i - 1].doubleValue(); |
||||||
|
// Upper-bound of the interval.
|
||||||
|
double b = (iMax == 1) ? -0.5 : previousPoints[i].doubleValue(); |
||||||
|
|
||||||
|
// H[j-1](a)
|
||||||
|
double hma = H0; |
||||||
|
// H[j](a)
|
||||||
|
double ha = H1 * a; |
||||||
|
// H[j-1](b)
|
||||||
|
double hmb = H0; |
||||||
|
// H[j](b)
|
||||||
|
double hb = H1 * b; |
||||||
|
for (int j = 1; j < numberOfPoints; j++) { |
||||||
|
// Compute H[j+1](a) and H[j+1](b)
|
||||||
|
final double jp1 = j + 1; |
||||||
|
final double s = FastMath.sqrt(2 / jp1); |
||||||
|
final double sm = FastMath.sqrt(j / jp1); |
||||||
|
final double hpa = s * a * ha - sm * hma; |
||||||
|
final double hpb = s * b * hb - sm * hmb; |
||||||
|
hma = ha; |
||||||
|
ha = hpa; |
||||||
|
hmb = hb; |
||||||
|
hb = hpb; |
||||||
|
} |
||||||
|
|
||||||
|
// Now ha = H[n+1](a), and hma = H[n](a) (same holds for b).
|
||||||
|
// Middle of the interval.
|
||||||
|
double c = 0.5 * (a + b); |
||||||
|
// P[j-1](c)
|
||||||
|
double hmc = H0; |
||||||
|
// P[j](c)
|
||||||
|
double hc = H1 * c; |
||||||
|
boolean done = false; |
||||||
|
while (!done) { |
||||||
|
done = b - a <= Math.ulp(c); |
||||||
|
hmc = H0; |
||||||
|
hc = H1 * c; |
||||||
|
for (int j = 1; j < numberOfPoints; j++) { |
||||||
|
// Compute H[j+1](c)
|
||||||
|
final double jp1 = j + 1; |
||||||
|
final double s = FastMath.sqrt(2 / jp1); |
||||||
|
final double sm = FastMath.sqrt(j / jp1); |
||||||
|
final double hpc = s * c * hc - sm * hmc; |
||||||
|
hmc = hc; |
||||||
|
hc = hpc; |
||||||
|
} |
||||||
|
// Now h = H[n+1](c) and hm = H[n](c).
|
||||||
|
if (!done) { |
||||||
|
if (ha * hc < 0) { |
||||||
|
b = c; |
||||||
|
hmb = hmc; |
||||||
|
hb = hc; |
||||||
|
} else { |
||||||
|
a = c; |
||||||
|
hma = hmc; |
||||||
|
ha = hc; |
||||||
|
} |
||||||
|
c = 0.5 * (a + b); |
||||||
|
} |
||||||
|
} |
||||||
|
final double d = sqrtTwoTimesNumPoints * hmc; |
||||||
|
final double w = 2 / (d * d); |
||||||
|
|
||||||
|
points[i] = c; |
||||||
|
weights[i] = w; |
||||||
|
|
||||||
|
final int idx = lastNumPoints - i; |
||||||
|
points[idx] = -c; |
||||||
|
weights[idx] = w; |
||||||
|
} |
||||||
|
|
||||||
|
// If "numberOfPoints" is odd, 0 is a root.
|
||||||
|
// Note: as written, the test for oddness will work for negative
|
||||||
|
// integers too (although it is not necessary here), preventing
|
||||||
|
// a FindBugs warning.
|
||||||
|
if (numberOfPoints % 2 != 0) { |
||||||
|
double hm = H0; |
||||||
|
for (int j = 1; j < numberOfPoints; j += 2) { |
||||||
|
final double jp1 = j + 1; |
||||||
|
hm = -FastMath.sqrt(j / jp1) * hm; |
||||||
|
} |
||||||
|
final double d = sqrtTwoTimesNumPoints * hm; |
||||||
|
final double w = 2 / (d * d); |
||||||
|
|
||||||
|
points[iMax] = 0d; |
||||||
|
weights[iMax] = w; |
||||||
|
} |
||||||
|
|
||||||
|
return new Pair<Double[], Double[]>(points, weights); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,215 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.math.MathContext; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Pair; |
||||||
|
|
||||||
|
/** |
||||||
|
* Factory that creates Gauss-type quadrature rule using Legendre polynomials. |
||||||
|
* In this implementation, the lower and upper bounds of the natural interval |
||||||
|
* of integration are -1 and 1, respectively. |
||||||
|
* The Legendre polynomials are evaluated using the recurrence relation |
||||||
|
* presented in <a href="http://en.wikipedia.org/wiki/Abramowitz_and_Stegun"> |
||||||
|
* Abramowitz and Stegun, 1964</a>. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class LegendreHighPrecisionRuleFactory extends BaseRuleFactory<BigDecimal> { |
||||||
|
/** Settings for enhanced precision computations. */ |
||||||
|
private final MathContext mContext; |
||||||
|
/** The number {@code 2}. */ |
||||||
|
private final BigDecimal two; |
||||||
|
/** The number {@code -1}. */ |
||||||
|
private final BigDecimal minusOne; |
||||||
|
/** The number {@code 0.5}. */ |
||||||
|
private final BigDecimal oneHalf; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default precision is {@link MathContext#DECIMAL128 DECIMAL128}. |
||||||
|
*/ |
||||||
|
public LegendreHighPrecisionRuleFactory() { |
||||||
|
this(MathContext.DECIMAL128); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param mContext Precision setting for computing the quadrature rules. |
||||||
|
*/ |
||||||
|
public LegendreHighPrecisionRuleFactory(MathContext mContext) { |
||||||
|
this.mContext = mContext; |
||||||
|
two = new BigDecimal("2", mContext); |
||||||
|
minusOne = new BigDecimal("-1", mContext); |
||||||
|
oneHalf = new BigDecimal("0.5", mContext); |
||||||
|
} |
||||||
|
|
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected Pair<BigDecimal[], BigDecimal[]> computeRule(int numberOfPoints) |
||||||
|
throws DimensionMismatchException { |
||||||
|
|
||||||
|
if (numberOfPoints == 1) { |
||||||
|
// Break recursion.
|
||||||
|
return new Pair<BigDecimal[], BigDecimal[]>(new BigDecimal[] { BigDecimal.ZERO }, |
||||||
|
new BigDecimal[] { two }); |
||||||
|
} |
||||||
|
|
||||||
|
// Get previous rule.
|
||||||
|
// If it has not been computed yet it will trigger a recursive call
|
||||||
|
// to this method.
|
||||||
|
final BigDecimal[] previousPoints = getRuleInternal(numberOfPoints - 1).getFirst(); |
||||||
|
|
||||||
|
// Compute next rule.
|
||||||
|
final BigDecimal[] points = new BigDecimal[numberOfPoints]; |
||||||
|
final BigDecimal[] weights = new BigDecimal[numberOfPoints]; |
||||||
|
|
||||||
|
// Find i-th root of P[n+1] by bracketing.
|
||||||
|
final int iMax = numberOfPoints / 2; |
||||||
|
for (int i = 0; i < iMax; i++) { |
||||||
|
// Lower-bound of the interval.
|
||||||
|
BigDecimal a = (i == 0) ? minusOne : previousPoints[i - 1]; |
||||||
|
// Upper-bound of the interval.
|
||||||
|
BigDecimal b = (iMax == 1) ? BigDecimal.ONE : previousPoints[i]; |
||||||
|
// P[j-1](a)
|
||||||
|
BigDecimal pma = BigDecimal.ONE; |
||||||
|
// P[j](a)
|
||||||
|
BigDecimal pa = a; |
||||||
|
// P[j-1](b)
|
||||||
|
BigDecimal pmb = BigDecimal.ONE; |
||||||
|
// P[j](b)
|
||||||
|
BigDecimal pb = b; |
||||||
|
for (int j = 1; j < numberOfPoints; j++) { |
||||||
|
final BigDecimal b_two_j_p_1 = new BigDecimal(2 * j + 1, mContext); |
||||||
|
final BigDecimal b_j = new BigDecimal(j, mContext); |
||||||
|
final BigDecimal b_j_p_1 = new BigDecimal(j + 1, mContext); |
||||||
|
|
||||||
|
// Compute P[j+1](a)
|
||||||
|
// ppa = ((2 * j + 1) * a * pa - j * pma) / (j + 1);
|
||||||
|
|
||||||
|
BigDecimal tmp1 = a.multiply(b_two_j_p_1, mContext); |
||||||
|
tmp1 = pa.multiply(tmp1, mContext); |
||||||
|
BigDecimal tmp2 = pma.multiply(b_j, mContext); |
||||||
|
// P[j+1](a)
|
||||||
|
BigDecimal ppa = tmp1.subtract(tmp2, mContext); |
||||||
|
ppa = ppa.divide(b_j_p_1, mContext); |
||||||
|
|
||||||
|
// Compute P[j+1](b)
|
||||||
|
// ppb = ((2 * j + 1) * b * pb - j * pmb) / (j + 1);
|
||||||
|
|
||||||
|
tmp1 = b.multiply(b_two_j_p_1, mContext); |
||||||
|
tmp1 = pb.multiply(tmp1, mContext); |
||||||
|
tmp2 = pmb.multiply(b_j, mContext); |
||||||
|
// P[j+1](b)
|
||||||
|
BigDecimal ppb = tmp1.subtract(tmp2, mContext); |
||||||
|
ppb = ppb.divide(b_j_p_1, mContext); |
||||||
|
|
||||||
|
pma = pa; |
||||||
|
pa = ppa; |
||||||
|
pmb = pb; |
||||||
|
pb = ppb; |
||||||
|
} |
||||||
|
// Now pa = P[n+1](a), and pma = P[n](a). Same holds for b.
|
||||||
|
// Middle of the interval.
|
||||||
|
BigDecimal c = a.add(b, mContext).multiply(oneHalf, mContext); |
||||||
|
// P[j-1](c)
|
||||||
|
BigDecimal pmc = BigDecimal.ONE; |
||||||
|
// P[j](c)
|
||||||
|
BigDecimal pc = c; |
||||||
|
boolean done = false; |
||||||
|
while (!done) { |
||||||
|
BigDecimal tmp1 = b.subtract(a, mContext); |
||||||
|
BigDecimal tmp2 = c.ulp().multiply(BigDecimal.TEN, mContext); |
||||||
|
done = tmp1.compareTo(tmp2) <= 0; |
||||||
|
pmc = BigDecimal.ONE; |
||||||
|
pc = c; |
||||||
|
for (int j = 1; j < numberOfPoints; j++) { |
||||||
|
final BigDecimal b_two_j_p_1 = new BigDecimal(2 * j + 1, mContext); |
||||||
|
final BigDecimal b_j = new BigDecimal(j, mContext); |
||||||
|
final BigDecimal b_j_p_1 = new BigDecimal(j + 1, mContext); |
||||||
|
|
||||||
|
// Compute P[j+1](c)
|
||||||
|
tmp1 = c.multiply(b_two_j_p_1, mContext); |
||||||
|
tmp1 = pc.multiply(tmp1, mContext); |
||||||
|
tmp2 = pmc.multiply(b_j, mContext); |
||||||
|
// P[j+1](c)
|
||||||
|
BigDecimal ppc = tmp1.subtract(tmp2, mContext); |
||||||
|
ppc = ppc.divide(b_j_p_1, mContext); |
||||||
|
|
||||||
|
pmc = pc; |
||||||
|
pc = ppc; |
||||||
|
} |
||||||
|
// Now pc = P[n+1](c) and pmc = P[n](c).
|
||||||
|
if (!done) { |
||||||
|
if (pa.signum() * pc.signum() <= 0) { |
||||||
|
b = c; |
||||||
|
pmb = pmc; |
||||||
|
pb = pc; |
||||||
|
} else { |
||||||
|
a = c; |
||||||
|
pma = pmc; |
||||||
|
pa = pc; |
||||||
|
} |
||||||
|
c = a.add(b, mContext).multiply(oneHalf, mContext); |
||||||
|
} |
||||||
|
} |
||||||
|
final BigDecimal nP = new BigDecimal(numberOfPoints, mContext); |
||||||
|
BigDecimal tmp1 = pmc.subtract(c.multiply(pc, mContext), mContext); |
||||||
|
tmp1 = tmp1.multiply(nP); |
||||||
|
tmp1 = tmp1.pow(2, mContext); |
||||||
|
BigDecimal tmp2 = c.pow(2, mContext); |
||||||
|
tmp2 = BigDecimal.ONE.subtract(tmp2, mContext); |
||||||
|
tmp2 = tmp2.multiply(two, mContext); |
||||||
|
tmp2 = tmp2.divide(tmp1, mContext); |
||||||
|
|
||||||
|
points[i] = c; |
||||||
|
weights[i] = tmp2; |
||||||
|
|
||||||
|
final int idx = numberOfPoints - i - 1; |
||||||
|
points[idx] = c.negate(mContext); |
||||||
|
weights[idx] = tmp2; |
||||||
|
} |
||||||
|
// If "numberOfPoints" is odd, 0 is a root.
|
||||||
|
// Note: as written, the test for oddness will work for negative
|
||||||
|
// integers too (although it is not necessary here), preventing
|
||||||
|
// a FindBugs warning.
|
||||||
|
if (numberOfPoints % 2 != 0) { |
||||||
|
BigDecimal pmc = BigDecimal.ONE; |
||||||
|
for (int j = 1; j < numberOfPoints; j += 2) { |
||||||
|
final BigDecimal b_j = new BigDecimal(j, mContext); |
||||||
|
final BigDecimal b_j_p_1 = new BigDecimal(j + 1, mContext); |
||||||
|
|
||||||
|
// pmc = -j * pmc / (j + 1);
|
||||||
|
pmc = pmc.multiply(b_j, mContext); |
||||||
|
pmc = pmc.divide(b_j_p_1, mContext); |
||||||
|
pmc = pmc.negate(mContext); |
||||||
|
} |
||||||
|
|
||||||
|
// 2 / pow(numberOfPoints * pmc, 2);
|
||||||
|
final BigDecimal nP = new BigDecimal(numberOfPoints, mContext); |
||||||
|
BigDecimal tmp1 = pmc.multiply(nP, mContext); |
||||||
|
tmp1 = tmp1.pow(2, mContext); |
||||||
|
BigDecimal tmp2 = two.divide(tmp1, mContext); |
||||||
|
|
||||||
|
points[iMax] = BigDecimal.ZERO; |
||||||
|
weights[iMax] = tmp2; |
||||||
|
} |
||||||
|
|
||||||
|
return new Pair<BigDecimal[], BigDecimal[]>(points, weights); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,140 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Pair; |
||||||
|
|
||||||
|
/** |
||||||
|
* Factory that creates Gauss-type quadrature rule using Legendre polynomials. |
||||||
|
* In this implementation, the lower and upper bounds of the natural interval |
||||||
|
* of integration are -1 and 1, respectively. |
||||||
|
* The Legendre polynomials are evaluated using the recurrence relation |
||||||
|
* presented in <a href="http://en.wikipedia.org/wiki/Abramowitz_and_Stegun"> |
||||||
|
* Abramowitz and Stegun, 1964</a>. |
||||||
|
* |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class LegendreRuleFactory extends BaseRuleFactory<Double> { |
||||||
|
/** {@inheritDoc} */ |
||||||
|
@Override |
||||||
|
protected Pair<Double[], Double[]> computeRule(int numberOfPoints) |
||||||
|
throws DimensionMismatchException { |
||||||
|
|
||||||
|
if (numberOfPoints == 1) { |
||||||
|
// Break recursion.
|
||||||
|
return new Pair<Double[], Double[]>(new Double[] { 0d }, |
||||||
|
new Double[] { 2d }); |
||||||
|
} |
||||||
|
|
||||||
|
// Get previous rule.
|
||||||
|
// If it has not been computed yet it will trigger a recursive call
|
||||||
|
// to this method.
|
||||||
|
final Double[] previousPoints = getRuleInternal(numberOfPoints - 1).getFirst(); |
||||||
|
|
||||||
|
// Compute next rule.
|
||||||
|
final Double[] points = new Double[numberOfPoints]; |
||||||
|
final Double[] weights = new Double[numberOfPoints]; |
||||||
|
|
||||||
|
// Find i-th root of P[n+1] by bracketing.
|
||||||
|
final int iMax = numberOfPoints / 2; |
||||||
|
for (int i = 0; i < iMax; i++) { |
||||||
|
// Lower-bound of the interval.
|
||||||
|
double a = (i == 0) ? -1 : previousPoints[i - 1].doubleValue(); |
||||||
|
// Upper-bound of the interval.
|
||||||
|
double b = (iMax == 1) ? 1 : previousPoints[i].doubleValue(); |
||||||
|
// P[j-1](a)
|
||||||
|
double pma = 1; |
||||||
|
// P[j](a)
|
||||||
|
double pa = a; |
||||||
|
// P[j-1](b)
|
||||||
|
double pmb = 1; |
||||||
|
// P[j](b)
|
||||||
|
double pb = b; |
||||||
|
for (int j = 1; j < numberOfPoints; j++) { |
||||||
|
final int two_j_p_1 = 2 * j + 1; |
||||||
|
final int j_p_1 = j + 1; |
||||||
|
// P[j+1](a)
|
||||||
|
final double ppa = (two_j_p_1 * a * pa - j * pma) / j_p_1; |
||||||
|
// P[j+1](b)
|
||||||
|
final double ppb = (two_j_p_1 * b * pb - j * pmb) / j_p_1; |
||||||
|
pma = pa; |
||||||
|
pa = ppa; |
||||||
|
pmb = pb; |
||||||
|
pb = ppb; |
||||||
|
} |
||||||
|
// Now pa = P[n+1](a), and pma = P[n](a) (same holds for b).
|
||||||
|
// Middle of the interval.
|
||||||
|
double c = 0.5 * (a + b); |
||||||
|
// P[j-1](c)
|
||||||
|
double pmc = 1; |
||||||
|
// P[j](c)
|
||||||
|
double pc = c; |
||||||
|
boolean done = false; |
||||||
|
while (!done) { |
||||||
|
done = b - a <= Math.ulp(c); |
||||||
|
pmc = 1; |
||||||
|
pc = c; |
||||||
|
for (int j = 1; j < numberOfPoints; j++) { |
||||||
|
// P[j+1](c)
|
||||||
|
final double ppc = ((2 * j + 1) * c * pc - j * pmc) / (j + 1); |
||||||
|
pmc = pc; |
||||||
|
pc = ppc; |
||||||
|
} |
||||||
|
// Now pc = P[n+1](c) and pmc = P[n](c).
|
||||||
|
if (!done) { |
||||||
|
if (pa * pc <= 0) { |
||||||
|
b = c; |
||||||
|
pmb = pmc; |
||||||
|
pb = pc; |
||||||
|
} else { |
||||||
|
a = c; |
||||||
|
pma = pmc; |
||||||
|
pa = pc; |
||||||
|
} |
||||||
|
c = 0.5 * (a + b); |
||||||
|
} |
||||||
|
} |
||||||
|
final double d = numberOfPoints * (pmc - c * pc); |
||||||
|
final double w = 2 * (1 - c * c) / (d * d); |
||||||
|
|
||||||
|
points[i] = c; |
||||||
|
weights[i] = w; |
||||||
|
|
||||||
|
final int idx = numberOfPoints - i - 1; |
||||||
|
points[idx] = -c; |
||||||
|
weights[idx] = w; |
||||||
|
} |
||||||
|
// If "numberOfPoints" is odd, 0 is a root.
|
||||||
|
// Note: as written, the test for oddness will work for negative
|
||||||
|
// integers too (although it is not necessary here), preventing
|
||||||
|
// a FindBugs warning.
|
||||||
|
if (numberOfPoints % 2 != 0) { |
||||||
|
double pmc = 1; |
||||||
|
for (int j = 1; j < numberOfPoints; j += 2) { |
||||||
|
pmc = -j * pmc / (j + 1); |
||||||
|
} |
||||||
|
final double d = numberOfPoints * pmc; |
||||||
|
final double w = 2 / (d * d); |
||||||
|
|
||||||
|
points[iMax] = 0d; |
||||||
|
weights[iMax] = w; |
||||||
|
} |
||||||
|
|
||||||
|
return new Pair<Double[], Double[]>(points, weights); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NonMonotonicSequenceException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.UnivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Pair; |
||||||
|
|
||||||
|
/** |
||||||
|
* This class's implements {@link #integrate(UnivariateFunction) integrate} |
||||||
|
* method assuming that the integral is symmetric about 0. |
||||||
|
* This allows to reduce numerical errors. |
||||||
|
* |
||||||
|
* @since 3.3 |
||||||
|
*/ |
||||||
|
public class SymmetricGaussIntegrator extends GaussIntegrator { |
||||||
|
/** |
||||||
|
* Creates an integrator from the given {@code points} and {@code weights}. |
||||||
|
* The integration interval is defined by the first and last value of |
||||||
|
* {@code points} which must be sorted in increasing order. |
||||||
|
* |
||||||
|
* @param points Integration points. |
||||||
|
* @param weights Weights of the corresponding integration nodes. |
||||||
|
* @throws NonMonotonicSequenceException if the {@code points} are not |
||||||
|
* sorted in increasing order. |
||||||
|
* @throws DimensionMismatchException if points and weights don't have the same length |
||||||
|
*/ |
||||||
|
public SymmetricGaussIntegrator(double[] points, |
||||||
|
double[] weights) |
||||||
|
throws NonMonotonicSequenceException, DimensionMismatchException { |
||||||
|
super(points, weights); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates an integrator from the given pair of points (first element of |
||||||
|
* the pair) and weights (second element of the pair. |
||||||
|
* |
||||||
|
* @param pointsAndWeights Integration points and corresponding weights. |
||||||
|
* @throws NonMonotonicSequenceException if the {@code points} are not |
||||||
|
* sorted in increasing order. |
||||||
|
* |
||||||
|
* @see #SymmetricGaussIntegrator(double[], double[]) |
||||||
|
*/ |
||||||
|
public SymmetricGaussIntegrator(Pair<double[], double[]> pointsAndWeights) |
||||||
|
throws NonMonotonicSequenceException { |
||||||
|
this(pointsAndWeights.getFirst(), pointsAndWeights.getSecond()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritDoc} |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public double integrate(UnivariateFunction f) { |
||||||
|
final int ruleLength = getNumberOfPoints(); |
||||||
|
|
||||||
|
if (ruleLength == 1) { |
||||||
|
return getWeight(0) * f.value(0d); |
||||||
|
} |
||||||
|
|
||||||
|
final int iMax = ruleLength / 2; |
||||||
|
double s = 0; |
||||||
|
double c = 0; |
||||||
|
for (int i = 0; i < iMax; i++) { |
||||||
|
final double p = getPoint(i); |
||||||
|
final double w = getWeight(i); |
||||||
|
|
||||||
|
final double f1 = f.value(p); |
||||||
|
final double f2 = f.value(-p); |
||||||
|
|
||||||
|
final double y = w * (f1 + f2) - c; |
||||||
|
final double t = s + y; |
||||||
|
|
||||||
|
c = (t - s) - y; |
||||||
|
s = t; |
||||||
|
} |
||||||
|
|
||||||
|
if (ruleLength % 2 != 0) { |
||||||
|
final double w = getWeight(iMax); |
||||||
|
|
||||||
|
final double y = w * f.value(0d) - c; |
||||||
|
final double t = s + y; |
||||||
|
|
||||||
|
s = t; |
||||||
|
} |
||||||
|
|
||||||
|
return s; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
/** |
||||||
|
* |
||||||
|
* Gauss family of quadrature schemes. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.fr.third.org.apache.commons.math3.analysis.integration.gauss; |
@ -0,0 +1,22 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
/** |
||||||
|
* |
||||||
|
* Numerical integration (quadrature) algorithms for univariate real functions. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.fr.third.org.apache.commons.math3.analysis.integration; |
@ -0,0 +1,215 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.interpolation; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NonMonotonicSequenceException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NullArgumentException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NumberIsTooSmallException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.util.LocalizedFormats; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.polynomials.PolynomialFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.FastMath; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.MathArrays; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.Precision; |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes a cubic spline interpolation for the data set using the Akima |
||||||
|
* algorithm, as originally formulated by Hiroshi Akima in his 1970 paper |
||||||
|
* "A New Method of Interpolation and Smooth Curve Fitting Based on Local Procedures." |
||||||
|
* J. ACM 17, 4 (October 1970), 589-602. DOI=10.1145/321607.321609 |
||||||
|
* http://doi.acm.org/10.1145/321607.321609
|
||||||
|
* <p> |
||||||
|
* This implementation is based on the Akima implementation in the CubicSpline |
||||||
|
* class in the Math.NET Numerics library. The method referenced is |
||||||
|
* CubicSpline.InterpolateAkimaSorted |
||||||
|
* </p> |
||||||
|
* <p> |
||||||
|
* The {@link #interpolate(double[], double[]) interpolate} method returns a |
||||||
|
* {@link PolynomialSplineFunction} consisting of n cubic polynomials, defined |
||||||
|
* over the subintervals determined by the x values, {@code x[0] < x[i] ... < x[n]}. |
||||||
|
* The Akima algorithm requires that {@code n >= 5}. |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
public class AkimaSplineInterpolator |
||||||
|
implements UnivariateInterpolator { |
||||||
|
/** The minimum number of points that are needed to compute the function. */ |
||||||
|
private static final int MINIMUM_NUMBER_POINTS = 5; |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes an interpolating function for the data set. |
||||||
|
* |
||||||
|
* @param xvals the arguments for the interpolation points |
||||||
|
* @param yvals the values for the interpolation points |
||||||
|
* @return a function which interpolates the data set |
||||||
|
* @throws DimensionMismatchException if {@code xvals} and {@code yvals} have |
||||||
|
* different sizes. |
||||||
|
* @throws NonMonotonicSequenceException if {@code xvals} is not sorted in |
||||||
|
* strict increasing order. |
||||||
|
* @throws NumberIsTooSmallException if the size of {@code xvals} is smaller |
||||||
|
* than 5. |
||||||
|
*/ |
||||||
|
public PolynomialSplineFunction interpolate(double[] xvals, |
||||||
|
double[] yvals) |
||||||
|
throws DimensionMismatchException, |
||||||
|
NumberIsTooSmallException, |
||||||
|
NonMonotonicSequenceException { |
||||||
|
if (xvals == null || |
||||||
|
yvals == null) { |
||||||
|
throw new NullArgumentException(); |
||||||
|
} |
||||||
|
|
||||||
|
if (xvals.length != yvals.length) { |
||||||
|
throw new DimensionMismatchException(xvals.length, yvals.length); |
||||||
|
} |
||||||
|
|
||||||
|
if (xvals.length < MINIMUM_NUMBER_POINTS) { |
||||||
|
throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS, |
||||||
|
xvals.length, |
||||||
|
MINIMUM_NUMBER_POINTS, true); |
||||||
|
} |
||||||
|
|
||||||
|
MathArrays.checkOrder(xvals); |
||||||
|
|
||||||
|
final int numberOfDiffAndWeightElements = xvals.length - 1; |
||||||
|
|
||||||
|
final double[] differences = new double[numberOfDiffAndWeightElements]; |
||||||
|
final double[] weights = new double[numberOfDiffAndWeightElements]; |
||||||
|
|
||||||
|
for (int i = 0; i < differences.length; i++) { |
||||||
|
differences[i] = (yvals[i + 1] - yvals[i]) / (xvals[i + 1] - xvals[i]); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 1; i < weights.length; i++) { |
||||||
|
weights[i] = FastMath.abs(differences[i] - differences[i - 1]); |
||||||
|
} |
||||||
|
|
||||||
|
// Prepare Hermite interpolation scheme.
|
||||||
|
final double[] firstDerivatives = new double[xvals.length]; |
||||||
|
|
||||||
|
for (int i = 2; i < firstDerivatives.length - 2; i++) { |
||||||
|
final double wP = weights[i + 1]; |
||||||
|
final double wM = weights[i - 1]; |
||||||
|
if (Precision.equals(wP, 0.0) && |
||||||
|
Precision.equals(wM, 0.0)) { |
||||||
|
final double xv = xvals[i]; |
||||||
|
final double xvP = xvals[i + 1]; |
||||||
|
final double xvM = xvals[i - 1]; |
||||||
|
firstDerivatives[i] = (((xvP - xv) * differences[i - 1]) + ((xv - xvM) * differences[i])) / (xvP - xvM); |
||||||
|
} else { |
||||||
|
firstDerivatives[i] = ((wP * differences[i - 1]) + (wM * differences[i])) / (wP + wM); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
firstDerivatives[0] = differentiateThreePoint(xvals, yvals, 0, 0, 1, 2); |
||||||
|
firstDerivatives[1] = differentiateThreePoint(xvals, yvals, 1, 0, 1, 2); |
||||||
|
firstDerivatives[xvals.length - 2] = differentiateThreePoint(xvals, yvals, xvals.length - 2, |
||||||
|
xvals.length - 3, xvals.length - 2, |
||||||
|
xvals.length - 1); |
||||||
|
firstDerivatives[xvals.length - 1] = differentiateThreePoint(xvals, yvals, xvals.length - 1, |
||||||
|
xvals.length - 3, xvals.length - 2, |
||||||
|
xvals.length - 1); |
||||||
|
|
||||||
|
return interpolateHermiteSorted(xvals, yvals, firstDerivatives); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Three point differentiation helper, modeled off of the same method in the |
||||||
|
* Math.NET CubicSpline class. This is used by both the Apache Math and the |
||||||
|
* Math.NET Akima Cubic Spline algorithms |
||||||
|
* |
||||||
|
* @param xvals x values to calculate the numerical derivative with |
||||||
|
* @param yvals y values to calculate the numerical derivative with |
||||||
|
* @param indexOfDifferentiation index of the elemnt we are calculating the derivative around |
||||||
|
* @param indexOfFirstSample index of the first element to sample for the three point method |
||||||
|
* @param indexOfSecondsample index of the second element to sample for the three point method |
||||||
|
* @param indexOfThirdSample index of the third element to sample for the three point method |
||||||
|
* @return the derivative |
||||||
|
*/ |
||||||
|
private double differentiateThreePoint(double[] xvals, double[] yvals, |
||||||
|
int indexOfDifferentiation, |
||||||
|
int indexOfFirstSample, |
||||||
|
int indexOfSecondsample, |
||||||
|
int indexOfThirdSample) { |
||||||
|
final double x0 = yvals[indexOfFirstSample]; |
||||||
|
final double x1 = yvals[indexOfSecondsample]; |
||||||
|
final double x2 = yvals[indexOfThirdSample]; |
||||||
|
|
||||||
|
final double t = xvals[indexOfDifferentiation] - xvals[indexOfFirstSample]; |
||||||
|
final double t1 = xvals[indexOfSecondsample] - xvals[indexOfFirstSample]; |
||||||
|
final double t2 = xvals[indexOfThirdSample] - xvals[indexOfFirstSample]; |
||||||
|
|
||||||
|
final double a = (x2 - x0 - (t2 / t1 * (x1 - x0))) / (t2 * t2 - t1 * t2); |
||||||
|
final double b = (x1 - x0 - a * t1 * t1) / t1; |
||||||
|
|
||||||
|
return (2 * a * t) + b; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a Hermite cubic spline interpolation from the set of (x,y) value |
||||||
|
* pairs and their derivatives. This is modeled off of the |
||||||
|
* InterpolateHermiteSorted method in the Math.NET CubicSpline class. |
||||||
|
* |
||||||
|
* @param xvals x values for interpolation |
||||||
|
* @param yvals y values for interpolation |
||||||
|
* @param firstDerivatives first derivative values of the function |
||||||
|
* @return polynomial that fits the function |
||||||
|
*/ |
||||||
|
private PolynomialSplineFunction interpolateHermiteSorted(double[] xvals, |
||||||
|
double[] yvals, |
||||||
|
double[] firstDerivatives) { |
||||||
|
if (xvals.length != yvals.length) { |
||||||
|
throw new DimensionMismatchException(xvals.length, yvals.length); |
||||||
|
} |
||||||
|
|
||||||
|
if (xvals.length != firstDerivatives.length) { |
||||||
|
throw new DimensionMismatchException(xvals.length, |
||||||
|
firstDerivatives.length); |
||||||
|
} |
||||||
|
|
||||||
|
final int minimumLength = 2; |
||||||
|
if (xvals.length < minimumLength) { |
||||||
|
throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS, |
||||||
|
xvals.length, minimumLength, |
||||||
|
true); |
||||||
|
} |
||||||
|
|
||||||
|
final int size = xvals.length - 1; |
||||||
|
final PolynomialFunction[] polynomials = new PolynomialFunction[size]; |
||||||
|
final double[] coefficients = new double[4]; |
||||||
|
|
||||||
|
for (int i = 0; i < polynomials.length; i++) { |
||||||
|
final double w = xvals[i + 1] - xvals[i]; |
||||||
|
final double w2 = w * w; |
||||||
|
|
||||||
|
final double yv = yvals[i]; |
||||||
|
final double yvP = yvals[i + 1]; |
||||||
|
|
||||||
|
final double fd = firstDerivatives[i]; |
||||||
|
final double fdP = firstDerivatives[i + 1]; |
||||||
|
|
||||||
|
coefficients[0] = yv; |
||||||
|
coefficients[1] = firstDerivatives[i]; |
||||||
|
coefficients[2] = (3 * (yvP - yv) / w - 2 * fd - fdP) / w; |
||||||
|
coefficients[3] = (2 * (yv - yvP) / w + fd + fdP) / w2; |
||||||
|
polynomials[i] = new PolynomialFunction(coefficients); |
||||||
|
} |
||||||
|
|
||||||
|
return new PolynomialSplineFunction(xvals, polynomials); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,326 @@ |
|||||||
|
/* |
||||||
|
* 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 com.fr.third.org.apache.commons.math3.analysis.interpolation; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
import com.fr.third.org.apache.commons.math3.exception.DimensionMismatchException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NoDataException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.NonMonotonicSequenceException; |
||||||
|
import com.fr.third.org.apache.commons.math3.exception.OutOfRangeException; |
||||||
|
import com.fr.third.org.apache.commons.math3.analysis.BivariateFunction; |
||||||
|
import com.fr.third.org.apache.commons.math3.util.MathArrays; |
||||||
|
|
||||||
|
/** |
||||||
|
* Function that implements the |
||||||
|
* <a href="http://en.wikipedia.org/wiki/Bicubic_interpolation"> |
||||||
|
* bicubic spline interpolation</a>. |
||||||
|
* |
||||||
|
* @since 3.4 |
||||||
|
*/ |
||||||
|
public class BicubicInterpolatingFunction |
||||||
|
implements BivariateFunction { |
||||||
|
/** Number of coefficients. */ |
||||||
|
private static final int NUM_COEFF = 16; |
||||||
|
/** |
||||||
|
* Matrix to compute the spline coefficients from the function values |
||||||
|
* and function derivatives values |
||||||
|
*/ |
||||||
|
private static final double[][] AINV = { |
||||||
|
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, |
||||||
|
{ 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }, |
||||||
|
{ -3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0 }, |
||||||
|
{ 2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0 }, |
||||||
|
{ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 }, |
||||||
|
{ 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 }, |
||||||
|
{ 0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0 }, |
||||||
|
{ 0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0 }, |
||||||
|
{ -3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0 }, |
||||||
|
{ 0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0 }, |
||||||
|
{ 9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1 }, |
||||||
|
{ -6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1 }, |
||||||
|
{ 2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0 }, |
||||||
|
{ 0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0 }, |
||||||
|
{ -6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1 }, |
||||||
|
{ 4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1 } |
||||||
|
}; |
||||||
|
|
||||||
|
/** Samples x-coordinates */ |
||||||
|
private final double[] xval; |
||||||
|
/** Samples y-coordinates */ |
||||||
|
private final double[] yval; |
||||||
|
/** Set of cubic splines patching the whole data grid */ |
||||||
|
private final BicubicFunction[][] splines; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param x Sample values of the x-coordinate, in increasing order. |
||||||
|
* @param y Sample values of the y-coordinate, in increasing order. |
||||||
|
* @param f Values of the function on every grid point. |
||||||
|
* @param dFdX Values of the partial derivative of function with respect |
||||||
|
* to x on every grid point. |
||||||
|
* @param dFdY Values of the partial derivative of function with respect |
||||||
|
* to y on every grid point. |
||||||
|
* @param d2FdXdY Values of the cross partial derivative of function on |
||||||
|
* every grid point. |
||||||
|
* @throws DimensionMismatchException if the various arrays do not contain |
||||||
|
* the expected number of elements. |
||||||
|
* @throws NonMonotonicSequenceException if {@code x} or {@code y} are |
||||||
|
* not strictly increasing. |
||||||
|
* @throws NoDataException if any of the arrays has zero length. |
||||||
|
*/ |
||||||
|
public BicubicInterpolatingFunction(double[] x, |
||||||
|
double[] y, |
||||||
|
double[][] f, |
||||||
|
double[][] dFdX, |
||||||
|
double[][] dFdY, |
||||||
|
double[][] d2FdXdY) |
||||||
|
throws DimensionMismatchException, |
||||||
|
NoDataException, |
||||||
|
NonMonotonicSequenceException { |
||||||
|
final int xLen = x.length; |
||||||
|
final int yLen = y.length; |
||||||
|
|
||||||
|
if (xLen == 0 || yLen == 0 || f.length == 0 || f[0].length == 0) { |
||||||
|
throw new NoDataException(); |
||||||
|
} |
||||||
|
if (xLen != f.length) { |
||||||
|
throw new DimensionMismatchException(xLen, f.length); |
||||||
|
} |
||||||
|
if (xLen != dFdX.length) { |
||||||
|
throw new DimensionMismatchException(xLen, dFdX.length); |
||||||
|
} |
||||||
|
if (xLen != dFdY.length) { |
||||||
|
throw new DimensionMismatchException(xLen, dFdY.length); |
||||||
|
} |
||||||
|
if (xLen != d2FdXdY.length) { |
||||||
|
throw new DimensionMismatchException(xLen, d2FdXdY.length); |
||||||
|
} |
||||||
|
|
||||||
|
MathArrays.checkOrder(x); |
||||||
|
MathArrays.checkOrder(y); |
||||||
|
|
||||||
|
xval = x.clone(); |
||||||
|
yval = y.clone(); |
||||||
|
|
||||||
|
final int lastI = xLen - 1; |
||||||
|
final int lastJ = yLen - 1; |
||||||
|
splines = new BicubicFunction[lastI][lastJ]; |
||||||
|
|
||||||
|
for (int i = 0; i < lastI; i++) { |
||||||
|
if (f[i].length != yLen) { |
||||||
|
throw new DimensionMismatchException(f[i].length, yLen); |
||||||
|
} |
||||||
|
if (dFdX[i].length != yLen) { |
||||||
|
throw new DimensionMismatchException(dFdX[i].length, yLen); |
||||||
|
} |
||||||
|
if (dFdY[i].length != yLen) { |
||||||
|
throw new DimensionMismatchException(dFdY[i].length, yLen); |
||||||
|
} |
||||||
|
if (d2FdXdY[i].length != yLen) { |
||||||
|
throw new DimensionMismatchException(d2FdXdY[i].length, yLen); |
||||||
|
} |
||||||
|
final int ip1 = i + 1; |
||||||
|
final double xR = xval[ip1] - xval[i]; |
||||||
|
for (int j = 0; j < lastJ; j++) { |
||||||
|
final int jp1 = j + 1; |
||||||
|
final double yR = yval[jp1] - yval[j]; |
||||||
|
final double xRyR = xR * yR; |
||||||
|
final double[] beta = new double[] { |
||||||
|
f[i][j], f[ip1][j], f[i][jp1], f[ip1][jp1], |
||||||
|
dFdX[i][j] * xR, dFdX[ip1][j] * xR, dFdX[i][jp1] * xR, dFdX[ip1][jp1] * xR, |
||||||
|
dFdY[i][j] * yR, dFdY[ip1][j] * yR, dFdY[i][jp1] * yR, dFdY[ip1][jp1] * yR, |
||||||
|
d2FdXdY[i][j] * xRyR, d2FdXdY[ip1][j] * xRyR, d2FdXdY[i][jp1] * xRyR, d2FdXdY[ip1][jp1] * xRyR |
||||||
|
}; |
||||||
|
|
||||||
|
splines[i][j] = new BicubicFunction(computeSplineCoefficients(beta)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritDoc} |
||||||
|
*/ |
||||||
|
public double value(double x, double y) |
||||||
|
throws OutOfRangeException { |
||||||
|
final int i = searchIndex(x, xval); |
||||||
|
final int j = searchIndex(y, yval); |
||||||
|
|
||||||
|
final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]); |
||||||
|
final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]); |
||||||
|
|
||||||
|
return splines[i][j].value(xN, yN); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Indicates whether a point is within the interpolation range. |
||||||
|
* |
||||||
|
* @param x First coordinate. |
||||||
|
* @param y Second coordinate. |
||||||
|
* @return {@code true} if (x, y) is a valid point. |
||||||
|
*/ |
||||||
|
public boolean isValidPoint(double x, double y) { |
||||||
|
if (x < xval[0] || |
||||||
|
x > xval[xval.length - 1] || |
||||||
|
y < yval[0] || |
||||||
|
y > yval[yval.length - 1]) { |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param c Coordinate. |
||||||
|
* @param val Coordinate samples. |
||||||
|
* @return the index in {@code val} corresponding to the interval |
||||||
|
* containing {@code c}. |
||||||
|
* @throws OutOfRangeException if {@code c} is out of the |
||||||
|
* range defined by the boundary values of {@code val}. |
||||||
|
*/ |
||||||
|
private int searchIndex(double c, double[] val) { |
||||||
|
final int r = Arrays.binarySearch(val, c); |
||||||
|
|
||||||
|
if (r == -1 || |
||||||
|
r == -val.length - 1) { |
||||||
|
throw new OutOfRangeException(c, val[0], val[val.length - 1]); |
||||||
|
} |
||||||
|
|
||||||
|
if (r < 0) { |
||||||
|
// "c" in within an interpolation sub-interval: Return the
|
||||||
|
// index of the sample at the lower end of the sub-interval.
|
||||||
|
return -r - 2; |
||||||
|
} |
||||||
|
final int last = val.length - 1; |
||||||
|
if (r == last) { |
||||||
|
// "c" is the last sample of the range: Return the index
|
||||||
|
// of the sample at the lower end of the last sub-interval.
|
||||||
|
return last - 1; |
||||||
|
} |
||||||
|
|
||||||
|
// "c" is another sample point.
|
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the spline coefficients from the list of function values and |
||||||
|
* function partial derivatives values at the four corners of a grid |
||||||
|
* element. They must be specified in the following order: |
||||||
|
* <ul> |
||||||
|
* <li>f(0,0)</li> |
||||||
|
* <li>f(1,0)</li> |
||||||
|
* <li>f(0,1)</li> |
||||||
|
* <li>f(1,1)</li> |
||||||
|
* <li>f<sub>x</sub>(0,0)</li> |
||||||
|
* <li>f<sub>x</sub>(1,0)</li> |
||||||
|
* <li>f<sub>x</sub>(0,1)</li> |
||||||
|
* <li>f<sub>x</sub>(1,1)</li> |
||||||
|
* <li>f<sub>y</sub>(0,0)</li> |
||||||
|
* <li>f<sub>y</sub>(1,0)</li> |
||||||
|
* <li>f<sub>y</sub>(0,1)</li> |
||||||
|
* <li>f<sub>y</sub>(1,1)</li> |
||||||
|
* <li>f<sub>xy</sub>(0,0)</li> |
||||||
|
* <li>f<sub>xy</sub>(1,0)</li> |
||||||
|
* <li>f<sub>xy</sub>(0,1)</li> |
||||||
|
* <li>f<sub>xy</sub>(1,1)</li> |
||||||
|
* </ul> |
||||||
|
* where the subscripts indicate the partial derivative with respect to |
||||||
|
* the corresponding variable(s). |
||||||
|
* |
||||||
|
* @param beta List of function values and function partial derivatives |
||||||
|
* values. |
||||||
|
* @return the spline coefficients. |
||||||
|
*/ |
||||||
|
private double[] computeSplineCoefficients(double[] beta) { |
||||||
|
final double[] a = new double[NUM_COEFF]; |
||||||
|
|
||||||
|
for (int i = 0; i < NUM_COEFF; i++) { |
||||||
|
double result = 0; |
||||||
|
final double[] row = AINV[i]; |
||||||
|
for (int j = 0; j < NUM_COEFF; j++) { |
||||||
|
result += row[j] * beta[j]; |
||||||
|
} |
||||||
|
a[i] = result; |
||||||
|
} |
||||||
|
|
||||||
|
return a; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Bicubic function. |
||||||
|
*/ |
||||||
|
class BicubicFunction implements BivariateFunction { |
||||||
|
/** Number of points. */ |
||||||
|
private static final short N = 4; |
||||||
|
/** Coefficients */ |
||||||
|
private final double[][] a; |
||||||
|
|
||||||
|
/** |
||||||
|
* Simple constructor. |
||||||
|
* |
||||||
|
* @param coeff Spline coefficients. |
||||||
|
*/ |
||||||
|
BicubicFunction(double[] coeff) { |
||||||
|
a = new double[N][N]; |
||||||
|
for (int j = 0; j < N; j++) { |
||||||
|
final double[] aJ = a[j]; |
||||||
|
for (int i = 0; i < N; i++) { |
||||||
|
aJ[i] = coeff[i * N + j]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritDoc} |
||||||
|
*/ |
||||||
|
public double value(double x, double y) { |
||||||
|
if (x < 0 || x > 1) { |
||||||
|
throw new OutOfRangeException(x, 0, 1); |
||||||
|
} |
||||||
|
if (y < 0 || y > 1) { |
||||||
|
throw new OutOfRangeException(y, 0, 1); |
||||||
|
} |
||||||
|
|
||||||
|
final double x2 = x * x; |
||||||
|
final double x3 = x2 * x; |
||||||
|
final double[] pX = {1, x, x2, x3}; |
||||||
|
|
||||||
|
final double y2 = y * y; |
||||||
|
final double y3 = y2 * y; |
||||||
|
final double[] pY = {1, y, y2, y3}; |
||||||
|
|
||||||
|
return apply(pX, pY, a); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the value of the bicubic polynomial. |
||||||
|
* |
||||||
|
* @param pX Powers of the x-coordinate. |
||||||
|
* @param pY Powers of the y-coordinate. |
||||||
|
* @param coeff Spline coefficients. |
||||||
|
* @return the interpolated value. |
||||||
|
*/ |
||||||
|
private double apply(double[] pX, double[] pY, double[][] coeff) { |
||||||
|
double result = 0; |
||||||
|
for (int i = 0; i < N; i++) { |
||||||
|
final double r = MathArrays.linearCombination(coeff[i], pY); |
||||||
|
result += r * pX[i]; |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue