CppAD: A C++ Algorithmic Differentiation Package
20130102
|
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