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