CppAD: A C++ Algorithmic Differentiation Package 20110419
independent.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_INDEPENDENT_INCLUDED
00003 # define CPPAD_INDEPENDENT_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-10 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Common 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 
00018 $begin Independent$$
00019 $spell
00020         Cpp
00021         bool
00022         const
00023         var
00024         typename
00025 $$
00026 
00027 $index Independent$$
00028 $index start, recording$$
00029 $index recording, start$$
00030 $index variable, independent$$
00031 
00032 $section Declare Independent Variables and Start Recording$$
00033 
00034 $head Syntax$$
00035 $syntax%Independent(%x%)%$$
00036 
00037 
00038 $head Purpose$$
00039 Start a recording the 
00040 $xref/glossary/AD of Base/AD of Base/$$ operations
00041 with $italic x$$ as the vector of independent variables.
00042 Once the 
00043 AD of $italic Base$$
00044 $xref/glossary/Operation/Sequence/operation sequence/1/$$ is completed,
00045 it must be transferred to a function object; see below.
00046 
00047 $head Variables for a Tape$$
00048 A tape is create by the call 
00049 $syntax%
00050         Independent(%x%)
00051 %$$
00052 The corresponding operation sequence is transferred to a function object,
00053 and the tape is deleted,
00054 using either (see $cref/ADFun<Base> f(x, y)/FunConstruct/$$)
00055 $syntax%
00056         ADFun<%Base%> %f%( %x%, %y%)
00057 %$$
00058 or using (see $cref/f.Dependent(x, y)/Dependent/$$)
00059 $syntax%
00060         %f%.Dependent( %x%, %y%)
00061 %$$
00062 Between when the tape is created and when it is destroyed,
00063 we refer to the elements of $italic x$$, 
00064 and the values that depend on the elements of $italic x$$,
00065 as variables for the tape created by the call to $code Independent$$. 
00066 
00067 $head x$$
00068 The vector $italic x$$ has prototype
00069 $syntax%
00070         %VectorAD% &%x%
00071 %$$
00072 (see $italic VectorAD$$ below).
00073 The size of the vector $italic x$$, must be greater than zero,
00074 and is the number of independent variables for this
00075 AD operation sequence.
00076 
00077 $head VectorAD$$
00078 The type $italic VectorAD$$ must be a $xref/SimpleVector/$$ class with
00079 $xref/SimpleVector/Elements of Specified Type/elements of type/$$
00080 $syntax%AD<%Base%>%$$.
00081 The routine $xref/CheckSimpleVector/$$ will generate an error message
00082 if this is not the case.
00083 
00084 $head Memory Leak$$
00085 A memory leak will result if
00086 a tape is create by a call to $code Independent$$
00087 and not deleted by a corresponding call to 
00088 $syntax%
00089         ADFun<%Base%> %f%( %x%, %y%)
00090 %$$
00091 or using 
00092 $syntax%
00093         %f%.Dependent( %x%, %y%)
00094 %$$
00095 
00096 $head OpenMP$$
00097 $index OpenMP, Independent$$
00098 $index Independent, OpenMP$$
00099 In the case of multi-threading with OpenMP,
00100 the call to $code Independent$$
00101 and the corresponding call to
00102 $syntax%
00103         ADFun<%Base%> %f%( %x%, %y%)
00104 %$$
00105 or 
00106 $syntax%
00107         %f%.Dependent( %x%, %y%)
00108 %$$
00109 must be preformed by the same thread.
00110 
00111 $head Example$$
00112 $children%
00113         example/independent.cpp
00114 %$$
00115 The file
00116 $xref/Independent.cpp/$$
00117 contains an example and test of this operation.
00118 It returns true if it succeeds and false otherwise.
00119 
00120 $end
00121 -----------------------------------------------------------------------------
00122 */
00123 
00124 //  BEGIN CppAD namespace
00125 namespace CppAD {
00126 // ---------------------------------------------------------------------------
00127 
00128 template <typename Base>
00129 template <typename VectorAD>
00130 void ADTape<Base>::Independent(VectorAD &x)
00131 {
00132         // check VectorAD is Simple Vector class with AD<Base> elements
00133         CheckSimpleVector< AD<Base>, VectorAD>();
00134 
00135         // dimension of the domain space
00136         size_t n = x.size();
00137         CPPAD_ASSERT_KNOWN(
00138                 n > 0,
00139                 "Indepdendent: the argument vector x has zero size"
00140         );
00141         CPPAD_ASSERT_UNKNOWN( Rec_.num_rec_var() == 0 );
00142 
00143         // mark the beginning of the tape and skip the first variable index 
00144         // (zero) because parameters use taddr zero
00145         CPPAD_ASSERT_NARG_NRES(BeginOp, 0, 1);
00146         Rec_.PutOp(BeginOp);
00147 
00148         // place each of the independent variables in the tape
00149         CPPAD_ASSERT_NARG_NRES(InvOp, 0, 1);
00150         size_t j;
00151         for(j = 0; j < n; j++)
00152         {       // tape address for this independent variable
00153                 x[j].taddr_ = Rec_.PutOp(InvOp);
00154                 x[j].id_    = id_;
00155                 CPPAD_ASSERT_UNKNOWN( x[j].taddr_ == j+1 );
00156                 CPPAD_ASSERT_UNKNOWN( Variable(x[j] ) );
00157         }
00158 
00159         // done specifying all of the independent variables
00160         size_independent_ = n;
00161 }
00162 
00163 template <typename VectorAD>
00164 inline void Independent(VectorAD &x)
00165 {       typedef typename VectorAD::value_type ADBase;
00166         typedef typename ADBase::value_type   Base;
00167         CPPAD_ASSERT_KNOWN(
00168                 ADBase::tape_ptr() == CPPAD_NULL,
00169                 "Independent: cannot create a new tape because\n"
00170                 "a previous tape is still active (for this thread).\n"
00171                 "AD<Base>::abort_recording() would abort this previous recording."
00172         );
00173         size_t id = ADBase::tape_new();
00174 
00175         ADBase::tape_ptr(id)->Independent(x); 
00176 }
00177 
00178 
00179 } 
00180 // END CppAD namespace
00181 
00182 # endif