------------------------------------------------------------------ lines 5-257 of file: include/cppad/core/forward/forward_order.xrst ------------------------------------------------------------------ {xrst_begin forward_order} {xrst_spell cout dx ostream xk xq yq } Multiple Order Forward Mode ########################### Syntax ****** | *yq* = *f* . ``Forward`` ( *q* , *xq* ) | *yq* = *f* . ``Forward`` ( *q* , *xq* , *s* ) Purpose ******* We use :math:`F : \B{R}^n \rightarrow \B{R}^m` to denote the :ref:`glossary@AD Function` corresponding to *f* . Given a function :math:`X : \B{R} \rightarrow \B{R}^n`, defined by its :ref:`Taylor coefficients` , forward mode computes the Taylor coefficients for the function .. math:: Y (t) = F [ X(t) ] Function Values =============== If you are using forward mode to compute values for :math:`F(x)`, :ref:`forward_zero-name` is simpler to understand than this explanation of the general case. Derivative Values ================= If you are using forward mode to compute values for :math:`F^{(1)} (x) * dx`, :ref:`forward_one-name` is simpler to understand than this explanation of the general case. Notation ******** n = We use *n* to denote the dimension of the :ref:`fun_property@Domain` space for *f* . m = We use *m* to denote the dimension of the :ref:`fun_property@Range` space for *f* . f * The :ref:`ADFun-name` object *f* has prototype ``ADFun`` < *Base* > *f* Note that the :ref:`ADFun-name` object *f* is not ``const`` . After this call we will have | |tab| *f* . ``size_order`` () == *q* + 1 | |tab| *f* . ``size_direction`` () == 1 One Order ********* If *xq* . ``size`` () == *n* , then we are only computing one order. In this case, before this call we must have | |tab| *f* . ``size_order`` () >= *q* | |tab| *f* . ``size_direction`` () == 1 q * The argument *q* has prototype ``size_t`` *q* and specifies the highest order of the Taylor coefficients to be calculated. xq ** The argument *xq* has prototype ``const`` *BaseVector* & *xq* (see :ref:`forward_order@BaseVector` below). As above, we use *n* to denote the dimension of the :ref:`fun_property@Domain` space for *f* . The size of *xq* must be either *n* or *n* * ( *q* +1) . After this call we will have *f* . ``size_order`` () == *q* + 1 One Order ========= If *xq* . ``size`` () == *n* , the *q*-th order Taylor coefficient for :math:`X(t)` is defined by |tab| :math:`x^{(q)} =` *xq* . For :math:`k = 0 , \ldots , q-1`, the Taylor coefficient :math:`x^{(k)}` is defined by *xk* in the previous call to *f* . ``Forward`` ( *k* , *xk* ) Multiple Orders =============== If *xq* . ``size`` () == *n* * ( *q* +1) , For :math:`k = 0 , \ldots , q`, :math:`j = 0 , \ldots , n-1`, the *j*-th component of the *k*-th order Taylor coefficient for :math:`X(t)` is defined by |tab| :math:`x_j^{(k)} =` *xq* [ ( *q* +1) * *j* + *k* ] Restrictions ============ Note if *f* uses :ref:`atomic_one-name` functions, the size of *xq* must be *n* . s * If the argument *s* is not present, ``std::cout`` is used in its place. Otherwise, this argument has prototype ``std::ostream&`` *s* If order zero is begin calculated, *s* specifies where the output corresponding to :ref:`PrintFor-name` will be written. If order zero is not being calculated, *s* is not used X(t) **** The function :math:`X : \B{R} \rightarrow \B{R}^n` is defined using the Taylor coefficients :math:`x^{(k)} \in \B{R}^n`: .. math:: X(t) = x^{(0)} * t^0 + x^{(1)} * t^1 + \cdots + x^{(q)} * t^q Note that for :math:`k = 0 , \ldots , q`, the *k*-th derivative of :math:`X(t)` is related to the Taylor coefficients by the equation .. math:: x^{(k)} = \frac{1}{k !} X^{(k)} (0) Y(t) **** The function :math:`Y : \B{R} \rightarrow \B{R}^m` is defined by :math:`Y(t) = F[ X(t) ]`. We use :math:`y^{(k)} \in \B{R}^m` to denote the *k*-th order Taylor coefficient of :math:`Y(t)`; i.e., .. math:: Y(t) = y^{(0)} * t^0 + y^{(1)} * t^1 + \cdots + y^{(q)} * t^q + o( t^q ) where :math:`o( t^q ) * t^{-q} \rightarrow 0` as :math:`t \rightarrow 0`. Note that :math:`y^{(k)}` is related to the *k*-th derivative of :math:`Y(t)` by the equation .. math:: y^{(k)} = \frac{1}{k !} Y^{(k)} (0) yq ** The return value *yq* has prototype *BaseVector* *yq* (see :ref:`forward_order@BaseVector` below). One Order ========= If *xq* . ``size`` () == *n* , the vector *yq* has size *m* . The *q*-th order Taylor coefficient for :math:`Y(t)` is returned as *yq* :math:`= y^{(q)}`. Multiple Orders =============== If *xq* . ``size`` () == *n* * ( *q* +1) , the vector *yq* has size *m* * ( *q* +1) . For :math:`k = 0 , \ldots , q`, for :math:`i = 0 , \ldots , m-1`, the *i*-th component of the *k*-th order Taylor coefficient for :math:`Y(t)` is returned as ``yq`` [ ( ``q`` +1) * ``i`` + ``k`` ] :math:`= y_i^{(k)}` BaseVector ********** The type *BaseVector* must be a :ref:`SimpleVector-name` class with :ref:`elements of type` *Base* . The routine :ref:`CheckSimpleVector-name` will generate an error message if this is not the case. Zero Order ********** The case where :math:`q = 0` and *xq* . ``size`` () == *n* , corresponds to the zero order :ref:`forward_zero@Special Case` . First Order *********** The case where :math:`q = 1` and *xq* . ``size`` () == *n* , corresponds to the first order :ref:`forward_one@Special Case` . Second Order ************ The case where :math:`q = 2` and *xq* . ``size`` () == *n* , corresponds to the second order :ref:`forward_two@Special Case` . {xrst_toc_hidden example/general/forward.cpp example/general/forward_order.cpp } Example ******* The files :ref:`forward.cpp-name` and :ref:`forward_order.cpp-name` contain examples and tests of using forward mode with one order and multiple orders respectively. They return true if they succeed and false otherwise. {xrst_end forward_order}