CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
base_cond_exp.hpp
Go to the documentation of this file.
1 // $Id$
2 # ifndef CPPAD_CORE_BASE_COND_EXP_HPP
3 # define CPPAD_CORE_BASE_COND_EXP_HPP
4 
5 /* --------------------------------------------------------------------------
6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell
7 
8 CppAD is distributed under multiple licenses. This distribution is under
9 the terms of the
10  Eclipse Public License Version 1.0.
11 
12 A copy of this license is included in the COPYING file of this distribution.
13 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14 -------------------------------------------------------------------------- */
15 
16 /*
17 $begin base_cond_exp$$
18 $spell
19  alloc
20  Rel
21  hpp
22  enum
23  namespace
24  Op
25  Lt
26  Le
27  Eq
28  Ge
29  Gt
30  Ne
31  cond
32  exp
33  const
34  adolc
35  CppAD
36  inline
37 $$
38 
39 $section Base Type Requirements for Conditional Expressions$$
40 $mindex CondExp require CPPAD_COND_EXP_REL$$
41 
42 $head Purpose$$
43 These definitions are required by the user's code to support the
44 $codei%AD<%Base%>%$$ type for $cref CondExp$$ operations:
45 
46 $head CompareOp$$
47 The following $code enum$$ type is used in the specifications below:
48 $codep
49 namespace CppAD {
50  // The conditional expression operator enum type
51  enum CompareOp
52  { CompareLt, // less than
53  CompareLe, // less than or equal
54  CompareEq, // equal
55  CompareGe, // greater than or equal
56  CompareGt, // greater than
57  CompareNe // not equal
58  };
59 }
60 $$
61 
62 $head CondExpTemplate$$
63 The type $icode Base$$ must support the syntax
64 $codei%
65  %result% = CppAD::CondExpOp(
66  %cop%, %left%, %right%, %exp_if_true%, %exp_if_false%
67  )
68 %$$
69 which computes implements the corresponding $cref CondExp$$
70 function when the result has prototype
71 $codei%
72  %Base% %result%
73 %$$
74 The argument $icode cop$$ has prototype
75 $codei%
76  enum CppAD::CompareOp %cop%
77 %$$
78 The other arguments have the prototype
79 $codei%
80  const %Base%& %left%
81  const %Base%& %right%
82  const %Base%& %exp_if_true%
83  const %Base%& %exp_if_false%
84 %$$
85 
86 $subhead Ordered Type$$
87 If $icode Base$$ is a relatively simple type
88 that supports
89 $code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators
90 its $code CondExpOp$$ function can be defined by
91 $codei%
92 namespace CppAD {
93  inline %Base% CondExpOp(
94  enum CppAD::CompareOp cop ,
95  const %Base% &left ,
96  const %Base% &right ,
97  const %Base% &exp_if_true ,
98  const %Base% &exp_if_false )
99  { return CondExpTemplate(
100  cop, left, right, trueCase, falseCase);
101  }
102 }
103 %$$
104 For example, see
105 $cref/double CondExpOp/base_alloc.hpp/CondExpOp/$$.
106 For an example of and implementation of $code CondExpOp$$ with
107 a more involved $icode Base$$ type see
108 $cref/adolc CondExpOp/base_adolc.hpp/CondExpOp/$$.
109 
110 
111 $subhead Not Ordered$$
112 If the type $icode Base$$ does not support ordering,
113 the $code CondExpOp$$ function does not make sense.
114 In this case one might (but need not) define $code CondExpOp$$ as follows:
115 $codei%
116 namespace CppAD {
117  inline %Base% CondExpOp(
118  enum CompareOp cop ,
119  const %Base% &left ,
120  const %Base% &right ,
121  const %Base% &exp_if_true ,
122  const %Base% &exp_if_false )
123  { // attempt to use CondExp with a %Base% argument
124  assert(0);
125  return %Base%(0);
126  }
127 }
128 %$$
129 For example, see
130 $cref/complex CondExpOp/base_complex.hpp/CondExpOp/$$.
131 
132 $head CondExpRel$$
133 The macro invocation
134 $codei%
135  CPPAD_COND_EXP_REL(%Base%)
136 %$$
137 uses $code CondExpOp$$ above to define the following functions
138 $codei%
139  CondExpLt(%left%, %right%, %exp_if_true%, %exp_if_false%)
140  CondExpLe(%left%, %right%, %exp_if_true%, %exp_if_false%)
141  CondExpEq(%left%, %right%, %exp_if_true%, %exp_if_false%)
142  CondExpGe(%left%, %right%, %exp_if_true%, %exp_if_false%)
143  CondExpGt(%left%, %right%, %exp_if_true%, %exp_if_false%)
144 %$$
145 where the arguments have type $icode Base$$.
146 This should be done inside of the CppAD namespace.
147 For example, see
148 $cref/base_alloc/base_alloc.hpp/CondExpRel/$$.
149 
150 $end
151 */
152 
153 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
154 
155 /*!
156 \file base_cond_exp.hpp
157 CondExp operations that aid in meeting Base type requirements.
158 */
159 
160 /*!
161 \def CPPAD_COND_EXP_BASE_REL(Type, Rel, Op)
162 This macro defines the operation
163 \verbatim
164  CondExpRel(left, right, exp_if_true, exp_if_false)
165 \endverbatim
166 The argument \c Type is the \c Base type for this base require operation.
167 The argument \c Rel is one of \c Lt, \c Le, \c Eq, \c Ge, \c Gt.
168 The argument \c Op is the corresponding \c CompareOp value.
169 */
170 # define CPPAD_COND_EXP_BASE_REL(Type, Rel, Op) \
171  inline Type CondExp##Rel( \
172  const Type& left , \
173  const Type& right , \
174  const Type& exp_if_true , \
175  const Type& exp_if_false ) \
176  { return CondExpOp(Op, left, right, exp_if_true, exp_if_false); \
177  }
178 
179 /*!
180 \def CPPAD_COND_EXP_REL(Type)
181 The macro defines the operations
182 \verbatim
183  CondExpLt(left, right, exp_if_true, exp_if_false)
184  CondExpLe(left, right, exp_if_true, exp_if_false)
185  CondExpEq(left, right, exp_if_true, exp_if_false)
186  CondExpGe(left, right, exp_if_true, exp_if_false)
187  CondExpGt(left, right, exp_if_true, exp_if_false)
188 \endverbatim
189 The argument \c Type is the \c Base type for this base require operation.
190 */
191 # define CPPAD_COND_EXP_REL(Type) \
192  CPPAD_COND_EXP_BASE_REL(Type, Lt, CompareLt) \
193  CPPAD_COND_EXP_BASE_REL(Type, Le, CompareLe) \
194  CPPAD_COND_EXP_BASE_REL(Type, Eq, CompareEq) \
195  CPPAD_COND_EXP_BASE_REL(Type, Ge, CompareGe) \
196  CPPAD_COND_EXP_BASE_REL(Type, Gt, CompareGt)
197 
198 /*!
199 Template function to implement Conditional Expressions for simple types
200 that have comparision operators.
201 
202 \tparam CompareType
203 is the type of the left and right operands to the comparision operator.
204 
205 \tparam ResultType
206 is the type of the result, which is the same as \c CompareType except
207 during forward and reverse mode sparese calculations.
208 
209 \param cop
210 specifices which comparision to use; i.e.,
211 $code <$$,
212 $code <=$$,
213 $code ==$$,
214 $code >=$$,
215 $code >$$, or
216 $code !=$$.
217 
218 \param left
219 is the left operand to the comparision operator.
220 
221 \param right
222 is the right operand to the comparision operator.
223 
224 \param exp_if_true
225 is the return value is the comparision results in true.
226 
227 \param exp_if_false
228 is the return value is the comparision results in false.
229 
230 \return
231 see \c exp_if_true and \c exp_if_false above.
232 */
233 template <class CompareType, class ResultType>
234 ResultType CondExpTemplate(
235  enum CompareOp cop ,
236  const CompareType& left ,
237  const CompareType& right ,
238  const ResultType& exp_if_true ,
239  const ResultType& exp_if_false )
240 { ResultType returnValue;
241  switch( cop )
242  {
243  case CompareLt:
244  if( left < right )
245  returnValue = exp_if_true;
246  else returnValue = exp_if_false;
247  break;
248 
249  case CompareLe:
250  if( left <= right )
251  returnValue = exp_if_true;
252  else returnValue = exp_if_false;
253  break;
254 
255  case CompareEq:
256  if( left == right )
257  returnValue = exp_if_true;
258  else returnValue = exp_if_false;
259  break;
260 
261  case CompareGe:
262  if( left >= right )
263  returnValue = exp_if_true;
264  else returnValue = exp_if_false;
265  break;
266 
267  case CompareGt:
268  if( left > right )
269  returnValue = exp_if_true;
270  else returnValue = exp_if_false;
271  break;
272 
273  default:
275  returnValue = exp_if_true;
276  }
277  return returnValue;
278 }
279 
280 } // END_CPPAD_NAMESPACE
281 # endif
ResultType CondExpTemplate(enum CompareOp cop, const CompareType &left, const CompareType &right, const ResultType &exp_if_true, const ResultType &exp_if_false)
Template function to implement Conditional Expressions for simple types that have comparision operato...
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.