CppAD: A C++ Algorithmic Differentiation Package  20130102
forward.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_FORWARD_INCLUDED
00003 # define CPPAD_FORWARD_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Eclipse Public License Version 1.0.
00011 
00012 A copy of this license is included in the COPYING file of this distribution.
00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00014 -------------------------------------------------------------------------- */
00015 
00016 /*
00017 $begin Forward$$
00018 
00019 $section Forward Mode$$
00020 
00021 $childtable%
00022      omh/forward.omh%
00023      cppad/local/cap_taylor.hpp%
00024      example/forward.cpp
00025 %$$
00026 
00027 $end
00028 -----------------------------------------------------------------------------
00029 */
00030 
00031 // documened after Forward but included here so easy to see
00032 # include <cppad/local/cap_taylor.hpp>
00033 
00034 CPPAD_BEGIN_NAMESPACE
00035 /*!
00036 \defgroup forward_hpp forward.hpp
00037 \{
00038 \file forward.hpp
00039 User interface to forward mode computations
00040 */
00041 
00042 /*!
00043 Compute arbitrary order forward mode Taylor coefficieints.
00044 
00045 \tparam Base
00046 The type used during the forward mode computations; i.e., the corresponding
00047 recording of operations used the type \c AD<Base>.
00048 
00049 \tparam Vector
00050 is a Simple Vector class with eleements of type \c Base.
00051 
00052 \param p
00053 is the order for this forward mode computation; i.e., the number
00054 of Taylor coefficient is <code>p+1</code>.
00055 
00056 \param x_p
00057 Is the \c p th order Taylor coefficient vector for the independent variables.
00058 
00059 \param s
00060 Is the stream where output corresponding to \c PriOp operations will written.
00061 */
00062 
00063 template <typename Base>
00064 template <typename Vector>
00065 Vector ADFun<Base>::Forward(
00066      size_t p                    , 
00067      const Vector& x_p           , 
00068      std::ostream& s             )
00069 {    // temporary indices
00070      size_t i, j;
00071 
00072      // number of independent variables
00073      size_t n = ind_taddr_.size();
00074 
00075      // number of dependent variables
00076      size_t m = dep_taddr_.size();
00077 
00078      // check Vector is Simple Vector class with Base type elements
00079      CheckSimpleVector<Base, Vector>();
00080 
00081      CPPAD_ASSERT_KNOWN(
00082           size_t(x_p.size()) == n,
00083           "Second argument to Forward does not have length equal to\n"
00084           "the dimension of the domain for the corresponding ADFun."
00085      );
00086      CPPAD_ASSERT_KNOWN(
00087           p <= taylor_per_var_,
00088           "The number of taylor_ coefficient currently stored\n"
00089           "in this ADFun object is less than p."
00090      );  
00091 
00092      // check if the taylor_ matrix needs more columns
00093      if( taylor_col_dim_ <= p )
00094           capacity_taylor(p + 1);
00095      CPPAD_ASSERT_UNKNOWN( taylor_col_dim_ > p );
00096 
00097      // set the p-th order taylor_ coefficients for independent variables
00098      for(j = 0; j < n; j++)
00099      {    CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < total_num_var_ );
00100 
00101           // ind_taddr_[j] is operator taddr for j-th independent variable
00102           CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == InvOp );
00103 
00104           // It is also variable taddr for j-th independent variable
00105           taylor_[ind_taddr_[j] * taylor_col_dim_ + p] = x_p[j];
00106      }
00107 
00108      // evaluate the derivatives
00109      if( p == 0 )
00110      {
00111 # if CPPAD_USE_FORWARD0SWEEP
00112           compare_change_ = forward0sweep(s, true,
00113                n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
00114           );
00115 # else
00116           compare_change_ = forward_sweep(s, true,
00117                p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
00118           );
00119 # endif
00120      }
00121      else forward_sweep(s, false,
00122           p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
00123      );
00124 
00125      // return the p-th order taylor_ coefficients for dependent variables
00126      Vector y_p(m);
00127      for(i = 0; i < m; i++)
00128      {    CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < total_num_var_ );
00129           y_p[i] = taylor_[dep_taddr_[i] * taylor_col_dim_ + p];
00130      }
00131 # ifndef NDEBUG
00132      if( hasnan(y_p) )
00133      {    if( p == 0 )
00134           {    CPPAD_ASSERT_KNOWN(false,
00135                     "y = f.Forward(0, x): has a nan in y."
00136                );  
00137           }
00138           else
00139           {    CPPAD_ASSERT_KNOWN(false,
00140                     "y_p = f.Forward(p, x_p): has a nan in y_p for p > 0, "
00141                     "but not for p = 0."
00142                );
00143           }
00144      }
00145 # endif
00146 
00147 
00148      // now we have p + 1  taylor_ coefficients per variable
00149      taylor_per_var_ = p + 1;
00150 
00151      return y_p;
00152 }
00153 
00154 /*! \} */
00155 CPPAD_END_NAMESPACE
00156 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines