source: trunk/cppad/local/compare.hpp @ 2506

Last change on this file since 2506 was 2506, checked in by bradbell, 7 years ago

Change Licenses: CPL-1.0 -> EPL-1.0, GPL-2.0->GPL-3.0

  • Property svn:keywords set to Id
File size: 9.4 KB
Line 
1/* $Id: compare.hpp 2506 2012-10-24 19:36:49Z bradbell $ */
2# ifndef CPPAD_COMPARE_INCLUDED
3# define CPPAD_COMPARE_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15
16/*
17-------------------------------------------------------------------------------
18$begin Compare$$
19$spell
20        cos
21        Op
22        bool
23        const
24$$
25
26$index binary, AD compare operator$$
27$index AD, binary compare operator$$
28$index compare, AD binary operator$$
29$index operator, AD binary compare$$
30
31$index <, AD operator$$
32$index <=, AD operator$$
33$index >, AD operator$$
34$index >=, AD operator$$
35$index ==, AD operator$$
36$index !=, AD operator$$
37
38$section AD Binary Comparison Operators$$
39
40
41$head Syntax$$
42
43$icode%b% = %x% %Op% %y%$$
44
45
46$head Purpose$$
47Compares two operands where one of the operands is an
48$codei%AD<%Base%>%$$ object.
49The comparison has the same interpretation as for
50the $icode Base$$ type.
51
52
53$head Op$$
54The operator $icode Op$$ is one of the following:
55$table
56$bold Op$$ $pre $$  $cnext $bold Meaning$$                           $rnext
57$code <$$   $cnext is $icode x$$ less than $icode y$$              $rnext
58$code <=$$  $cnext is $icode x$$ less than or equal $icode y$$     $rnext
59$code >$$   $cnext is $icode x$$ greater than $icode y$$           $rnext
60$code >=$$  $cnext is $icode x$$ greater than or equal $icode y$$  $rnext
61$code ==$$  $cnext is $icode x$$ equal to $icode y$$               $rnext
62$code !=$$  $cnext is $icode x$$ not equal to $icode y$$
63$tend
64 
65$head x$$
66The operand $icode x$$ has prototype
67$codei%
68        const %Type% &%x%
69%$$
70where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
71
72$head y$$
73The operand $icode y$$ has prototype
74$codei%
75        const %Type% &%y%
76%$$
77where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
78
79$head b$$
80The result $icode b$$ has type
81$codei%
82        bool %b%
83%$$
84
85$head Operation Sequence$$
86The result of this operation is a $code bool$$ value
87(not an $cref/AD of Base/glossary/AD of Base/$$ object).
88Thus it will not be recorded as part of an
89AD of $icode Base$$
90$cref/operation sequence/glossary/Operation/Sequence/$$.
91$pre
92
93$$
94For example, suppose
95$icode x$$ and $icode y$$ are $codei%AD<%Base%>%$$ objects,
96the tape corresponding to $codei%AD<%Base%>%$$ is recording,
97$icode b$$ is true,
98and the subsequent code is
99$codei%
100        if( %b% )
101                %y% = cos(%x%);
102        else    %y% = sin(%x%);
103%$$
104only the assignment $icode%y% = cos(%x%)%$$ is recorded on the tape
105(if $icode x$$ is a $cref/parameter/glossary/Parameter/$$,
106nothing is recorded).
107The $cref CompareChange$$ function can yield
108some information about changes in comparison operation results.
109You can use $cref CondExp$$ to obtain comparison operations
110that depends on the
111$cref/independent variable/glossary/Tape/Independent Variable/$$
112values with out re-taping the AD sequence of operations.
113
114$head Assumptions$$
115If one of the $icode Op$$ operators listed above
116is used with an $codei%AD<%Base%>%$$ object,
117it is assumed that the same operator is supported by the base type
118$icode Base$$.
119
120$head Example$$
121$children%
122        example/compare.cpp
123%$$
124The file
125$cref compare.cpp$$
126contains an example and test of these operations.
127It returns true if it succeeds and false otherwise.
128
129$end
130-------------------------------------------------------------------------------
131*/
132//  BEGIN CppAD namespace
133namespace CppAD {
134
135template <class Base>
136
137// -------------- RecordCompare(cop, result, left, right) --------------------
138/// All these operations are done in \c Rec_, so we should move this
139/// routine to <tt>recorder<Base></tt>.
140void ADTape<Base>::RecordCompare(
141        enum CompareOp  cop   ,
142        bool           result ,
143        const AD<Base> &left  ,
144        const AD<Base> &right )
145{       addr_t ind0, ind1, ind2, ind3;
146
147        // ind[1] = base 2 representation of [result, Var(left), Var(right])
148        ind1 = 0;
149
150        // ind[2] = left address
151        if( Parameter(left) )
152                ind2 = Rec_.PutPar(left.value_);
153        else
154        {       ind1 += 2;
155                ind2 =  left.taddr_;
156        }
157
158        // ind[3] = right address
159        if( Parameter(right) )
160                ind3 = Rec_.PutPar(right.value_);
161        else
162        {       ind1 += 4;
163                ind3 =  right.taddr_;
164        }
165
166        // If both left and right are parameters, do not need to record
167        if( ind1 == 0 )
168                return;
169
170        // ind[1] & 1 = result
171        if( result )
172                ind1+= 1;
173
174        // ind[0] = cop
175        ind0 = size_t (cop);
176
177        CPPAD_ASSERT_UNKNOWN( ind1 > 1 );
178        CPPAD_ASSERT_UNKNOWN( NumArg(ComOp) == 4 );
179        CPPAD_ASSERT_UNKNOWN( NumRes(ComOp) == 0 );
180
181        // put the operator in the tape
182        Rec_.PutOp(ComOp);
183        Rec_.PutArg(ind0, ind1, ind2, ind3);
184}
185
186// -------------------------------- < -------------------------
187# ifdef NDEBUG
188
189template <class Base>
190CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
191bool operator < (const AD<Base> &left , const AD<Base> &right)
192{       bool result =  (left.value_ < right.value_); 
193        return result;
194}
195
196# else
197template <class Base>
198CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
199bool operator < (const AD<Base> &left , const AD<Base> &right)
200{       bool result =  (left.value_ < right.value_); 
201
202        ADTape<Base> *tape = CPPAD_NULL;
203        if( Variable(left) )
204                tape = left.tape_this();
205        else if ( Variable(right) )
206                tape = right.tape_this();
207
208        if( tape != CPPAD_NULL )
209                tape->RecordCompare(CompareLt, result, left, right);
210
211        return result;
212}
213# endif
214
215// convert other cases into the case above
216CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<)
217
218// -------------------------------- <= -------------------------
219# ifdef NDEBUG
220
221template <class Base>
222CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
223bool operator <= (const AD<Base> &left , const AD<Base> &right)
224{       bool result =  (left.value_ <= right.value_); 
225        return result;
226}
227
228# else
229template <class Base>
230CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
231bool operator <= (const AD<Base> &left , const AD<Base> &right)
232{       bool result =  (left.value_ <= right.value_); 
233
234        ADTape<Base> *tape = CPPAD_NULL;
235        if( Variable(left) )
236                tape = left.tape_this();
237        else if ( Variable(right) )
238                tape = right.tape_this();
239
240        if( tape != CPPAD_NULL )
241                tape->RecordCompare(CompareLe, result, left, right);
242
243        return result;
244}
245# endif
246
247// convert other cases into the case above
248CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<=)
249
250
251// -------------------------------- > -------------------------
252# ifdef NDEBUG
253
254template <class Base>
255CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
256bool operator > (const AD<Base> &left , const AD<Base> &right)
257{       bool result =  (left.value_ > right.value_); 
258        return result;
259}
260
261# else
262template <class Base>
263CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
264bool operator > (const AD<Base> &left , const AD<Base> &right)
265{       bool result =  (left.value_ > right.value_); 
266
267        ADTape<Base> *tape = CPPAD_NULL;
268        if( Variable(left) )
269                tape = left.tape_this();
270        else if ( Variable(right) )
271                tape = right.tape_this();
272
273        if( tape != CPPAD_NULL )
274                tape->RecordCompare(CompareGt, result, left, right);
275
276
277        return result;
278}
279# endif
280
281// convert other cases into the case above
282CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>)
283
284// -------------------------------- >= -------------------------
285# ifdef NDEBUG
286
287template <class Base>
288CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
289bool operator >= (const AD<Base> &left , const AD<Base> &right)
290{       bool result =  (left.value_ >= right.value_); 
291        return result;
292}
293
294# else
295template <class Base>
296CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
297bool operator >= (const AD<Base> &left , const AD<Base> &right)
298{       bool result =  (left.value_ >= right.value_); 
299
300        ADTape<Base> *tape = CPPAD_NULL;
301        if( Variable(left) )
302                tape = left.tape_this();
303        else if ( Variable(right) )
304                tape = right.tape_this();
305
306        if( tape != CPPAD_NULL )
307                tape->RecordCompare(CompareGe, result, left, right);
308
309        return result;
310}
311# endif
312
313// convert other cases into the case above
314CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>=)
315
316
317// -------------------------------- == -------------------------
318# ifdef NDEBUG
319
320template <class Base>
321CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
322bool operator == (const AD<Base> &left , const AD<Base> &right)
323{       bool result =  (left.value_ == right.value_); 
324        return result;
325}
326
327# else
328template <class Base>
329CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
330bool operator == (const AD<Base> &left , const AD<Base> &right)
331{       bool result =  (left.value_ == right.value_); 
332
333        ADTape<Base> *tape = CPPAD_NULL;
334        if( Variable(left) )
335                tape = left.tape_this();
336        else if ( Variable(right) )
337                tape = right.tape_this();
338
339        if( tape != CPPAD_NULL )
340                tape->RecordCompare(CompareEq, result, left, right);
341
342        return result;
343}
344# endif
345
346// convert other cases into the case above
347CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(==)
348
349// -------------------------------- != -------------------------
350# ifdef NDEBUG
351
352template <class Base>
353CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
354bool operator != (const AD<Base> &left , const AD<Base> &right)
355{       bool result =  (left.value_ != right.value_);
356        return result;
357}
358
359# else
360template <class Base>
361CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
362bool operator != (const AD<Base> &left , const AD<Base> &right)
363{       bool result =  (left.value_ != right.value_);
364
365        ADTape<Base> *tape = CPPAD_NULL;
366        if( Variable(left) )
367                tape = left.tape_this();
368        else if ( Variable(right) )
369                tape = right.tape_this();
370
371        if( tape != CPPAD_NULL )
372                tape->RecordCompare(CompareNe, result, left, right);
373
374        return result;
375}
376# endif
377
378// convert other cases into the case above
379CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(!=)
380
381} // END CppAD namespace
382
383# endif
Note: See TracBrowser for help on using the repository browser.