source: trunk/cppad/local/capacity_order.hpp @ 3301

Last change on this file since 3301 was 3301, checked in by bradbell, 6 years ago

merge in multiple forward direcitons from branches/forward_dir

  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1/* $Id: capacity_order.hpp 3301 2014-05-24 05:20:21Z bradbell $ */
2# ifndef CPPAD_CAPACITY_ORDER_INCLUDED
3# define CPPAD_CAPACITY_ORDER_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 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/*
17$begin capacity_order$$
18$spell
19        var
20        taylor_
21        xq
22        yq
23$$
24
25$index Forward, capacity$$
26$index capacity_order$$
27$index capacity, Forward$$
28$index control, memory$$
29$index memory, control$$
30
31$section Controlling Taylor Coefficients Memory Allocation$$
32
33$head Syntax$$
34$icode%f%.capacity_order(%c%)%$$
35
36$subhead See Also$$
37$cref seq_property$$
38
39$head Purpose$$
40The Taylor coefficients calculated by $cref Forward$$ mode calculations
41are retained in an $cref ADFun$$ object for subsequent use during
42$cref Reverse$$ mode and higher order Forward mode calculations.
43For example, a call to $cref/Forward/forward_order/$$ with the syntax
44$codei%
45        %yq% = %f%.Forward(%q%, %xq%)
46%$$
47where $icode%q% > 0%$$ and  $code%xq%.size() == %f%.Domain()%$$,
48uses the lower order Taylor coefficients and
49computes the $th q$$ order Taylor coefficients for all
50the variables in the operation sequence corresponding to $icode f$$.
51The $code capacity_order$$ operation allows you to control that
52amount of memory that is retained by an AD function object
53(to hold $code Forward$$ results for subsequent calculations).
54
55$head f$$
56The object $icode f$$ has prototype
57$codei%
58        ADFun<%Base%> %f%
59%$$
60
61$head c$$
62The argument $icode c$$ has prototype
63$codei%
64        size_t %c%
65%$$
66It specifies the number of Taylor coefficient orders that are allocated
67in the AD operation sequence corresponding to $icode f$$.
68
69$subhead Pre-Allocating Memory$$
70If you plan to make calls to $code Forward$$ with the maximum value of
71$icode q$$ equal to $icode Q$$,
72it should be faster to pre-allocate memory for these calls using
73$codei%
74        %f%.capacity_order(%c%)
75%$$
76with $icode c$$ equal to $latex Q + 1$$.
77If you do no do this, $code Forward$$ will automatically allocate memory
78and will copy the results to a larger buffer, when necessary.
79$pre
80
81$$
82Note that each call to $cref Dependent$$ frees the old memory
83connected to the function object and sets the corresponding
84taylor capacity to zero.
85
86$subhead Freeing Memory$$
87If you no longer need the Taylor coefficients of order $icode q$$
88and higher (that are stored in $icode f$$),
89you can reduce the memory allocated to $icode f$$ using
90$codei%
91        %f%.capacity_order(%c%)
92%$$
93with $icode c$$ equal to $icode q$$.
94Note that, if $cref ta_hold_memory$$ is true, this memory is not actually
95returned to the system, but rather held for future use by the same thread.
96
97$head Original State$$
98If $icode f$$ is $cref/constructed/FunConstruct/$$ with the syntax
99$codei%
100        ADFun<%Base%> %f%(%x%, %y%)
101%$$,
102there is an implicit call to $cref forward_zero$$ with $icode xq$$ equal to
103the value of the
104$cref/independent variables/glossary/Tape/Independent Variable/$$
105when the AD operation sequence was recorded.
106This corresponds to $icode%c% == 1%$$.
107
108$children%
109        example/capacity_order.cpp
110%$$
111$head Example$$
112The file
113$cref capacity_order.cpp$$
114contains an example and test of these operations.
115It returns true if it succeeds and false otherwise.
116
117$end
118-----------------------------------------------------------------------------
119*/
120
121namespace CppAD { // BEGIN_CPPAD_NAMESPACE
122/*!
123\file capacity_order.hpp
124Control of number of orders allocated.
125\}
126*/
127
128/*!
129Control of number of orders and directions allocated.
130
131\tparam Base
132The type used during the forward mode computations; i.e., the corresponding
133recording of operations used the type AD<Base>.
134
135\param c
136is the number of orders to allocate memory for.
137If <code>c == 0</code> then \c r must also be zero.
138In this case num_order_taylor_, cap_order_taylor_, and num_direction_taylor_
139are all set to zero.
140In addition, taylor_.free() is called.
141
142\param r
143is the number of directions to allocate memory for.
144If <code>c == 1</code> then \c r must also be one.
145In all cases, it must hold that
146<code>
147        r == num_direction_taylor_ || num_order_taylor <= 1
148</code>
149Upon return, num_direction_taylor_ is equal to r.
150
151\par num_order_taylor_
152The output value of num_order_taylor_ is the mininumum of its input
153value and c. This minimum is the number of orders that are copied to the
154new taylor coefficient buffer.
155
156\par num_direction_taylor_
157The output value of num_direction_taylor_ is equal to \c r.
158*/
159
160template <typename Base>
161void ADFun<Base>::capacity_order(size_t c, size_t r)
162{       // temporary indices
163        size_t i, k, ell;
164
165        if( (c == cap_order_taylor_) & (r == num_direction_taylor_) ) 
166                return;
167
168        if( c == 0 )
169        {       CPPAD_ASSERT_UNKNOWN( r == 0 );
170                taylor_.free();
171                num_order_taylor_     = 0;
172                cap_order_taylor_     = 0;
173                num_direction_taylor_ = r;
174                return;
175        }
176        CPPAD_ASSERT_UNKNOWN(r==num_direction_taylor_ || num_order_taylor_<=1);
177       
178        // Allocate new taylor with requested number of orders and directions 
179        size_t new_len   = ( (c-1)*r + 1 ) * num_var_tape_;
180        pod_vector<Base> new_taylor;
181        new_taylor.extend(new_len);
182
183        // number of orders to copy
184        size_t p = std::min(num_order_taylor_, c);
185        if( p > 0 )
186        {
187                // old order capacity
188                size_t C = cap_order_taylor_;
189
190                // old number of directions
191                size_t R = num_direction_taylor_;
192
193                // copy the old data into the new matrix
194                CPPAD_ASSERT_UNKNOWN( p == 1 || r == R );
195                for(i = 0; i < num_var_tape_; i++)
196                {       // copy zero order
197                        size_t old_index = ((C-1) * R + 1) * i + 0;
198                        size_t new_index = ((c-1) * r + 1) * i + 0;
199                        new_taylor[ new_index ] = taylor_[ old_index ];
200                        // copy higher orders
201                        for(k = 1; k < p; k++)
202                        {       for(ell = 0; ell < R; ell++)
203                                {       old_index = ((C-1) * R + 1) * i + (k-1) * R + ell + 1;
204                                        new_index = ((c-1) * r + 1) * i + (k-1) * r + ell + 1;
205                                        new_taylor[ new_index ] = taylor_[ old_index ];
206                                }
207                        }
208                }
209        }
210
211        // replace taylor_ by new_taylor
212        taylor_.swap(new_taylor);
213        cap_order_taylor_     = c;
214        num_order_taylor_     = p;
215        num_direction_taylor_ = r;
216
217        // note that the destructor for new_taylor will free the old taylor memory
218        return;
219}
220
221/*!
222User API control of number of orders allocated.
223
224\tparam Base
225The type used during the forward mode computations; i.e., the corresponding
226recording of operations used the type AD<Base>.
227
228\param c
229is the number of orders to allocate memory for.
230If <code>c == 0</code>,
231num_order_taylor_, cap_order_taylor_, and num_direction_taylor_
232are all set to zero.
233In addition, taylor_.free() is called.
234
235\par num_order_taylor_
236The output value of num_order_taylor_ is the mininumum of its input
237value and c. This minimum is the number of orders that are copied to the
238new taylor coefficient buffer.
239
240\par num_direction_taylor_
241If \c is zero (one), \c num_direction_taylor_ is set to zero (one).
242Otherwise, if \c num_direction_taylor_ is zero, it is set to one.
243Othwerwise, \c num_direction_taylor_ is not modified.
244*/
245
246template <typename Base>
247void ADFun<Base>::capacity_order(size_t c)
248{       size_t r;
249        if( (c == 0) | (c == 1) )
250        {       r = c;
251                capacity_order(c, r);
252                return;
253        }
254        r = num_direction_taylor_;
255        if( r == 0 )
256                r = 1;
257        capacity_order(c, r);
258        return;
259}
260
261} // END CppAD namespace
262       
263
264# endif
Note: See TracBrowser for help on using the repository browser.