CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_CAPACITY_ORDER_INCLUDED 00003 # define CPPAD_CAPACITY_ORDER_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell 00007 00008 CppAD is distributed under multiple licenses. This distribution is under 00009 the terms of the 00010 Eclipse 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 $begin capacity_order$$ 00018 $spell 00019 var 00020 taylor_ 00021 xq 00022 yq 00023 $$ 00024 00025 $index Forward, capacity$$ 00026 $index capacity_order$$ 00027 $index capacity, Forward$$ 00028 $index control, memory$$ 00029 $index memory, control$$ 00030 00031 $section Controlling Taylor Coefficients Memory Allocation$$ 00032 00033 $head Syntax$$ 00034 $icode%f%.capacity_order(%c%)%$$ 00035 00036 $subhead See Also$$ 00037 $cref seq_property$$ 00038 00039 $head Purpose$$ 00040 The Taylor coefficients calculated by $cref Forward$$ mode calculations 00041 are retained in an $cref ADFun$$ object for subsequent use during 00042 $cref Reverse$$ mode and higher order Forward mode calculations. 00043 For example, a call to $cref/Forward/forward_order/$$ with the syntax 00044 $codei% 00045 %yq% = %f%.Forward(%q%, %xq%) 00046 %$$ 00047 where $icode%q% > 0%$$ and $code%xq%.size() == %f%.Domain()%$$, 00048 uses the lower order Taylor coefficients and 00049 computes the $th q$$ order Taylor coefficients for all 00050 the variables in the operation sequence corresponding to $icode f$$. 00051 The $code capacity_order$$ operation allows you to control that 00052 amount of memory that is retained by an AD function object 00053 (to hold $code Forward$$ results for subsequent calculations). 00054 00055 $head f$$ 00056 The object $icode f$$ has prototype 00057 $codei% 00058 ADFun<%Base%> %f% 00059 %$$ 00060 00061 $head c$$ 00062 The argument $icode c$$ has prototype 00063 $codei% 00064 size_t %c% 00065 %$$ 00066 It specifies the number of Taylor coefficient orders that are allocated 00067 in the AD operation sequence corresponding to $icode f$$. 00068 00069 $subhead Pre-Allocating Memory$$ 00070 If you plan to make calls to $code Forward$$ with the maximum value of 00071 $icode q$$ equal to $icode Q$$, 00072 it should be faster to pre-allocate memory for these calls using 00073 $codei% 00074 %f%.capacity_order(%c%) 00075 %$$ 00076 with $icode c$$ equal to $latex Q + 1$$. 00077 If you do no do this, $code Forward$$ will automatically allocate memory 00078 and will copy the results to a larger buffer, when necessary. 00079 $pre 00080 00081 $$ 00082 Note that each call to $cref Dependent$$ frees the old memory 00083 connected to the function object and sets the corresponding 00084 taylor capacity to zero. 00085 00086 $subhead Freeing Memory$$ 00087 If you no longer need the Taylor coefficients of order $icode q$$ 00088 and higher (that are stored in $icode f$$), 00089 you can reduce the memory allocated to $icode f$$ using 00090 $codei% 00091 %f%.capacity_order(%c%) 00092 %$$ 00093 with $icode c$$ equal to $icode q$$. 00094 Note that, if $cref ta_hold_memory$$ is true, this memory is not actually 00095 returned to the system, but rather held for future use by the same thread. 00096 00097 $head Original State$$ 00098 If $icode f$$ is $cref/constructed/FunConstruct/$$ with the syntax 00099 $codei% 00100 ADFun<%Base%> %f%(%x%, %y%) 00101 %$$, 00102 there is an implicit call to $cref forward_zero$$ with $icode xq$$ equal to 00103 the value of the 00104 $cref/independent variables/glossary/Tape/Independent Variable/$$ 00105 when the AD operation sequence was recorded. 00106 This corresponds to $icode%c% == 1%$$. 00107 00108 $children% 00109 example/capacity_order.cpp 00110 %$$ 00111 $head Example$$ 00112 The file 00113 $cref capacity_order.cpp$$ 00114 contains an example and test of these operations. 00115 It returns true if it succeeds and false otherwise. 00116 00117 $end 00118 ----------------------------------------------------------------------------- 00119 */ 00120 00121 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00122 /*! 00123 \file capacity_order.hpp 00124 Control of number of orders allocated. 00125 \} 00126 */ 00127 00128 /*! 00129 Control of number of orders allocated. 00130 00131 00132 \tparam Base 00133 The type used during the forward mode computations; i.e., the corresponding 00134 recording of operations used the type AD<Base>. 00135 00136 \param c 00137 is the number of orders to allocate memory for. 00138 If <code>c == 0</code>, 00139 the values num_order_taylor_, cap_order_taylor_, and num_direction_taylor_ 00140 are all set to zero. 00141 In addition, taylor_.free() is called. 00142 00143 \par num_order_taylor_ 00144 The output value of num_order_taylor_ is the mininumum of its input 00145 value and c. This minimum is the number of orders that are copied to the 00146 new taylor coefficient buffer. 00147 */ 00148 00149 template <typename Base> 00150 void ADFun<Base>::capacity_order(size_t c) 00151 { // temporary indices 00152 size_t i, k; 00153 00154 if(c == cap_order_taylor_ ) 00155 return; 00156 00157 if( c == 0 ) 00158 { taylor_.free(); 00159 num_order_taylor_ = 0; 00160 cap_order_taylor_ = 0; 00161 return; 00162 } 00163 00164 // Allocate new matrix with requested number of columns 00165 size_t new_len = num_var_tape_ * c; 00166 pod_vector<Base> new_taylor; 00167 new_taylor.extend(new_len); 00168 00169 00170 // number of orders to copy 00171 size_t p = std::min(num_order_taylor_, c); 00172 if( p > 0 ) 00173 { 00174 // old order capacity 00175 size_t C = cap_order_taylor_; 00176 00177 // copy the old data into the new matrix 00178 for(i = 0; i < num_var_tape_; i++) 00179 { for(k = 0; k < p; k++) 00180 new_taylor[ c*i + k] = taylor_[ C*i + k]; 00181 } 00182 } 00183 00184 // replace taylor_ by new_taylor 00185 taylor_.swap(new_taylor); 00186 cap_order_taylor_ = c; 00187 num_order_taylor_ = p; 00188 00189 // note that the destructor for new_taylor will free the old taylor memory 00190 return; 00191 } 00192 00193 } // END CppAD namespace 00194 00195 00196 # endif