CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
azmul.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_AZMUL_HPP
2 # define CPPAD_CORE_AZMUL_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 $begin azmul$$
16 $spell
17  azmul
18  const
19  namespace
20  Vec
21 $$
22 
23 $section Absolute Zero Multiplication$$
24 
25 $head Syntax$$
26 $icode%z% = azmul(%x%, %y%)%$$
27 
28 $head Purpose$$
29 Evaluates multiplication with an absolute zero
30 for any of the possible types listed below.
31 The result is given by
32 $latex \[
33 z = \left\{ \begin{array}{ll}
34  0 & {\rm if} \; x = 0 \\
35  x \cdot y & {\rm otherwise}
36 \end{array} \right.
37 \] $$
38 Note if $icode x$$ is zero and $icode y$$ is infinity,
39 ieee multiplication would result in not a number whereas
40 $icode z$$ would be zero.
41 
42 $head Base$$
43 If $icode Base$$ satisfies the
44 $cref/base type requirements/base_require/$$
45 and arguments $icode x$$, $icode y$$ have prototypes
46 $codei%
47  const %Base%& %x%
48  const %Base%& %y%
49 %$$
50 then the result $icode z$$ has prototype
51 $codei%
52  %Base% %z%
53 %$$
54 
55 $head AD<Base>$$
56 If the arguments $icode x$$, $icode y$$ have prototype
57 $codei%
58  const AD<%Base%>& %x%
59  const AD<%Base%>& %y%
60 %$$
61 then the result $icode z$$ has prototype
62 $codei%
63  AD<%Base%> %z%
64 %$$
65 
66 $head VecAD<Base>$$
67 If the arguments $icode x$$, $icode y$$ have prototype
68 $codei%
69  const VecAD<%Base%>::reference& %x%
70  const VecAD<%Base%>::reference& %y%
71 %$$
72 then the result $icode z$$ has prototype
73 $codei%
74  AD<%Base%> %z%
75 %$$
76 
77 $head Example$$
78 $children%
79  example/general/azmul.cpp
80 %$$
81 The file
82 $cref azmul.cpp$$
83 is an examples and tests of this function.
84 It returns true if it succeeds and false otherwise.
85 
86 $end
87 */
88 
89 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
90 // ==========================================================================
91 
92 // case where x and y are AD<Base> -------------------------------------------
93 template <class Base> AD<Base>
94 azmul(const AD<Base>& x, const AD<Base>& y)
95 {
96  // compute the Base part
97  AD<Base> result;
98  result.value_ = azmul(x.value_, y.value_);
99 
100  // check if there is a recording in progress
102  if( tape == CPPAD_NULL )
103  return result;
104  tape_id_t tape_id = tape->id_;
105 
106  // tape_id cannot match the default value for tape_id_; i.e., 0
107  CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
108  bool var_x = x.tape_id_ == tape_id;
109  bool var_y = y.tape_id_ == tape_id;
110 
111  if( var_x )
112  { if( var_y )
113  { // result = azmul(variable, variable)
116 
117  // put operand addresses in tape
118  tape->Rec_.PutArg(x.taddr_, y.taddr_);
119 
120  // put operator in the tape
121  result.taddr_ = tape->Rec_.PutOp(local::ZmulvvOp);
122 
123  // make result a variable
124  result.tape_id_ = tape_id;
125  }
126  else if( IdenticalZero( y.value_ ) )
127  { // result = variable * 0
128  }
129  else if( IdenticalOne( y.value_ ) )
130  { // result = variable * 1
131  result.make_variable(x.tape_id_, x.taddr_);
132  }
133  else
134  { // result = zmul(variable, parameter)
137 
138  // put operand addresses in tape
139  addr_t p = tape->Rec_.PutPar(y.value_);
140  tape->Rec_.PutArg(x.taddr_, p);
141 
142  // put operator in the tape
143  result.taddr_ = tape->Rec_.PutOp(local::ZmulvpOp);
144 
145  // make result a variable
146  result.tape_id_ = tape_id;
147  }
148  }
149  else if( var_y )
150  { if( IdenticalZero(x.value_) )
151  { // result = 0 * variable
152  }
153  else if( IdenticalOne( x.value_ ) )
154  { // result = 1 * variable
155  result.make_variable(y.tape_id_, y.taddr_);
156  }
157  else
158  { // result = zmul(parameter, variable)
161 
162  // put operand addresses in tape
163  addr_t p = tape->Rec_.PutPar(x.value_);
164  tape->Rec_.PutArg(p, y.taddr_);
165 
166  // put operator in the tape
167  result.taddr_ = tape->Rec_.PutOp(local::ZmulpvOp);
168 
169  // make result a variable
170  result.tape_id_ = tape_id;
171  }
172  }
173  return result;
174 }
175 // =========================================================================
176 // Fold operations into case above
177 // -------------------------------------------------------------------------
178 // Operations with VecAD_reference<Base> and AD<Base> only
179 
180 template <class Base> AD<Base>
182 { return azmul(x, y.ADBase()); }
183 
184 template <class Base> AD<Base>
186 { return azmul(x.ADBase(), y.ADBase()); }
187 
188 template <class Base> AD<Base>
190 { return azmul(x.ADBase(), y); }
191 // -------------------------------------------------------------------------
192 // Operations with Base
193 
194 template <class Base> AD<Base>
195 azmul(const Base& x, const AD<Base>& y)
196 { return azmul(AD<Base>(x), y); }
197 
198 template <class Base> AD<Base>
199 azmul(const Base& x, const VecAD_reference<Base>& y)
200 { return azmul(AD<Base>(x), y.ADBase()); }
201 
202 template <class Base> AD<Base>
203 azmul(const AD<Base>& x, const Base& y)
204 { return azmul(x, AD<Base>(y)); }
205 
206 template <class Base> AD<Base>
207 azmul(const VecAD_reference<Base>& x, const Base& y)
208 { return azmul(x.ADBase(), AD<Base>(y)); }
209 
210 // ==========================================================================
211 } // END_CPPAD_NAMESPACE
212 
213 # endif
AD< Base > azmul(const AD< Base > &x, const AD< Base > &y)
Definition: azmul.hpp:94
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
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.
bool IdenticalOne(const std::complex< double > &x)
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
addr_t taddr_
Definition: ad.hpp:44
void make_variable(tape_id_t id, addr_t taddr)
Definition: ad.hpp:271
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