CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
compare.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_COMPARE_HPP
2 # define CPPAD_CORE_COMPARE_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 -------------------------------------------------------------------------------
17 $begin Compare$$
18 $spell
19  cos
20  Op
21  bool
22  const
23 $$
24 
25 
26 
27 $section AD Binary Comparison Operators$$
28 $mindex compare < <= > >= == !=$$
29 
30 
31 $head Syntax$$
32 
33 $icode%b% = %x% %Op% %y%$$
34 
35 
36 $head Purpose$$
37 Compares two operands where one of the operands is an
38 $codei%AD<%Base%>%$$ object.
39 The comparison has the same interpretation as for
40 the $icode Base$$ type.
41 
42 
43 $head Op$$
44 The operator $icode Op$$ is one of the following:
45 $table
46 $bold Op$$ $pre $$ $cnext $bold Meaning$$ $rnext
47 $code <$$ $cnext is $icode x$$ less than $icode y$$ $rnext
48 $code <=$$ $cnext is $icode x$$ less than or equal $icode y$$ $rnext
49 $code >$$ $cnext is $icode x$$ greater than $icode y$$ $rnext
50 $code >=$$ $cnext is $icode x$$ greater than or equal $icode y$$ $rnext
51 $code ==$$ $cnext is $icode x$$ equal to $icode y$$ $rnext
52 $code !=$$ $cnext is $icode x$$ not equal to $icode y$$
53 $tend
54 
55 $head x$$
56 The operand $icode x$$ has prototype
57 $codei%
58  const %Type% &%x%
59 %$$
60 where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
61 
62 $head y$$
63 The operand $icode y$$ has prototype
64 $codei%
65  const %Type% &%y%
66 %$$
67 where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
68 
69 $head b$$
70 The result $icode b$$ has type
71 $codei%
72  bool %b%
73 %$$
74 
75 $head Operation Sequence$$
76 The result of this operation is a $code bool$$ value
77 (not an $cref/AD of Base/glossary/AD of Base/$$ object).
78 Thus it will not be recorded as part of an
79 AD of $icode Base$$
80 $cref/operation sequence/glossary/Operation/Sequence/$$.
81 $pre
82 
83 $$
84 For example, suppose
85 $icode x$$ and $icode y$$ are $codei%AD<%Base%>%$$ objects,
86 the tape corresponding to $codei%AD<%Base%>%$$ is recording,
87 $icode b$$ is true,
88 and the subsequent code is
89 $codei%
90  if( %b% )
91  %y% = cos(%x%);
92  else %y% = sin(%x%);
93 %$$
94 only the assignment $icode%y% = cos(%x%)%$$ is recorded on the tape
95 (if $icode x$$ is a $cref/parameter/glossary/Parameter/$$,
96 nothing is recorded).
97 The $cref CompareChange$$ function can yield
98 some information about changes in comparison operation results.
99 You can use $cref CondExp$$ to obtain comparison operations
100 that depends on the
101 $cref/independent variable/glossary/Tape/Independent Variable/$$
102 values with out re-taping the AD sequence of operations.
103 
104 $head Assumptions$$
105 If one of the $icode Op$$ operators listed above
106 is used with an $codei%AD<%Base%>%$$ object,
107 it is assumed that the same operator is supported by the base type
108 $icode Base$$.
109 
110 $head Example$$
111 $children%
112  example/general/compare.cpp
113 %$$
114 The file
115 $cref compare.cpp$$
116 contains an example and test of these operations.
117 It returns true if it succeeds and false otherwise.
118 
119 $end
120 -------------------------------------------------------------------------------
121 */
122 // BEGIN CppAD namespace
123 namespace CppAD {
124 
125 // -------------------------------- < --------------------------
126 template <class Base>
128 bool operator < (const AD<Base> &left , const AD<Base> &right)
129 { bool result = (left.value_ < right.value_);
130  bool var_left = Variable(left);
131  bool var_right = Variable(right);
132 
133  local::ADTape<Base> *tape = CPPAD_NULL;
134  if( var_left )
135  { tape = left.tape_this();
136  if( var_right )
137  { if( result )
138  { tape->Rec_.PutOp(local::LtvvOp);
139  tape->Rec_.PutArg(left.taddr_, right.taddr_);
140  }
141  else
142  { tape->Rec_.PutOp(local::LevvOp);
143  tape->Rec_.PutArg(right.taddr_, left.taddr_);
144  }
145  }
146  else
147  { addr_t arg1 = tape->Rec_.PutPar(right.value_);
148  if( result )
149  { tape->Rec_.PutOp(local::LtvpOp);
150  tape->Rec_.PutArg(left.taddr_, arg1);
151  }
152  else
153  { tape->Rec_.PutOp(local::LepvOp);
154  tape->Rec_.PutArg(arg1, left.taddr_);
155  }
156  }
157  }
158  else if ( var_right )
159  { tape = right.tape_this();
160  addr_t arg0 = tape->Rec_.PutPar(left.value_);
161  if( result )
162  { tape->Rec_.PutOp(local::LtpvOp);
163  tape->Rec_.PutArg(arg0, right.taddr_);
164  }
165  else
166  { tape->Rec_.PutOp(local::LevpOp);
167  tape->Rec_.PutArg(right.taddr_, arg0);
168  }
169  }
170 
171  return result;
172 }
173 // convert other cases into the case above
175 
176 // -------------------------------- <= -------------------------
177 template <class Base>
179 bool operator <= (const AD<Base> &left , const AD<Base> &right)
180 { bool result = (left.value_ <= right.value_);
181  bool var_left = Variable(left);
182  bool var_right = Variable(right);
183 
184  local::ADTape<Base> *tape = CPPAD_NULL;
185  if( var_left )
186  { tape = left.tape_this();
187  if( var_right )
188  { if( result )
189  { tape->Rec_.PutOp(local::LevvOp);
190  tape->Rec_.PutArg(left.taddr_, right.taddr_);
191  }
192  else
193  { tape->Rec_.PutOp(local::LtvvOp);
194  tape->Rec_.PutArg(right.taddr_, left.taddr_);
195  }
196  }
197  else
198  { addr_t arg1 = tape->Rec_.PutPar(right.value_);
199  if( result )
200  { tape->Rec_.PutOp(local::LevpOp);
201  tape->Rec_.PutArg(left.taddr_, arg1);
202  }
203  else
204  { tape->Rec_.PutOp(local::LtpvOp);
205  tape->Rec_.PutArg(arg1, left.taddr_);
206  }
207  }
208  }
209  else if ( var_right )
210  { tape = right.tape_this();
211  addr_t arg0 = tape->Rec_.PutPar(left.value_);
212  if( result )
213  { tape->Rec_.PutOp(local::LepvOp);
214  tape->Rec_.PutArg(arg0, right.taddr_);
215  }
216  else
217  { tape->Rec_.PutOp(local::LtvpOp);
218  tape->Rec_.PutArg(right.taddr_, arg0);
219  }
220  }
221 
222  return result;
223 }
224 // convert other cases into the case above
226 
227 // -------------------------------- > --------------------------
228 template <class Base>
230 bool operator > (const AD<Base> &left , const AD<Base> &right)
231 { bool result = (left.value_ > right.value_);
232  bool var_left = Variable(left);
233  bool var_right = Variable(right);
234 
235  local::ADTape<Base> *tape = CPPAD_NULL;
236  if( var_left )
237  { tape = left.tape_this();
238  if( var_right )
239  { if( result )
240  { tape->Rec_.PutOp(local::LtvvOp);
241  tape->Rec_.PutArg(right.taddr_, left.taddr_);
242  }
243  else
244  { tape->Rec_.PutOp(local::LevvOp);
245  tape->Rec_.PutArg(left.taddr_, right.taddr_);
246  }
247  }
248  else
249  { addr_t arg1 = tape->Rec_.PutPar(right.value_);
250  if( result )
251  { tape->Rec_.PutOp(local::LtpvOp);
252  tape->Rec_.PutArg(arg1, left.taddr_);
253  }
254  else
255  { tape->Rec_.PutOp(local::LevpOp);
256  tape->Rec_.PutArg(left.taddr_, arg1);
257  }
258  }
259  }
260  else if ( var_right )
261  { tape = right.tape_this();
262  addr_t arg0 = tape->Rec_.PutPar(left.value_);
263  if( result )
264  { tape->Rec_.PutOp(local::LtvpOp);
265  tape->Rec_.PutArg(right.taddr_, arg0);
266  }
267  else
268  { tape->Rec_.PutOp(local::LepvOp);
269  tape->Rec_.PutArg(arg0, right.taddr_);
270  }
271  }
272 
273  return result;
274 }
275 // convert other cases into the case above
277 
278 // -------------------------------- >= -------------------------
279 template <class Base>
281 bool operator >= (const AD<Base> &left , const AD<Base> &right)
282 { bool result = (left.value_ >= right.value_);
283  bool var_left = Variable(left);
284  bool var_right = Variable(right);
285 
286  local::ADTape<Base> *tape = CPPAD_NULL;
287  if( var_left )
288  { tape = left.tape_this();
289  if( var_right )
290  { if( result )
291  { tape->Rec_.PutOp(local::LevvOp);
292  tape->Rec_.PutArg(right.taddr_, left.taddr_);
293  }
294  else
295  { tape->Rec_.PutOp(local::LtvvOp);
296  tape->Rec_.PutArg(left.taddr_, right.taddr_);
297  }
298  }
299  else
300  { addr_t arg1 = tape->Rec_.PutPar(right.value_);
301  if( result )
302  { tape->Rec_.PutOp(local::LepvOp);
303  tape->Rec_.PutArg(arg1, left.taddr_);
304  }
305  else
306  { tape->Rec_.PutOp(local::LtvpOp);
307  tape->Rec_.PutArg(left.taddr_, arg1);
308  }
309  }
310  }
311  else if ( var_right )
312  { tape = right.tape_this();
313  addr_t arg0 = tape->Rec_.PutPar(left.value_);
314  if( result )
315  { tape->Rec_.PutOp(local::LevpOp);
316  tape->Rec_.PutArg(right.taddr_, arg0);
317  }
318  else
319  { tape->Rec_.PutOp(local::LtpvOp);
320  tape->Rec_.PutArg(arg0, right.taddr_);
321  }
322  }
323 
324  return result;
325 }
326 // convert other cases into the case above
328 
329 // -------------------------------- == -------------------------
330 template <class Base>
332 bool operator == (const AD<Base> &left , const AD<Base> &right)
333 { bool result = (left.value_ == right.value_);
334  bool var_left = Variable(left);
335  bool var_right = Variable(right);
336 
337  local::ADTape<Base> *tape = CPPAD_NULL;
338  if( var_left )
339  { tape = left.tape_this();
340  if( var_right )
341  { tape->Rec_.PutArg(left.taddr_, right.taddr_);
342  if( result )
343  tape->Rec_.PutOp(local::EqvvOp);
344  else
345  tape->Rec_.PutOp(local::NevvOp);
346  }
347  else
348  { addr_t arg1 = tape->Rec_.PutPar(right.value_);
349  tape->Rec_.PutArg(arg1, left.taddr_);
350  if( result )
351  tape->Rec_.PutOp(local::EqpvOp);
352  else
353  tape->Rec_.PutOp(local::NepvOp);
354  }
355  }
356  else if ( var_right )
357  { tape = right.tape_this();
358  addr_t arg0 = tape->Rec_.PutPar(left.value_);
359  tape->Rec_.PutArg(arg0, right.taddr_);
360  if( result )
361  tape->Rec_.PutOp(local::EqpvOp);
362  else
363  tape->Rec_.PutOp(local::NepvOp);
364  }
365 
366  return result;
367 }
368 // convert other cases into the case above
370 
371 // -------------------------------- != -------------------------
372 template <class Base>
374 bool operator != (const AD<Base> &left , const AD<Base> &right)
375 { bool result = (left.value_ != right.value_);
376  bool var_left = Variable(left);
377  bool var_right = Variable(right);
378 
379  local::ADTape<Base> *tape = CPPAD_NULL;
380  if( var_left )
381  { tape = left.tape_this();
382  if( var_right )
383  { tape->Rec_.PutArg(left.taddr_, right.taddr_);
384  if( result )
385  tape->Rec_.PutOp(local::NevvOp);
386  else
387  tape->Rec_.PutOp(local::EqvvOp);
388  }
389  else
390  { addr_t arg1 = tape->Rec_.PutPar(right.value_);
391  tape->Rec_.PutArg(arg1, left.taddr_);
392  if( result )
393  tape->Rec_.PutOp(local::NepvOp);
394  else
395  tape->Rec_.PutOp(local::EqpvOp);
396  }
397  }
398  else if ( var_right )
399  { tape = right.tape_this();
400  addr_t arg0 = tape->Rec_.PutPar(left.value_);
401  tape->Rec_.PutArg(arg0, right.taddr_);
402  if( result )
403  tape->Rec_.PutOp(local::NepvOp);
404  else
405  tape->Rec_.PutOp(local::EqpvOp);
406  }
407 
408  return result;
409 }
410 // convert other cases into the case above
412 
413 } // END CppAD namespace
414 
415 # endif
CPPAD_TAPE_ADDR_TYPE addr_t
Definition: declare_ad.hpp:44
Definition: ad.hpp:34
#define CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op)
Declares automatic coercion for certain binary operations with bool result.
Definition: define.hpp:227
#define CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
A version of the inline command that works with MC compiler.
Definition: define.hpp:43
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool Variable(const AD< Base > &x)
Definition: par_var.hpp:99
local::recorder< Base > Rec_
This is where the information is recorded.
Definition: ad_tape.hpp:106
Class used to hold tape that records AD&lt;Base&gt; operations.
Definition: ad_tape.hpp:26