CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pow.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_POW_HPP
2 # define CPPAD_CORE_POW_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 pow$$
17 $spell
18  Vec
19  std
20  namespace
21  CppAD
22  const
23 $$
24 
25 
26 $section The AD Power Function$$
27 $mindex pow exponent$$
28 
29 $head Syntax$$
30 $icode%z% = pow(%x%, %y%)%$$
31 
32 $head See Also$$
33 $cref pow_int$$
34 
35 
36 $head Purpose$$
37 Determines the value of the power function which is defined by
38 $latex \[
39  {\rm pow} (x, y) = x^y
40 \] $$
41 This version of the $code pow$$ function may use
42 logarithms and exponentiation to compute derivatives.
43 This will not work if $icode x$$ is less than or equal zero.
44 If the value of $icode y$$ is an integer,
45 the $cref pow_int$$ function is used to compute this value
46 using only multiplication (and division if $icode y$$ is negative).
47 (This will work even if $icode x$$ is less than or equal zero.)
48 
49 $head x$$
50 The argument $icode x$$ has one of the following prototypes
51 $codei%
52  const %Base%& %x%
53  const AD<%Base%>& %x%
54  const VecAD<%Base%>::reference& %x%
55 %$$
56 
57 $head y$$
58 The argument $icode y$$ has one of the following prototypes
59 $codei%
60  const %Base%& %y%
61  const AD<%Base%>& %y%
62  const VecAD<%Base%>::reference& %y%
63 %$$
64 
65 $head z$$
66 If both $icode x$$ and $icode y$$ are $icode Base$$ objects,
67 the result $icode z$$ is also a $icode Base$$ object.
68 Otherwise, it has prototype
69 $codei%
70  AD<%Base%> %z%
71 %$$
72 
73 $head Operation Sequence$$
74 This is an AD of $icode Base$$
75 $cref/atomic operation/glossary/Operation/Atomic/$$
76 and hence is part of the current
77 AD of $icode Base$$
78 $cref/operation sequence/glossary/Operation/Sequence/$$.
79 
80 $head Example$$
81 $children%
82  example/general/pow.cpp
83 %$$
84 The file
85 $cref pow.cpp$$
86 is an examples and tests of this function.
87 It returns true if it succeeds and false otherwise.
88 
89 $end
90 -------------------------------------------------------------------------------
91 */
92 
93 // BEGIN CppAD namespace
94 namespace CppAD {
95 
96 // case where x and y are AD<Base> -----------------------------------------
97 template <class Base> AD<Base>
98 pow(const AD<Base>& x, const AD<Base>& y)
99 {
100  // compute the Base part
101  AD<Base> result;
102  result.value_ = pow(x.value_, y.value_);
103  CPPAD_ASSERT_UNKNOWN( Parameter(result) );
104 
105  // check if there is a recording in progress
107  if( tape == CPPAD_NULL )
108  return result;
109  tape_id_t tape_id = tape->id_;
110 
111  // tape_id cannot match the default value for tape_id_; i.e., 0
112  CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
113  bool var_x = x.tape_id_ == tape_id;
114  bool var_y = y.tape_id_ == tape_id;
115 
116  if( var_x )
117  { if( var_y )
118  { // result = variable^variable
121 
122  // put operand addresses in tape
123  tape->Rec_.PutArg(x.taddr_, y.taddr_);
124 
125  // put operator in the tape
126  result.taddr_ = tape->Rec_.PutOp(local::PowvvOp);
127 
128  // make result a variable
129  result.tape_id_ = tape_id;
130  }
131  else if( IdenticalZero( y.value_ ) )
132  { // result = variable^0
133  }
134  else
135  { // result = variable^parameter
138 
139  // put operand addresses in tape
140  addr_t p = tape->Rec_.PutPar(y.value_);
141  tape->Rec_.PutArg(x.taddr_, p);
142 
143  // put operator in the tape
144  result.taddr_ = tape->Rec_.PutOp(local::PowvpOp);
145 
146  // make result a variable
147  result.tape_id_ = tape_id;
148  }
149  }
150  else if( var_y )
151  { if( IdenticalZero(x.value_) )
152  { // result = 0^variable
153  }
154  else
155  { // result = parameter^variable
158 
159  // put operand addresses in tape
160  addr_t p = tape->Rec_.PutPar(x.value_);
161  tape->Rec_.PutArg(p, y.taddr_);
162 
163  // put operator in the tape
164  result.taddr_ = tape->Rec_.PutOp(local::PowpvOp);
165 
166  // make result a variable
167  result.tape_id_ = tape_id;
168  }
169  }
170  return result;
171 }
172 // =========================================================================
173 // Fold operations in same way as CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op)
174 // -------------------------------------------------------------------------
175 // Operations with VecAD_reference<Base> and AD<Base> only
176 
177 template <class Base> AD<Base>
178 pow(const AD<Base>& x, const VecAD_reference<Base>& y)
179 { return pow(x, y.ADBase()); }
180 
181 template <class Base> AD<Base>
183 { return pow(x.ADBase(), y.ADBase()); }
184 
185 template <class Base> AD<Base>
186 pow(const VecAD_reference<Base>& x, const AD<Base>& y)
187 { return pow(x.ADBase(), y); }
188 // -------------------------------------------------------------------------
189 // Operations with Base
190 
191 template <class Base> AD<Base>
192 pow(const Base& x, const AD<Base>& y)
193 { return pow(AD<Base>(x), y); }
194 
195 template <class Base> AD<Base>
196 pow(const Base& x, const VecAD_reference<Base>& y)
197 { return pow(AD<Base>(x), y.ADBase()); }
198 
199 template <class Base> AD<Base>
200 pow(const AD<Base>& x, const Base& y)
201 { return pow(x, AD<Base>(y)); }
202 
203 template <class Base> AD<Base>
204 pow(const VecAD_reference<Base>& x, const Base& y)
205 { return pow(x.ADBase(), AD<Base>(y)); }
206 // -------------------------------------------------------------------------
207 // Operations with double
208 
209 template <class Base> AD<Base>
210 pow(const double& x, const AD<Base>& y)
211 { return pow(AD<Base>(x), y); }
212 
213 template <class Base> AD<Base>
214 pow(const double& x, const VecAD_reference<Base>& y)
215 { return pow(AD<Base>(x), y.ADBase()); }
216 
217 template <class Base> AD<Base>
218 pow(const AD<Base>& x, const double& y)
219 { return pow(x, AD<Base>(y)); }
220 
221 template <class Base> AD<Base>
222 pow(const VecAD_reference<Base>& x, const double& y)
223 { return pow(x.ADBase(), AD<Base>(y)); }
224 // -------------------------------------------------------------------------
225 // Special case to avoid ambuigity when Base is double
226 
227 inline AD<double>
228 pow(const double& x, const AD<double>& y)
229 { return pow(AD<double>(x), y); }
230 
231 inline AD<double>
232 pow(const double& x, const VecAD_reference<double>& y)
233 { return pow(AD<double>(x), y.ADBase()); }
234 
235 inline AD<double>
236 pow(const AD<double>& x, const double& y)
237 { return pow(x, AD<double>(y)); }
238 
239 inline AD<double>
240 pow(const VecAD_reference<double>& x, const double& y)
241 { return pow(x.ADBase(), AD<double>(y)); }
242 
243 // =========================================================================
244 // Fold operations for the cases where x is an int,
245 // but let cppad/utility/pow_int.hpp handle the cases where y is an int.
246 // -------------------------------------------------------------------------
247 template <class Base> AD<Base> pow
248 (const int& x, const VecAD_reference<Base>& y)
249 { return pow(AD<Base>(x), y.ADBase()); }
250 
251 template <class Base> AD<Base> pow
252 (const int& x, const AD<Base>& y)
253 { return pow(AD<Base>(x), y); }
254 
255 } // END CppAD namespace
256 
257 # endif
Base value_
Definition: ad.hpp:38
CPPAD_TAPE_ADDR_TYPE addr_t
Definition: declare_ad.hpp:44
Definition: ad.hpp:34
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
bool IdenticalZero(const std::complex< double > &x)
AD< Base > ADBase(void) const
Conversion from VecAD_reference to AD&lt;Base&gt;. puts the correspond vecad load instruction in the tape...
Definition: vec_ad.hpp:392
Type pow(const Type &x, const int &n)
Definition: pow_int.hpp:116
static local::ADTape< Base > * tape_ptr(void)
Pointer for the tape for this AD&lt;Base&gt; class and the current thread.
Definition: tape_link.hpp:130
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
local::recorder< Base > Rec_
This is where the information is recorded.
Definition: ad_tape.hpp:106
tape_id_t tape_id_
Definition: ad.hpp:41
Class used to hold a reference to an element of a VecAD object.
Definition: vec_ad.hpp:352
Class used to hold tape that records AD&lt;Base&gt; operations.
Definition: ad_tape.hpp:26
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool Parameter(const AD< Base > &x)
Definition: par_var.hpp:80
addr_t taddr_
Definition: ad.hpp:44
tape_id_t id_
Unique identifier for this tape.
Definition: ad_tape.hpp:101
CPPAD_TAPE_ID_TYPE tape_id_t
Definition: declare_ad.hpp:45