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 &lt; 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>