source: branches/opt_cond_exp/cppad/local/dependent.hpp @ 2979

Last change on this file since 2979 was 2979, checked in by bradbell, 7 years ago
  1. Add operator index to trace output.
  2. Check that new operator values have been set and are valid.
  3. Reinitialize cskip_op_ after optimization.

optimize.hpp: Add test of entirely removing an atomic call.

  • Property svn:keywords set to Id
File size: 8.4 KB
Line 
1/* $Id: dependent.hpp 2979 2013-10-20 18:00:28Z bradbell $ */
2# ifndef CPPAD_DEPENDENT_INCLUDED
3# define CPPAD_DEPENDENT_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15/*
16$begin Dependent$$
17$spell
18        alloc
19        num
20        taylor_
21        ADvector
22        const
23$$
24
25$spell
26$$
27
28$section Stop Recording and Store Operation Sequence$$
29
30$index ADFun, operation sequence$$
31$index operation, sequence store$$
32$index sequence, operation store$$
33$index recording, stop$$
34$index tape, stop recording$$
35$index Dependent$$
36
37$head Syntax$$
38$icode%f%.Dependent(%x%, %y%)%$$
39
40$head Purpose$$
41Stop recording and the AD of $icode Base$$
42$cref/operation sequence/glossary/Operation/Sequence/$$
43that started with the call
44$codei%
45        Independent(%x%)
46%$$
47and store the operation sequence in $icode f$$.
48The operation sequence defines an
49$cref/AD function/glossary/AD Function/$$
50$latex \[
51        F : B^n \rightarrow B^m
52\] $$
53where $latex B$$ is the space corresponding to objects of type $icode Base$$.
54The value $latex n$$ is the dimension of the
55$cref/domain/seq_property/Domain/$$ space for the operation sequence.
56The value $latex m$$ is the dimension of the
57$cref/range/seq_property/Range/$$ space for the operation sequence
58(which is determined by the size of $icode y$$).
59
60$head f$$
61The object $icode f$$ has prototype
62$codei%
63        ADFun<%Base%> %f%
64%$$
65The AD of $icode Base$$ operation sequence is stored in $icode f$$; i.e.,
66it becomes the operation sequence corresponding to $icode f$$.
67If a previous operation sequence was stored in $icode f$$,
68it is deleted.
69
70$head x$$
71The argument $icode x$$
72must be the vector argument in a previous call to
73$cref Independent$$.
74Neither its size, or any of its values, are allowed to change
75between calling
76$codei%
77        Independent(%x%)
78%$$
79and
80$codei%
81        %f%.Dependent(%x%, %y%)
82%$$.
83
84$head y$$
85The vector $icode y$$ has prototype
86$codei%
87        const %ADvector% &%y%
88%$$
89(see $cref/ADvector/FunConstruct/$$ below).
90The length of $icode y$$ must be greater than zero
91and is the dimension of the range space for $icode f$$.
92
93$head ADvector$$
94The type $icode ADvector$$ must be a $cref SimpleVector$$ class with
95$cref/elements of type/SimpleVector/Elements of Specified Type/$$
96$codei%AD<%Base%>%$$.
97The routine $cref CheckSimpleVector$$ will generate an error message
98if this is not the case.
99
100$head Taping$$
101The tape,
102that was created when $codei%Independent(%x%)%$$ was called,
103will stop recording.
104The AD operation sequence will be transferred from
105the tape to the object $icode f$$ and the tape will then be deleted.
106
107$head Forward$$
108No $cref Forward$$ calculation is preformed during this operation.
109Thus, directly after this operation,
110$codei%
111        %f%.size_taylor()
112%$$
113is zero (see $cref size_taylor$$).
114
115$head Parallel Mode$$
116$index parallel, Dependent$$
117$index Dependent, parallel$$
118The call to $code Independent$$,
119and the corresponding call to
120$codei%
121        ADFun<%Base%> %f%( %x%, %y%)
122%$$
123or
124$codei%
125        %f%.Dependent( %x%, %y%)
126%$$
127or $cref abort_recording$$,
128must be preformed by the same thread; i.e.,
129$cref/thread_alloc::thread_num/ta_thread_num/$$ must be the same.
130
131$head Example$$
132The file
133$cref fun_check.cpp$$
134contains an example and test of this operation.
135It returns true if it succeeds and false otherwise.
136
137$end
138----------------------------------------------------------------------------
139*/
140
141
142// BEGIN CppAD namespace
143namespace CppAD {
144
145/*!
146Determine the \c tape corresponding to this exeuction thread and then use
147<code>Dependent(tape, y)</code> to store this tapes recording in a function.
148
149\param y [in]
150The dependent variable vector for the corresponding function.
151*/
152template <typename Base>
153template <typename ADvector>
154void ADFun<Base>::Dependent(const ADvector &y)
155{       ADTape<Base>* tape = AD<Base>::tape_ptr();
156        CPPAD_ASSERT_KNOWN(
157                tape != CPPAD_NULL,
158                "Can't store current operation sequence in this ADFun object"
159                "\nbecause there is no active tape (for this thread)."
160        );
161
162        // code above just determines the tape and checks for errors
163        Dependent(tape, y);
164}
165
166
167/*!
168Determine the \c tape corresponding to this exeuction thread and then use
169<code>Dependent(tape, y)</code> to store this tapes recording in a function.
170
171\param x [in]
172The independent variable vector for this tape. This informaiton is
173also stored in the tape so a check is done to make sure it is correct
174(if NDEBUG is not defined).
175
176\param y [in]
177The dependent variable vector for the corresponding function.
178*/
179template <typename Base>
180template <typename ADvector>
181void ADFun<Base>::Dependent(const ADvector &x, const ADvector &y)
182{
183        CPPAD_ASSERT_KNOWN(
184                x.size() > 0,
185                "Dependent: independent variable vector has size zero."
186        );
187        CPPAD_ASSERT_KNOWN(
188                Variable(x[0]),
189                "Dependent: independent variable vector has been changed."
190        );
191        ADTape<Base> *tape = AD<Base>::tape_ptr(x[0].tape_id_);
192        CPPAD_ASSERT_KNOWN(
193                tape->size_independent_ == size_t( x.size() ),
194                "Dependent: independent variable vector has been changed."
195        );
196# ifndef NDEBUG
197        size_t i, j;
198        for(j = 0; j < size_t(x.size()); j++)
199        {       CPPAD_ASSERT_KNOWN(
200                size_t(x[j].taddr_) == (j+1),
201                "ADFun<Base>: independent variable vector has been changed."
202                );
203                CPPAD_ASSERT_KNOWN(
204                x[j].tape_id_ == x[0].tape_id_,
205                "ADFun<Base>: independent variable vector has been changed."
206                );
207        }
208        for(i = 0; i < size_t(y.size()); i++)
209        {       CPPAD_ASSERT_KNOWN(
210                CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) ,
211                "ADFun<Base>: dependent vector contains a variable for"
212                "\na different tape (thread) than the independent variables."
213                );
214        }
215# endif
216
217        // code above just determines the tape and checks for errors
218        Dependent(tape, y);
219}
220
221/*!
222Replace the floationg point operations sequence for this function object.
223
224\param tape
225is a tape that contains the new floating point operation sequence
226for this function.
227After this operation, all memory allocated for this tape is deleted.
228
229\param y
230The dependent variable vector for the function being stored in this object.
231*/
232
233template <typename Base>
234template <typename ADvector>
235void ADFun<Base>::Dependent(ADTape<Base> *tape, const ADvector &y)
236{
237        size_t   m = y.size();
238        size_t   n = tape->size_independent_;
239        size_t   i, j;
240        size_t   y_taddr;
241
242        // check ADvector is Simple Vector class with AD<Base> elements
243        CheckSimpleVector< AD<Base>, ADvector>();
244
245        CPPAD_ASSERT_KNOWN(
246                y.size() > 0,
247                "ADFun operation sequence dependent variable size is zero size"
248        ); 
249
250        // set total number of variables in tape, parameter flag,
251        // make a tape copy of dependent variables that are parameters,
252        // and store tape address for each dependent variable
253        CPPAD_ASSERT_UNKNOWN( NumRes(ParOp) == 1 );
254        dep_parameter_.resize(m);
255        dep_taddr_.resize(m);
256        for(i = 0; i < m; i++)
257        {       dep_parameter_[i] = CppAD::Parameter(y[i]);
258                if( dep_parameter_[i] )
259                        y_taddr = tape->RecordParOp( y[i].value_ );
260                else    y_taddr = y[i].taddr_;
261
262                CPPAD_ASSERT_UNKNOWN( y_taddr > 0 );
263                dep_taddr_[i] = y_taddr;
264        }
265
266        // put an EndOp at the end of the tape
267        tape->Rec_.PutOp(EndOp);
268
269        // total number of variables on the tape
270        total_num_var_ = tape->Rec_.num_rec_var();
271
272        // conditional skip vector
273        cskip_op_.clear();
274        cskip_op_.resize( tape->Rec_.num_rec_op() );
275        for(i = 0; i < cskip_op_.size(); i++)
276                cskip_op_[i] = false;
277
278        // now that each dependent variable has a place in the tape,
279        // and there is a EndOp at the end of the tape, we can transfer the
280        // recording to the player and and erase the tape.
281        play_.get(tape->Rec_);
282
283        // now we can delete the tape
284        AD<Base>::tape_manage(tape_manage_delete);
285
286        // total number of varables in this recording
287        CPPAD_ASSERT_UNKNOWN( total_num_var_ == play_.num_rec_var() );
288
289        // used to determine if there is an operation sequence in *this
290        CPPAD_ASSERT_UNKNOWN( total_num_var_ > 0 );
291
292        // free old buffers
293        for_jac_sparse_pack_.resize(0, 0);
294        for_jac_sparse_set_.resize(0,0);
295
296        // initial row and column dimensions
297        taylor_.erase();
298        taylor_per_var_   = 0;
299        taylor_col_dim_   = 0;
300
301        // set tape address
302        ind_taddr_.resize(n);
303        CPPAD_ASSERT_UNKNOWN(
304                n < total_num_var_
305        );
306        for(j = 0; j < n; j++)
307        {       CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == InvOp );
308                ind_taddr_[j] = j+1;
309        }
310
311}
312
313} // END CppAD namespace
314
315# endif
Note: See TracBrowser for help on using the repository browser.