You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/09/28 18:46:25 UTC
svn commit: r1391550 - in /commons/sandbox/nabla/trunk/src/site/xdoc:
index.xml usage.xml
Author: luc
Date: Fri Sep 28 16:46:24 2012
New Revision: 1391550
URL: http://svn.apache.org/viewvc?rev=1391550&view=rev
Log:
Updated doc.
Modified:
commons/sandbox/nabla/trunk/src/site/xdoc/index.xml
commons/sandbox/nabla/trunk/src/site/xdoc/usage.xml
Modified: commons/sandbox/nabla/trunk/src/site/xdoc/index.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/site/xdoc/index.xml?rev=1391550&r1=1391549&r2=1391550&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/site/xdoc/index.xml (original)
+++ commons/sandbox/nabla/trunk/src/site/xdoc/index.xml Fri Sep 28 16:46:24 2012
@@ -33,9 +33,9 @@
Just like the mathematical Nabla operator transforms a
function into its differential, the Nabla library transforms
an existing java object implementing a function
- <pre><code>double f(double) { ... }</code></pre>
+ <pre><code>double value(double) { ... }</code></pre>
into another java object that in addition to computing the
- value of <code>f</code> like the original one also computes
+ value of <code>value</code> like the original one also computes
its derivative. The created object is built by applying the
classical exact differentiation rules to the function
underlying expressions. There are <em>no</em> approximations
@@ -59,6 +59,16 @@
differentiation can be computed even at domains boundaries
</li>
<li>
+ differentiation is not limited to first order, it is
+ possible to compute second, third or higher order derivatives
+ </li>
+ <li>
+ bottleneck cases like f(atan2(y,x)) where f is a univariate
+ function, but the complete expression is really a bivariate
+ function are handled properly and allow to compute cross
+ derivatives like d<sup>3</sup>f/dx<sup>2</sup>dy
+ </li>
+ <li>
there is no special handling of source:
<ul>
<li>no symbolic package with its own language</li>
@@ -125,8 +135,8 @@
function <code>f(t)</code>:
</p>
<source>
- UnivariateDifferentiable function = new UnivariateDifferentiable() {
- public double f(double t) {
+ UnivariateFunction function = new UnivariateFunction() {
+ public double value(double t) {
return (6 - t) / 3 + Math.cos(4 * t - 4) * Math.exp(-0.9 * t);
}
};
@@ -138,41 +148,41 @@
</p>
<source>
- UnivariateDifferentiator differentiator = new ForwardAlgorithmicDifferentiator();
- final UnivariateDerivative derivative = differentiator.differentiate(function);
+ UnivariateFunctionDifferentiator differentiator = new ForwardModeDifferentiator();
+ final UnivariateDifferentiableFunction derivative = differentiator.differentiate(function);
</source>
<p>
The <code>derivative</code> object implements the <a
- href="apidocs/org/apache/commons/nabla/core/UnivariateDerivative.html">UnivariateDerivative</a>
- interface which means it provides a method <code>f</code> which is an enhanced
- version of the <code>f</code> method of the original <code>function</code> object:
- it computes both the value and the derivative of the function.
+ href="http://commons.apache.org/math/">Apache Commons Math</a> UnivariateDifferentiableFunction
+ interface which means it provides a method <code>value</code> which is an enhanced
+ version of the <code>value</code> method of the original <code>function</code> object:
+ it computes both the value and the partial derivatives of the function.
</p>
<p>
We can therefore find the maximal value by calling a solver on the
derivative. In this example, we will use
- the <a href="http://commons.apache.org/math/apidocs/org/apache/commons/math/analysis/BrentSolver.html">
- Brent solver</a> from the <a href="http://commons.apache.org/math/">commons-math</a>
- library. Functions passed to any commons-math solver must implement a specific
- interface: <a href="http://commons.apache.org/math/apidocs/org/apache/commons/math/analysis/UnivariateRealFunction.html">
- UnivariateRealFunction</a>. In order to comply with this
+ the <a href="http://commons.apache.org/math/apidocs/org/apache/commons/math3/analysis/solvers/BracketingNthOrderBrentSolver.html">
+ bracketings n<sup>th</sup> order Brent solver</a> from the <a href="http://commons.apache.org/math/">Apache
+ Commons Math</a> library. Functions passed to any Apache Commons Math solvers must implement a specific
+ interface: <a href="http://commons.apache.org/math/apidocs/org/apache/commons/math3/analysis/UnivariateFunction.html">
+ UnivariateFunction</a>. In order to comply with this
requirement, we wrap the derivative object into another
object adapting the interface and pass this wrapped
derivative to the solver:
</p>
<source>
- UnivariateRealFunction wrappedDerivative = new UnivariateRealFunction() {
+ UnivariateFunction wrappedDerivative = new UnivariateFunction() {
public double value(double x) {
- DifferentialPair t = DifferentialPair.newVariable(x);
- return derivative.f(t).getFirstDerivative();
+ DerivativeStructure t = new DerivativeStructure(1, 1, 0, x);
+ return derivative.f(t).getPartialDerivative(1);
}
};
- UnivariateRealSolver solver = new BrentSolver(wrappedDerivative);
- double tMax = solver.solve(0.5, 1.5);
- double yMax = derivative.f(DifferentialPair.newVariable(tMax)).getValue();
+ UnivariateSolver solver = new .BracketingNthOrderBrentSolver(5);
+ double tMax = solver.solve(wrappedDerivative, 0.5, 1.5);
+ double yMax = derivative.value(new DerivativeStructure(1, 1, 0, tMax)).getValue();
System.out.println("max value = " + yMax + ", at t = " + tMax +
" (" + solver.getIterationCount() + " iterations)");
</source>
@@ -208,8 +218,8 @@
<source>
for (double t = 0.0; t < 1.0; t += 0.01) {
- DifferentialPair y = derivative.f(DifferentialPair.newVariable(t));
- System.out.println(t + " " + y.getValue() + " " + y.getFirstDerivative());
+ DerivativeStructure y = derivative.value(new DerivativeStructure(1, 1, 0, t));
+ System.out.println(t + " " + y.getValue() + " " + y.getPartialDerivative(1));
}
</source>
@@ -235,8 +245,8 @@
<p>
The main drawback of this approach is that functions that call native
code cannot be handled. For these functions, a fallback method is
- provided that uses finite differences (with 2, 4, 6 or 8
- points schemes). This fallback method does not have the same
+ to uses finite differences using the <a href="http://commons.apache.org/math/">Apache
+ Commons Math</a> library. This fallback method does not have the same
advantages as the previous one: it needs configuration (number
of points and step size), it is not exact, it is more
computation intensive and it cannot be used too close to domain
Modified: commons/sandbox/nabla/trunk/src/site/xdoc/usage.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/site/xdoc/usage.xml?rev=1391550&r1=1391549&r2=1391550&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/site/xdoc/usage.xml (original)
+++ commons/sandbox/nabla/trunk/src/site/xdoc/usage.xml Fri Sep 28 16:46:24 2012
@@ -27,138 +27,128 @@
<subsection name="Public API">
<p>
Nabla public interface is very small, it is composed of only
- three interfaces and two classes.
- <dl>
- <dt><a href="apidocs/org/apache/commons/nabla/core/UnivariateDifferentiable.html">UnivariateDifferentiable</a></dt>
- <dd>is the interface representing the mathematical
- function that should be differentiated. The user-defined
- class are provided to Nabla as classes implementing this
- interface</dd>
- <dt><a href="apidocs/org/apache/commons/nabla/core/UnivariateDerivative.html">UnivariateDerivative</a></dt>
- <dd>is the interface representing the differentiated
- function created by Nabla.</dd>
- <dt><a href="apidocs/org/apache/commons/nabla/core/UnivariateDifferentiator.html">UnivariateDifferentiator</a></dt>
- <dd>is the interface implemented by the various
- differentiators provided by Nabla.</dd>
- <dt><a href="apidocs/org/apache/commons/nabla/core/DifferentialPair.html">DifferentialPair</a></dt>
- <dd>is a simple container holding both a value and a
- derivative. It can be considered simply as an <em>enhanced
- double</em> that is used both as the type of input
- parameters and return value of differentiated
- functions.</dd>
- <dt><a href="apidocs/org/apache/commons/nabla/algorithmic/forward/ForwardAlgorithmicDifferentiator.html">ForwardAlgorithmicDifferentiator</a></dt>
- <dd>is the main implementation of the
- UnivariateDifferentiator interface. It performs
- differentiation by bytecode analysis and generation, using
+ one top level class: <a
+ href="apidocs/org/apache/commons/nabla/forward/ForwardModeDifferentiator.html">ForwardModeDifferentiator</a>
+ </p>
+ <p>
+ This class is an implementation of the <a
+ href="http://commons.apache.org/math/apidocs/org/apache/commons/math3/analysis/differentiation/UnivariateFunctionDifferentiator.html">
+ UnivariateFunctionDifferentiator</a> interface from
+ <a href="http://commons.apache.org/math/">Apache Commons Math</a>. It performs
+ algorithmic differentiation by bytecode analysis and generation, using
the exact differentiation rules in order to create functions
- that compute exact differentials.</dd>
- </dl>
- </p>
+ that compute exact differentials.
+ </p>
- <img src="images/public-API.png" alt="UML class diagram of Nabla public API" />
</subsection>
<subsection name="Differentiating user-defined functions">
<p>
- In order to differentiate a function using Nabla, a
- user-defined function must be provided as an implementation
- of the UnivariateDifferentiable interface. It is passed as
- the single parameter to the <code>differentiate</code>
- method of a ForwardAlgorithmicDifferentiator instance. If the
- existing class does not already implements the
- UnivariateDifferentiable interface, it has to be wrapped
- when provided to the differentiator.
+ In order to differentiate a function using Nabla, a user-defined function must be
+ provided as an implementation of the <a href="http://commons.apache.org/math/">Apache
+ Commons Math</a> <a
+ href="http://commons.apache.org/math/apidocs/org/apache/commons/math3/analysis/UnivariateFunction.html">
+ UnivariateFunction</a> interface. It is passed as the single parameter
+ to the <code>differentiate</code> method of a ForwardModeDifferentiator instance. If the
+ available user class does not already implements the UnivariateFunction interface, it
+ has to be wrapped when provided to the differentiator. The <code>differentiate</code>
+ method will then return an object that implements the <a href="http://commons.apache.org/math/">Apache
+ Commons Math</a> <a
+ href="http://commons.apache.org/math/apidocs/org/apache/commons/math3/analysis/differentiation/UnivariateDifferentialFunction.html">
+ UnivariateDifferentialFunction</a> interface, i.e. the new object is
+ able to compute differentials, even despite the original user object was not able
+ to do so.
</p>
<p>
- As an example, consider the following problem. We have
- a <code>model</code> variable which is an instance of a
- class with a method <code>evaluate</code>:
+ As an example, consider the following problem. We have a <code>model</code> variable
+ which is an instance of a class with a method <code>evaluate</code>:
<pre><code>double evaluate(double first, double second)</code></pre>
- We want to compute its partial derivative with respect to
+ We want to compute its partial derivatives with respect to
the second parameter, when the first parameter value is 2.5
and the second parameter ranges from -1 to +1. Here is a way
to do that:
</p>
<source>
- UnivariateDerivative derivative =
- new ForwardAlgorithmicDifferentiator().differentiate(new UnivariateDifferentiable() {
- public double f(double t) {
+ UnivariateDifferentiableFunction derivative =
+ new ForwardAlgorithmicDifferentiator().differentiate(new UnivariateFunction() {
+ public double value(double t) {
return model.evaluate(2.5, t);
}
});
</source>
- </subsection>
-
- <subsection name="Differential pairs">
<p>
- The derivative instance created by Nabla provides a
- method <code>f</code> which computes both the value of the
- primitive function (as the initial instance does) and the
- value of its first derivative with respect to its input
- parameter. This method has the following signature:
- <pre><code>DifferentialPair f(DifferentialPair t)</code></pre>
+ The <code>derivative</code> object we get can compute the desired derivatives:
</p>
+ <source>
+ int params = 1;
+ int order = 2;
+ double t = 3.4;
+ DerivativeStructure dsT = new DerivativeStructure(params, order, 0, t);
+ DerivativeStructure dsV = derivative.value(dstT);
+ System.out.println("first derivative at t = " + t +
+ " = " + dsV.getPartialDerivative(1));
+ System.out.println("second derivative at t = " + t +
+ " = " + dsV.getPartialDerivative(2));
+ </source>
+ </subsection>
- <p>
- It is important to note this method does not
- use <code>double</code> as its input parameter
- but <code>DifferentialPair</code>. This allows to handle both
- the basic usage when one wants to compute the derivative of
- the <code>f</code> function when its parameter is the
- independent variable, but also more advanced cases when the
- parameter <code>t</code> is not an independent variable.
- </p>
-
- <p>Let's say <code>t</code> is computed by another
- function <code>g</code> from a variable <code>x</code>
- (<code>t = g(x)</code>). The signature of the derivative
- function produced by Nabla allows to chain calls and compute
- the composite derivative. We compute
- first <code>dt/dx</code> from the derivative
- function <code>g'(x)</code>, and then pass the resulting
- differential pair to the derivative
- function <code>f'(t)</code> in order to get the
- result <code>dy/dx</code>.
- </p>
+ <subsection name="Derivative structures">
- <source>
- DifferentialPair dTdX = gDerivative(DifferentialPair.newVariable(2.0));
- DifferentialPair dYdX = fDerivative(dTdX);
- </source>
+ <p>
+ The UnivariateDifferentiableFunction instance created by Nabla provides a
+ method <code>value</code> which computes both the value of the primitive
+ function (as the initial instance does) and the value of its derivatives
+ with respect to its input parameter. This method has the following signature:
+ <pre><code>DerivativeStructure value(DerivativeStructure t)</code></pre>
+ </p>
<p>
- Simple derivatives are computed by passing independent
- variables to the derivative functions. An independent
- variable is represented by a <code>DifferentialPair</code>
- with a first derivative set to 1. Composite derivatives are
- computed by passing dependent variables to the derivative
- functions. A dependent variable is represented by
- a <code>DifferentialPair</code> which has been computed by a
- previous derivative function and which may have any value as
- its first derivative. A constant may be represented by
- a <code>DifferentialPair</code> with a first derivative set
- to 0.
+ It is important to note this method does not use <code>double</code> as its
+ input parameter but <a
+ href="http://commons.apache.org/math/apidocs/org/apache/commons/math3/analysis/differentiation/DerivativeStructure.html">
+ DerivativeStructure</a>, which is a class provided
+ by <a href="http://commons.apache.org/math/">Apache Commons Math</a>.
</p>
<p>
- The <code>DifferentialPair</code> class provides a general
- constructor to build an instance from its value and
- derivative. For convenience, it also provides factory methods
- to build independent variables and constants:
+ It is the <code>DerivativeStructure</code> which specifies the desired derivation
+ order as well as the numbers of free parameters. This allows to manage chaining
+ calls like computing <code>f(atan2(y, x))</code>, where despite f is a univariate
+ function, the expression above really depends on two variables <code>x</code>
+ and <code>y</code>, and we may be interested in second order coupled cross
+ derivatives like d<sup>3</sup>f/dx<sup>2</sup>dy. In this case, the
+ <code>DerivativeStructure</code> argument will contain the information that there
+ are really two variables and we want to compute all derivatives up to order 2.
</p>
<source>
- // value = 1.0, first derivative = 2.0
- DifferentialPair aPair = new DifferentialPair(1.0, 2.0);
-
- // this is equivalent to new DifferentialPair(3.5, 1.0);
- DifferentialPair variable = DifferentialPair.newVariable(3.5);
+ int params = 2;
+ int order = 3;
+ double x = 1.2;
+ double y = 4.5;
+
+ // we arbitrarily specify variable x is variable number 0
+ DerivativeStructure dsX = new DerivativeStructure(params, order, 0, x));
+
+ // we arbitrarily specify variable y is variable number 1
+ DerivativeStructure dsy = new DerivativeStructure(params, order, 1, y));
+
+ // evaluate atan2 value and all its derivatives
+ DerivativeStructure atan2 = DerivativeStructure.atan2(dsY, dsX);
+
+ // perform differentiation
+ UnivariateDifferentiableFunction differentiated =
+ new ForwardModeDifferentiator().differentiate(f);
+
+ // evaluate f value and all its derivatives,
+ // using the automatically generated "value(DerivativeStructure)" method
+ DerivativeStructure fXY = differentiated.value(atan2);
- // this is equivalent to new DifferentialPair(Math.PI, 0.0)
- DifferentialPair constant = DifferentialPair.newConstant(Math.PI);
+ // display output
+ System.out("d3f/dx2dy = " + fXY.getPartialDerivative(3, 2));
</source>
</subsection>
@@ -174,7 +164,7 @@
called. This implies that we end up with two different
instances of two different classes that compute roughly
similar things: the original instance and the newly created
- object. If the implementation of the <code>f</code> method
+ object. If the implementation of the <code>value</code> method
does use some attribute of the original class, then the class
of the newly created object should also provide a way to get
this value.
@@ -189,7 +179,7 @@
if they are stored in private attributes). A direct
implication is that if the state of the original object is
changed <em>after</em> differentiation, all subsequent calls
- to the <code>f</code> method of the already created
+ to the <code>value</code> method of the already created
differentiated instance will reflect these changes in their
behavior. There is no need to bother about updating the
differentiated instance, it is already up-to-date.
@@ -205,7 +195,7 @@
</p>
<source>
- public class SetableFirstParameterModel implements UnivariateDifferentiable {
+ public class SetableFirstParameterModel implements UnivariateFunction {
private Model model;
private double firstParameter;
@@ -219,7 +209,7 @@
this.firstParameter = firstParameter;
}
- public double f(double t) {
+ public double value(double t) {
return model.evaluate(firstParameter, t);
}
@@ -237,15 +227,16 @@
<source>
SetableFirstParameterModel setable = new SetableFirstParameterModel(model, 2.5);
- UnivariateDerivative derivative = new ForwardAlgorithmicDifferentiator().differentiate(setable);
- DifferentialPair t = DifferentialPair.newVariable(2.0);
+ UnivariateDifferentiableFunction derivative =
+ new ForwardAlgorithmicDifferentiator().differentiate(setable);
+ DerivativeStructure t = new DerivativeStructure(1, 1, 0, 2.0);
// derivative with respect to second parameter when first parameter equals 2.5
- double der25 = derivative.f(t).getFirstDerivative();
+ double der25 = derivative.value(t).getPartialDerivative(1);
// derivative with respect to second parameter when first parameter equals 3.0
setable.setFirstParameter(3.0);
- double der30 = derivative.f(t).getFirstDerivative();
+ double der30 = derivative.value(t).getPartialDerivative(1);
</source>
</subsection>
@@ -255,26 +246,19 @@
<p>
Since the algorithmic differentiator can analyze only bytecode,
functions calling native code cannot be handled this way by
- Nabla. There is a fallback procedure using finite differences.
- The <code>numerical</code> package provides several classes
- that implement the <code>UnivariateDifferentiator</code> interface:
- <code><a href="apidocs/org/apache/commons/nabla/numerical/TwoPointsScheme.html">TwoPointsScheme</a></code>,
- <code><a href="apidocs/org/apache/commons/nabla/numerical/FourPointsScheme.html">FourPointsScheme</a></code>,
- <code><a href="apidocs/org/apache/commons/nabla/numerical/SixPointsScheme.html">SixPointsScheme</a></code> and
- <code><a href="apidocs/org/apache/commons/nabla/numerical/EightPointsScheme.html">EightPointsScheme</a></code>.
+ Nabla. In this case, a fallback procedure is to rely on finite differences,
+ using the <a
+ href="http://commons.apache.org/math/apidocs/org/apache/commons/math3/analysis/differentiation/FiniteDifferencesDifferentiator.html">
+ FiniteDifferencesDifferentiator</a> class from
+ <a href="http://commons.apache.org/math/">Apache Commons Math</a>.
</p>
<p>
- These classes need a step size at construction time. For each call
- to the derivative instance <code>f</code> method, they will call the
- <code>f</code> of the primitive instance <code>n+1</code> times where
- <code>n</code> is the number of points of the method. One evaluation
- is at the location defined by the parameter and the <code>n</code>
- other evaluations are regularly distributed around it. So the two points
- method will evaluate the primitive function 3 times at <code>t-h</code>,
- <code>t</code> and <code>t+h</code> while the eight points method will
- evaluate it 9 times at <code>t-4h</code>, <code>t-3h</code> ...
- <code>t+4h</code> where <code>h</code> is the step size.
+ This class need a step size at construction time. For each call
+ to the derivative instance <code>value</code> method, they will call the
+ <code>value</code> of the primitive instance <code>n</code> times where
+ <code>n</code> is the number of points of the method. The evaluations
+ are regularly distributed around the location defined by the parameter.
</p>
<p>