/home/coin/SVN-release/CoinAll-1.1.0/cppad/cppad/local/dependent.hpp

Go to the documentation of this file.
00001 # ifndef CPPAD_DEPENDENT_INCLUDED
00002 # define CPPAD_DEPENDENT_INCLUDED
00003 
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-07 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Common Public License Version 1.0.
00010 
00011 A copy of this license is included in the COPYING file of this distribution.
00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00013 -------------------------------------------------------------------------- */
00014 /*
00015 $begin Dependent$$
00016 $spell 
00017         Taylor
00018         ADvector
00019         const
00020 $$
00021 
00022 $spell
00023 $$
00024 
00025 $section Stop Recording and Store Operation Sequence$$
00026 
00027 $index ADFun, operation sequence$$
00028 $index operation, sequence store$$
00029 $index sequence, operation store$$
00030 $index recording, stop$$
00031 $index tape, stop recording$$
00032 $index Dependent$$
00033 
00034 $head Syntax$$
00035 $syntax%%f%.Dependent(%x%, %y%)%$$
00036 
00037 $head Purpose$$
00038 Stop recording and the AD of $italic Base$$
00039 $xref/glossary/Operation/Sequence/operation sequence/1/$$
00040 that started with the call
00041 $syntax%
00042         Independent(%x%)
00043 %$$
00044 and store the operation sequence in $italic f$$.
00045 The operation sequence defines an 
00046 $xref/glossary/AD Function/AD function/$$
00047 $latex \[
00048         F : B^n \rightarrow B^m
00049 \] $$
00050 where $latex B$$ is the space corresponding to objects of type $italic Base$$.
00051 The value $latex n$$ is the dimension of the 
00052 $xref/SeqProperty/Domain/domain/$$ space for the operation sequence.
00053 The value $latex m$$ is the dimension of the 
00054 $xref/SeqProperty/Range/range/$$ space for the operation sequence
00055 (which is determined by the size of $italic y$$).
00056 
00057 $head f$$
00058 The object $italic f$$ has prototype
00059 $syntax%
00060         ADFun<%Base%> %f%
00061 %$$
00062 The AD of $italic Base$$ operation sequence is stored in $italic f$$; i.e.,
00063 it becomes the operation sequence corresponding to $italic f$$.
00064 If a previous operation sequence was stored in $italic f$$,
00065 it is deleted. 
00066 
00067 $head x$$
00068 The argument $italic x$$ 
00069 must be the vector argument in a previous call to
00070 $cref/Independent/$$.
00071 Neither its size, or any of its values, are allowed to change
00072 between calling
00073 $syntax%
00074         Independent(%x%)
00075 %$$
00076 and 
00077 $syntax%
00078         %f%.Dependent(%x%, %y%)
00079 %$$.
00080 
00081 $head y$$
00082 The vector $italic y$$ has prototype
00083 $syntax%
00084         const %ADvector% &%y%
00085 %$$
00086 (see $xref/FunConstruct//ADvector/$$ below).
00087 The length of $italic y$$ must be greater than zero
00088 and is the dimension of the range space for $italic f$$.
00089 
00090 $head ADvector$$
00091 The type $italic ADvector$$ must be a $xref/SimpleVector/$$ class with
00092 $xref/SimpleVector/Elements of Specified Type/elements of type/$$
00093 $syntax%AD<%Base%>%$$.
00094 The routine $xref/CheckSimpleVector/$$ will generate an error message
00095 if this is not the case.
00096 
00097 $head Taping$$
00098 The tape,
00099 that was created when $syntax%Independent(%x%)%$$ was called, 
00100 will stop recording.
00101 The AD operation sequence will be transferred from
00102 the tape to the object $italic f$$ and the tape will then be deleted.
00103 
00104 $head Forward$$
00105 No $xref/Forward/$$ calculation is preformed during this operation.
00106 Thus, directly after this operation,
00107 $syntax%
00108         %f%.size_taylor()
00109 %$$ 
00110 is zero (see $xref/size_taylor/$$).
00111 
00112 $head Example$$
00113 The file
00114 $xref/FunCheck.cpp/$$ 
00115 contains an example and test of this operation.
00116 It returns true if it succeeds and false otherwise.
00117 
00118 $end
00119 ----------------------------------------------------------------------------
00120 */
00121 
00122 
00123 // BEGIN CppAD namespace
00124 namespace CppAD {
00125 
00126 template <typename Base>
00127 template <typename ADvector>
00128 void ADFun<Base>::Dependent(const ADvector &y)
00129 {       ADTape<Base> *tape = AD<Base>::tape_ptr();
00130         CPPAD_ASSERT_KNOWN(
00131                 tape != CPPAD_NULL,
00132                 "Can't store current operation sequence in this ADFun object"
00133                 "\nbecause there is no active tape (for this thread)."
00134         );
00135 
00136         // code above just determines the tape and checks for errors
00137         Dependent(tape, y);
00138 }
00139 
00140 template <typename Base>
00141 template <typename ADvector>
00142 void ADFun<Base>::Dependent(const ADvector &x, const ADvector &y)
00143 {
00144         CPPAD_ASSERT_KNOWN(
00145                 x.size() > 0,
00146                 "Dependent: independent variable vector has size zero."
00147         );
00148         CPPAD_ASSERT_KNOWN(
00149                 Variable(x[0]),
00150                 "Dependent: independent variable vector has been changed."
00151         );
00152         ADTape<Base> *tape = AD<Base>::tape_ptr(x[0].id_);
00153         CPPAD_ASSERT_KNOWN(
00154                 tape->size_independent == x.size(),
00155                 "Dependent: independent variable vector has been changed."
00156         );
00157 # ifndef NDEBUG
00158         size_t i, j;
00159         for(j = 0; j < x.size(); j++)
00160         {       CPPAD_ASSERT_KNOWN(
00161                 x[j].taddr_ == (j+1),
00162                 "ADFun<Base>: independent variable vector has been changed."
00163                 );
00164                 CPPAD_ASSERT_KNOWN(
00165                 x[j].id_ == x[0].id_,
00166                 "ADFun<Base>: independent variable vector has been changed."
00167                 );
00168         }
00169         for(i = 0; i < y.size(); i++)
00170         {       CPPAD_ASSERT_KNOWN(
00171                 CppAD::Parameter( y[i] ) | (y[i].id_ == x[0].id_) ,
00172                 "ADFun<Base>: dependent vector contains a variable for"
00173                 "\na different tape (thread) than the independent variables."
00174                 );
00175         }
00176 # endif
00177 
00178         // code above just determines the tape and checks for errors
00179         Dependent(tape, y);
00180 }
00181                 
00182 
00183 template <typename Base>
00184 template <typename ADvector>
00185 void ADFun<Base>::Dependent(ADTape<Base> *tape, const ADvector &y)
00186 {
00187         size_t   m = y.size();
00188         size_t   n = tape->size_independent;
00189         size_t   i, j;
00190         size_t   y_taddr;
00191 
00192         // check ADvector is Simple Vector class with AD<Base> elements
00193         CheckSimpleVector< AD<Base>, ADvector>();
00194 
00195         CPPAD_ASSERT_KNOWN(
00196                 y.size() > 0,
00197                 "ADFun operation sequence dependent variable size is zero size"
00198         ); 
00199 
00200         // set total number of variables in tape, parameter flag, 
00201         // make a tape copy of dependent variables that are parameters, 
00202         // and store tape address for each dependent variable
00203         CPPAD_ASSERT_UNKNOWN( NumVar(ParOp) == 1 );
00204         dep_parameter.resize(m);
00205         dep_taddr.resize(m);
00206         totalNumVar = tape->Rec.TotNumVar();
00207         for(i = 0; i < m; i++)
00208         {       dep_parameter[i] = CppAD::Parameter(y[i]);
00209                 if( dep_parameter[i] )
00210                 {       y_taddr = tape->RecordParOp( y[i].value_ );
00211                         totalNumVar++;
00212                 }
00213                 else    y_taddr = y[i].taddr_;
00214 
00215                 CPPAD_ASSERT_UNKNOWN( y_taddr > 0 );
00216                 CPPAD_ASSERT_UNKNOWN( y_taddr < totalNumVar );
00217                 dep_taddr[i] = y_taddr;
00218         }
00219 
00220         // now that each dependent variable has a place in the tape,
00221         // we can make a copy for this function and erase the tape.
00222         Rec = tape->Rec;
00223 
00224         // now we can delete the tape
00225         AD<Base>::tape_delete( tape->id_ );
00226 
00227         // total number of varables in this recording 
00228         CPPAD_ASSERT_UNKNOWN( totalNumVar == Rec.TotNumVar() );
00229 
00230         // used to determine if there is an operation sequence in *this
00231         CPPAD_ASSERT_UNKNOWN( totalNumVar > 0 );
00232 
00233         // free old buffers
00234         if( Taylor != CPPAD_NULL )
00235                 CPPAD_TRACK_DEL_VEC(Taylor);
00236         if( ForJac != CPPAD_NULL )
00237                 CPPAD_TRACK_DEL_VEC(ForJac);
00238 
00239         // initialize buffers
00240         Taylor  = CPPAD_NULL;
00241         ForJac  = CPPAD_NULL;
00242 
00243         // initial row and column dimensions
00244         // memoryMax  = 0;
00245         taylor_per_var= 0;
00246         ForJacColDim  = 0;
00247         ForJacBitDim  = 0;
00248         TaylorColDim  = 0;
00249 
00250         // set tape address 
00251         ind_taddr.resize(n);
00252         CPPAD_ASSERT_UNKNOWN(
00253                 n < totalNumVar
00254         );
00255         for(j = 0; j < n; j++)
00256         {       CPPAD_ASSERT_UNKNOWN( Rec.GetOp(j+1) == InvOp );
00257                 ind_taddr[j] = j+1;
00258         }
00259 
00260 }
00261 
00262 } // END CppAD namespace
00263 
00264 # endif

Generated on Sun Nov 14 14:06:33 2010 for Coin-All by  doxygen 1.4.7