source: trunk/cppad/local/base_complex.hpp @ 3680

Last change on this file since 3680 was 3680, checked in by bradbell, 5 years ago

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 071875a4beba3363e5fa9752426aec4762cd1caa
end hash code: 0bef506513a519e1073c6279d5c4cba9e5c3b180

commit 0bef506513a519e1073c6279d5c4cba9e5c3b180
Author: Brad Bell <bradbell@…>
Date: Thu May 7 12:14:32 2015 -0700

Add the acosh function (as an atomic operation when defined by compiler).

commit b3264fa17b2f65b65800423a0e243c9c3ccfe06a
Author: Brad Bell <bradbell@…>
Date: Wed May 6 20:25:38 2015 -0700

CMakeLists.txt: Change so test only check for compliation.

commit dcbac4d4f20cc383f2bd9edb02036659df40b791
Author: Brad Bell <bradbell@…>
Date: Wed May 6 15:06:28 2015 -0700

asinh.cpp: check higher orders, relax accuracy on test.

commit 5f8881993fedd18cccc3c74831133a8f8a9d17b0
Author: Brad Bell <bradbell@…>
Date: Wed May 6 14:36:18 2015 -0700

Change Acos to acos.
acos.cpp: remove trailing white space.

commit e828fa1f7c4c3848c727f14b1b7a8030071ee705
Author: Brad Bell <bradbell@…>
Date: Wed May 6 12:07:35 2015 -0700

Change Acos to acos.
acos.cpp: remove redundant index commands, remove trailing with space.

commit 3d16e5b9fe1bdafa4ad01d1d466bb72b792650fa
Author: Brad Bell <bradbell@…>
Date: Wed May 6 11:30:49 2015 -0700

op_code.hpp: Minor edits to AcosOp? commnets.

commit 58beaaad149b4ac29fae44589d7f8900bf8f4c40
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:51:43 2015 -0700

for_jac_sweep.hpp: Add missing AsinhOp? case.

commit 623c134870c522ae5e80bcf0f89d230902594c80
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:27:39 2015 -0700

Fix comment about AsinhOp? operator.

commit 226b14f6f4810f5abf1ca247aae541963efaf4d6
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:14:08 2015 -0700

Add derivative of F to make order zero case clearer.
acos_reverse.omh: Fix some sign errors.
asin_reverse.omh: Fix typo.
acos_forward.omh: Simplify by distributing minus sign.

commit 4682f4ee73e33b600b180086576e986f636a24dc
Author: Brad Bell <bradbell@…>
Date: Wed May 6 08:15:50 2015 -0700

acos_forward.omh: fix sign that depends on acos versus acosh.

commit 906ae10adf019ddda7f57dd165aab08fc55289c4
Author: Brad Bell <bradbell@…>
Date: Wed May 6 07:09:47 2015 -0700

  1. Fix inclusion of some temporary files in package (e.g., git_commit.sh).
  2. Simplify and improve using git ls-files and ls bin/check_*.
  3. Remove trailing white space.

commit 5096f4706a547bd76caa3766aa2c62802ef7f0bf
Author: Brad Bell <bradbell@…>
Date: Wed May 6 06:41:20 2015 -0700

Combine base type documentation for erf, asinh
(will add more functions to this list list).

commit b3535db5ad95bee90672abcaa686032d23bce2fc
Author: Brad Bell <bradbell@…>
Date: Tue May 5 18:01:11 2015 -0700

  1. Change Arc Cosine/Sine? to Inverse Cosine/Sine?.
  2. Change arcsin-> asin and arccos->acos.
  3. Remove index commands that are duplicates of words in titles.


acos_reverse.omh: Add acosh case to this page.

  • Property svn:keywords set to Id
File size: 13.3 KB
Line 
1/* $Id: base_complex.hpp 3680 2015-05-07 19:17:37Z bradbell $ */
2# ifndef CPPAD_BASE_COMPLEX_INCLUDED
3# define CPPAD_BASE_COMPLEX_INCLUDED
4/* --------------------------------------------------------------------------
5CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
6
7CppAD is distributed under multiple licenses. This distribution is under
8the terms of the
9                    Eclipse Public License Version 1.0.
10
11A copy of this license is included in the COPYING file of this distribution.
12Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13-------------------------------------------------------------------------- */
14# include <cppad/configure.hpp>
15# include <limits>
16# include <complex>
17
18// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
19# include <cppad/thread_alloc.hpp>
20
21/*
22$begin base_complex.hpp$$
23$spell
24        acosh
25        asinh
26        endif
27        eps
28        abs_geq
29        Rel
30        Lt Le Eq Ge Gt
31        imag
32        gcc
33        isnan
34        cppad.hpp
35        sqrt
36        exp
37        cos
38        std
39        const
40        CppAD
41        Op
42        inline
43        enum
44        undef
45        acos
46        asin
47        atan
48        erf
49        Cond
50        namespace
51        bool
52$$
53
54$index complex, double Base$$
55$index Base, double complex$$
56$index double, complex Base$$
57
58$section Enable use of AD<Base> where Base is std::complex<double>$$
59
60$children%example/complex_poly.cpp
61%$$
62$head Example$$
63The file $cref complex_poly.cpp$$ contains an example use of
64$code std::complex<double>$$ type for a CppAD $icode Base$$ type.
65It returns true if it succeeds and false otherwise.
66
67$head Include Order$$
68This file is included before $code <cppad/cppad.hpp>$$
69so it is necessary to define the error handler
70in addition to including
71$cref/base_require.hpp/base_require/Include Order/$$
72$codep */
73# include <limits>
74# include <complex>
75# include <cppad/base_require.hpp>
76# include <cppad/local/cppad_assert.hpp>
77
78/* $$
79
80$head CondExpOp$$
81The type $code std::complex<double>$$ does not supports the
82$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
83$cref/not ordered/base_cond_exp/CondExpTemplate/Not Ordered/$$.
84Hence its $code CondExpOp$$ function is defined by
85$codep */
86namespace CppAD {
87        inline std::complex<double> CondExpOp(
88                enum CppAD::CompareOp      cop        ,
89                const std::complex<double> &left      ,
90                const std::complex<double> &right     ,
91                const std::complex<double> &trueCase  ,
92                const std::complex<double> &falseCase )
93        {       CppAD::ErrorHandler::Call(
94                        true     , __LINE__ , __FILE__ ,
95                        "std::complex<float> CondExpOp(...)",
96                        "Error: cannot use CondExp with a complex type"
97                );
98                return std::complex<double>(0);
99        }
100}
101/* $$
102
103$head CondExpRel$$
104The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
105$codep */
106namespace CppAD {
107        CPPAD_COND_EXP_REL( std::complex<double> )
108}
109/* $$
110used $code CondExpOp$$ above to
111define $codei%CondExp%Rel%$$ for $code std::complex<double>$$ arguments
112and $icode%Rel%$$ equal to
113$code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, and $code Gt$$.
114
115$head EqualOpSeq$$
116Complex numbers do not carry operation sequence information.
117Thus they are equal in this sense if and only if there values are equal.
118$codep */
119namespace CppAD {
120        inline bool EqualOpSeq(
121                const std::complex<double> &x ,
122                const std::complex<double> &y )
123        {       return x == y;
124        }
125}
126/* $$
127
128$head Identical$$
129Complex numbers do not carry operation sequence information.
130Thus they are all parameters so the identical functions just check values.
131$codep */
132namespace CppAD {
133        inline bool IdenticalPar(const std::complex<double> &x)
134        {       return true; }
135        inline bool IdenticalZero(const std::complex<double> &x)
136        {       return (x == std::complex<double>(0., 0.) ); }
137        inline bool IdenticalOne(const std::complex<double> &x)
138        {       return (x == std::complex<double>(1., 0.) ); }
139        inline bool IdenticalEqualPar(
140                const std::complex<double> &x, const std::complex<double> &y)
141        {       return (x == y); }
142}
143/* $$
144
145$head Ordered$$
146Complex types do not support comparison operators,
147$codep */
148# undef  CPPAD_USER_MACRO
149# define CPPAD_USER_MACRO(Fun)                                     \
150inline bool Fun(const std::complex<double>& x)                     \
151{      CppAD::ErrorHandler::Call(                                  \
152               true     , __LINE__ , __FILE__ ,                    \
153               #Fun"(x)",                                          \
154               "Error: cannot use " #Fun " with x complex<double> " \
155       );                                                          \
156       return false;                                               \
157}
158namespace CppAD {
159        CPPAD_USER_MACRO(LessThanZero)
160        CPPAD_USER_MACRO(LessThanOrZero)
161        CPPAD_USER_MACRO(GreaterThanOrZero)
162        CPPAD_USER_MACRO(GreaterThanZero)
163        inline bool abs_geq(
164                const std::complex<double>& x ,
165                const std::complex<double>& y )
166        {       return std::abs(x) >= std::abs(y); }
167}
168/* $$
169
170$head erf$$
171Complex types do not support the error function
172(use CPPAD_USER_MACRO define above).
173$codep */
174# if CPPAD_COMPILER_HAS_ERF
175namespace CppAD {
176        CPPAD_USER_MACRO(erf)
177}
178# endif
179/* $$
180
181
182$head Integer$$
183The implementation of this function must agree
184with the CppAD user specifications for complex arguments to the
185$cref/Integer/Integer/x/Complex Types/$$ function:
186$codep */
187namespace CppAD {
188        inline int Integer(const std::complex<double> &x)
189        {       return static_cast<int>( x.real() ); }
190}
191/* $$
192
193$head isnan$$
194The gcc 4.1.1 complier defines the function
195$codei%
196        int std::complex<double>::isnan( std::complex<double> %z% )
197%$$
198(which is not specified in the C++ 1998 standard ISO/IEC 14882).
199This causes an ambiguity between the function above and the CppAD
200$cref/isnan/nan/$$ template function.
201We avoid this ambiguity by defining a non-template version of
202this function in the CppAD namespace.
203$codep */
204namespace CppAD {
205        inline bool isnan(const std::complex<double>& z)
206        {       return (z != z);
207        }
208}
209/* $$
210
211$head Valid Unary Math$$
212The following macro invocations define the standard unary
213math functions that are valid with complex arguments and are
214required to use $code AD< std::complex<double> >$$.
215$codep */
216namespace CppAD {
217        CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cos)
218        CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cosh)
219        CPPAD_STANDARD_MATH_UNARY(std::complex<double>, exp)
220        CPPAD_STANDARD_MATH_UNARY(std::complex<double>, log)
221        CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sin)
222        CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sinh)
223        CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sqrt)
224}
225/* $$
226
227$head Invalid Unary Math$$
228The following macro definition and invocations define the standard unary
229math functions that are invalid with complex arguments and are
230required to use $code AD< std::complex<double> >$$.
231$codep */
232# undef  CPPAD_USER_MACRO
233# define CPPAD_USER_MACRO(Fun)                                     \
234inline std::complex<double> Fun(const std::complex<double>& x)     \
235{      CppAD::ErrorHandler::Call(                                  \
236               true     , __LINE__ , __FILE__ ,                    \
237               #Fun"(x)",                                          \
238               "Error: cannot use " #Fun " with x complex<double> " \
239       );                                                          \
240       return std::complex<double>(0);                             \
241}
242namespace CppAD {
243        CPPAD_USER_MACRO(abs)
244        CPPAD_USER_MACRO(acos)
245        CPPAD_USER_MACRO(asin)
246        CPPAD_USER_MACRO(atan)
247        CPPAD_USER_MACRO(sign)
248# if CPPAD_COMPILER_HAS_ASINH
249        CPPAD_USER_MACRO(asinh)
250# endif
251# if CPPAD_COMPILER_HAS_ACOSH
252        CPPAD_USER_MACRO(acosh)
253# endif
254}
255/* $$
256
257$head pow $$
258The following defines a $code CppAD::pow$$ function that
259is required to use $code AD< std::complex<double> >$$:
260$codep */
261namespace CppAD {
262        inline std::complex<double> pow(
263                const std::complex<double> &x ,
264                const std::complex<double> &y )
265        {       return std::pow(x, y); }
266}
267/*$$
268
269$head limits$$
270The following defines the numeric limits functions
271$code epsilon$$, $code min$$, and $code max$$ for the type
272$code std::complex<double>$$.
273It also defines the deprecated $code epsilon$$ function:
274$codep */
275namespace CppAD {
276        template <>
277        class numeric_limits< std::complex<double> > {
278        public:
279                // machine epsilon
280                static  std::complex<double> epsilon(void)
281                {       double eps = std::numeric_limits<double>::epsilon();
282                        return std::complex<double>(eps, 0.0);
283                }
284                // minimum positive normalized value
285                static  std::complex<double> min(void)
286                {       double min = std::numeric_limits<double>::min();
287                        return std::complex<double>(min, 0.0);
288                }
289                // maximum finite value
290                static  std::complex<double> max(void)
291                {       double max = std::numeric_limits<double>::max();
292                        return std::complex<double>(max, 0.0);
293                }
294        };
295        // deprecated machine epsilon
296        template <>
297        inline std::complex<double> epsilon< std::complex<double> > (void)
298        {       return numeric_limits< std::complex<double> >::epsilon(); }
299}
300/* $$
301$end
302*/
303# undef  CPPAD_USER_MACRO_ONE
304# define CPPAD_USER_MACRO_ONE(Fun)                                 \
305inline bool Fun(const std::complex<float>& x)                      \
306{      CppAD::ErrorHandler::Call(                                  \
307               true     , __LINE__ , __FILE__ ,                    \
308               #Fun"(x)",                                          \
309               "Error: cannot use " #Fun " with x complex<float> " \
310       );                                                          \
311       return false;                                               \
312}
313# undef  CPPAD_USER_MACRO_TWO
314# define CPPAD_USER_MACRO_TWO(Fun)                                 \
315inline std::complex<float> Fun(const std::complex<float>& x)       \
316{      CppAD::ErrorHandler::Call(                                  \
317               true     , __LINE__ , __FILE__ ,                    \
318               #Fun"(x)",                                          \
319               "Error: cannot use " #Fun " with x complex<float> " \
320       );                                                          \
321       return std::complex<float>(0);                              \
322}
323namespace CppAD {
324        // CondExpOp ------------------------------------------------------
325        inline std::complex<float> CondExpOp(
326                enum CppAD::CompareOp      cop       ,
327                const std::complex<float> &left      ,
328                const std::complex<float> &right     ,
329                const std::complex<float> &trueCase  ,
330                const std::complex<float> &falseCase )
331        {       CppAD::ErrorHandler::Call(
332                        true     , __LINE__ , __FILE__ ,
333                        "std::complex<float> CondExpOp(...)",
334                        "Error: cannot use CondExp with a complex type"
335                );
336                return std::complex<float>(0);
337        }
338        // CondExpRel --------------------------------------------------------
339        CPPAD_COND_EXP_REL( std::complex<float> )
340        // EqualOpSeq -----------------------------------------------------
341        inline bool EqualOpSeq(
342                const std::complex<float> &x ,
343                const std::complex<float> &y )
344        {       return x == y;
345        }
346        // Identical ------------------------------------------------------
347        inline bool IdenticalPar(const std::complex<float> &x)
348        {       return true; }
349        inline bool IdenticalZero(const std::complex<float> &x)
350        {       return (x == std::complex<float>(0., 0.) ); }
351        inline bool IdenticalOne(const std::complex<float> &x)
352        {       return (x == std::complex<float>(1., 0.) ); }
353        inline bool IdenticalEqualPar(
354                const std::complex<float> &x, const std::complex<float> &y)
355        {       return (x == y); }
356        // Ordered --------------------------------------------------------
357        CPPAD_USER_MACRO_ONE(LessThanZero)
358        CPPAD_USER_MACRO_ONE(LessThanOrZero)
359        CPPAD_USER_MACRO_ONE(GreaterThanOrZero)
360        CPPAD_USER_MACRO_ONE(GreaterThanZero)
361        inline bool abs_geq(
362                const std::complex<float>& x ,
363                const std::complex<float>& y )
364        {       return std::abs(x) >= std::abs(y); }
365        // Integer ------------------------------------------------------
366        inline int Integer(const std::complex<float> &x)
367        {       return static_cast<int>( x.real() ); }
368        // isnan -------------------------------------------------------------
369        inline bool isnan(const std::complex<float>& z)
370        {       return (z != z);
371        }
372        // Valid standard math functions --------------------------------
373        CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cos)
374        CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cosh)
375        CPPAD_STANDARD_MATH_UNARY(std::complex<float>, exp)
376        CPPAD_STANDARD_MATH_UNARY(std::complex<float>, log)
377        CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sin)
378        CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sinh)
379        CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sqrt)
380        // Invalid standrd math functions -------------------------------
381        CPPAD_USER_MACRO_TWO(abs)
382        CPPAD_USER_MACRO_TWO(acos)
383        CPPAD_USER_MACRO_TWO(asin)
384        CPPAD_USER_MACRO_TWO(atan)
385        CPPAD_USER_MACRO_TWO(sign)
386        // The pow function
387        inline std::complex<float> pow(
388                const std::complex<float> &x ,
389                const std::complex<float> &y )
390        {       return std::pow(x, y); }
391        // numeric_limits -------------------------------------------------
392        template <>
393        class numeric_limits< std::complex<float> > {
394        public:
395                /// machine epsilon
396                static  std::complex<float> epsilon(void)
397                {       float eps = std::numeric_limits<float>::epsilon();
398                        return std::complex<float>(eps, 0.0);
399                }
400                /// minimum positive normalized value
401                static  std::complex<float> min(void)
402                {       float min = std::numeric_limits<float>::min();
403                        return std::complex<float>(min, 0.0);
404                }
405                /// maximum finite value
406                static  std::complex<float> max(void)
407                {       float max = std::numeric_limits<float>::max();
408                        return std::complex<float>(max, 0.0);
409                }
410        };
411        template <>
412        inline std::complex<float> epsilon< std::complex<float> >(void)
413        {       return numeric_limits< std::complex<float> >::epsilon(); }
414}
415
416// undefine macros only used by this file
417# undef CPPAD_USER_MACRO
418# undef CPPAD_USER_MACRO_ONE
419# undef CPPAD_USER_MACRO_TWO
420
421# endif
Note: See TracBrowser for help on using the repository browser.