1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_MATHFUNCTIONS_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_MATHFUNCTIONS_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal \struct global_math_functions_filtering_base
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * What it does:
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * Defines a typedef 'type' as follows:
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *   global_math_functions_filtering_base<T>::type is a typedef for it.
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * - otherwise, global_math_functions_filtering_base<T>::type is a typedef for T.
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * How it's used:
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions.
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase<Derived>.
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * So we must make sure to use sin_impl<ArrayBase<Derived> > and not sin_impl<Derived>, otherwise our partial specialization
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it.
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * How it's implemented:
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * the typename dummy by an integer template parameter, it doesn't work anymore!
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename dummy = void>
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct global_math_functions_filtering_base
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef T type;
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct always_void { typedef void type; };
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T>
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct global_math_functions_filtering_base
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  <T,
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath   typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  >
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of real                                                 *
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct real_default_impl
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar run(const Scalar& x)
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x;
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct real_default_impl<Scalar,true>
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef typename NumTraits<Scalar>::Real RealScalar;
757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static inline RealScalar run(const Scalar& x)
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::real;
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return real(x);
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct real_retval
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real type;
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of imag                                                 *
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct imag_default_impl
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar run(const Scalar&)
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return RealScalar(0);
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
1067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct imag_default_impl<Scalar,true>
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
1087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef typename NumTraits<Scalar>::Real RealScalar;
1097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static inline RealScalar run(const Scalar& x)
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::imag;
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return imag(x);
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
1177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct imag_retval
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real type;
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of real_ref                                             *
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct real_ref_impl
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar& run(Scalar& x)
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return reinterpret_cast<RealScalar*>(&x)[0];
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline const RealScalar& run(const Scalar& x)
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return reinterpret_cast<const RealScalar*>(&x)[0];
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct real_ref_retval
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real & type;
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of imag_ref                                             *
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, bool IsComplex>
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct imag_ref_default_impl
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar& run(Scalar& x)
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return reinterpret_cast<RealScalar*>(&x)[1];
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline const RealScalar& run(const Scalar& x)
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return reinterpret_cast<RealScalar*>(&x)[1];
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct imag_ref_default_impl<Scalar, false>
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(Scalar&)
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return Scalar(0);
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline const Scalar run(const Scalar&)
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return Scalar(0);
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct imag_ref_retval
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real & type;
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of conj                                                 *
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conj_impl
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar& x)
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x;
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
2027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct conj_impl<Scalar,true>
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
2047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static inline Scalar run(const Scalar& x)
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::conj;
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return conj(x);
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conj_retval
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Scalar type;
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of abs2                                                 *
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct abs2_impl
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar run(const Scalar& x)
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x*x;
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename RealScalar>
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct abs2_impl<std::complex<RealScalar> >
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar run(const std::complex<RealScalar>& x)
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return real(x)*real(x) + imag(x)*imag(x);
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct abs2_retval
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real type;
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of norm1                                                *
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, bool IsComplex>
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct norm1_default_impl
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar run(const Scalar& x)
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
2567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return abs(real(x)) + abs(imag(x));
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct norm1_default_impl<Scalar, false>
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar& x)
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
2667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return abs(x);
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct norm1_retval
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real type;
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of hypot                                                *
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct hypot_impl
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline RealScalar run(const Scalar& x, const Scalar& y)
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::max;
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::min;
2927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
2937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::sqrt;
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar _x = abs(x);
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar _y = abs(y);
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar p = (max)(_x, _y);
2977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if(p==RealScalar(0)) return 0;
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar q = (min)(_x, _y);
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar qp = q/p;
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return p * sqrt(RealScalar(1) + qp*qp);
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct hypot_retval
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real type;
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of cast                                                 *
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OldType, typename NewType>
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct cast_impl
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline NewType run(const OldType& x)
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return static_cast<NewType>(x);
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// here, for once, we're plainly returning NewType: we don't want cast to do weird things.
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OldType, typename NewType>
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline NewType cast(const OldType& x)
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return cast_impl<OldType, NewType>::run(x);
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
3327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez* Implementation of atanh2                                                *
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, bool IsInteger>
3367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct atanh2_default_impl
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Scalar retval;
3397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef typename NumTraits<Scalar>::Real RealScalar;
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar& x, const Scalar& y)
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
3427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
3437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::log;
3447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::sqrt;
3457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    Scalar z = x / y;
3467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (y == Scalar(0) || abs(z) > sqrt(NumTraits<RealScalar>::epsilon()))
3477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return RealScalar(0.5) * log((y + x) / (y - x));
3487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    else
3497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return z + z*z*z / RealScalar(3);
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
3547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct atanh2_default_impl<Scalar, true>
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar&, const Scalar&)
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return Scalar(0);
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
3647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct atanh2_impl : atanh2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
3677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstruct atanh2_retval
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Scalar type;
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of pow                                                  *
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, bool IsInteger>
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct pow_default_impl
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Scalar retval;
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar& x, const Scalar& y)
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::pow;
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return pow(x, y);
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct pow_default_impl<Scalar, true>
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(Scalar x, Scalar y)
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar res(1);
393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(y & 1) res *= x;
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    y >>= 1;
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    while(y)
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      x *= x;
399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(y&1) res *= x;
400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      y >>= 1;
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return res;
403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct pow_retval
411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Scalar type;
413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of random                                               *
417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar,
420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         bool IsComplex,
421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         bool IsInteger>
422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct random_default_impl {};
423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
426c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct random_retval
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Scalar type;
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
437c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct random_default_impl<Scalar, false, false>
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar& x, const Scalar& y)
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run()
444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathenum {
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  floor_log2_terminate,
451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  floor_log2_move_up,
452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  floor_log2_move_down,
453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  floor_log2_bogus
454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<unsigned int n, int lower, int upper> struct floor_log2_selector
457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { middle = (lower + upper) / 2,
459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         value = (upper <= lower + 1) ? int(floor_log2_terminate)
460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath               : (n < (1 << middle)) ? int(floor_log2_move_down)
461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath               : (n==0) ? int(floor_log2_bogus)
462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath               : int(floor_log2_move_up)
463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<unsigned int n,
467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int lower = 0,
468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int upper = sizeof(unsigned int) * CHAR_BIT - 1,
469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int selector = floor_log2_selector<n, lower, upper>::value>
470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct floor_log2 {};
471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<unsigned int n, int lower, int upper>
473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct floor_log2<n, lower, upper, floor_log2_move_down>
474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<unsigned int n, int lower, int upper>
479c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct floor_log2<n, lower, upper, floor_log2_move_up>
480c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
481c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
482c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
483c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
484c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<unsigned int n, int lower, int upper>
485c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct floor_log2<n, lower, upper, floor_log2_terminate>
486c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<unsigned int n, int lower, int upper>
491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct floor_log2<n, lower, upper, floor_log2_bogus>
492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // no value, error at compile time
494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct random_default_impl<Scalar, false, true>
498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::NonInteger NonInteger;
500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar& x, const Scalar& y)
502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
504c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
505c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
506c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run()
507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifdef EIGEN_MAKING_DOCS
509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
510c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#else
511c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
512c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           scalar_bits = sizeof(Scalar) * CHAR_BIT,
5137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez           shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
5147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez           offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
515c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
5167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return Scalar((std::rand() >> shift) - offset);
517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
521c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
522c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct random_default_impl<Scalar, true, false>
523c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
524c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run(const Scalar& x, const Scalar& y)
525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return Scalar(random(real(x), real(y)),
527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                  random(imag(x), imag(y)));
528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
529c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar run()
530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
531c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename NumTraits<Scalar>::Real RealScalar;
532c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return Scalar(random<RealScalar>(), random<RealScalar>());
533c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
534c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
535c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
536c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
537c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
538c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
539c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
540c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
541c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
542c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
543c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
544c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
545c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
546c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
547c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
5487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} // end namespace internal
5497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/****************************************************************************
5517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez* Generic math function                                                    *
5527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez****************************************************************************/
5537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace numext {
5557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
5587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
5597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
5607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
5617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
5647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
5657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return internal::real_ref_impl<Scalar>::run(x);
5667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
5677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
5707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
5717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
5727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
5737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
5767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
5777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
5787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
5797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
5827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
5837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return internal::imag_ref_impl<Scalar>::run(x);
5847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
5857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
5887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
5897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
5907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
5917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
5947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
5957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
5967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
5977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
5987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
5997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
6007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
6017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
6027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
6037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
6057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
6067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
6077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
6087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
6097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
6117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
6127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
6137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
6147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
6157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
6177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y)
6187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
6197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y);
6207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
6217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar>
6237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezinline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
6247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
6257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
6267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
6277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// std::isfinite is non standard, so let's define our own version,
6297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// even though it is not very efficient.
6307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename T> bool (isfinite)(const T& x)
6317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
6327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
6337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
6347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} // end namespace numext
6367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
6377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace internal {
6387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
639c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/****************************************************************************
640c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of fuzzy comparisons                                       *
641c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************************************************************/
642c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
643c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar,
644c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         bool IsComplex,
645c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         bool IsInteger>
646c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct scalar_fuzzy_default_impl {};
647c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
648c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
649c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct scalar_fuzzy_default_impl<Scalar, false, false>
650c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
651c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
652c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename OtherScalar>
653c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
654c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
6557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
656c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return abs(x) <= abs(y) * prec;
657c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
658c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
659c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
660c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::min;
6617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
662c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
663c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
664c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
665c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
666c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x <= y || isApprox(x, y, prec);
667c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
668c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
669c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
670c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
671c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct scalar_fuzzy_default_impl<Scalar, false, true>
672c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
673c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
674c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename OtherScalar>
675c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
676c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
677c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x == Scalar(0);
678c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
679c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
680c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
681c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x == y;
682c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
683c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
684c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
685c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x <= y;
686c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
687c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
688c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
689c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
690c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct scalar_fuzzy_default_impl<Scalar, true, false>
691c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
692c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
693c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename OtherScalar>
694c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
695c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
6967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return numext::abs2(x) <= numext::abs2(y) * prec * prec;
697c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
698c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
699c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
700c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using std::min;
7017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec;
702c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
703c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
704c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
705c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
706c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
707c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
708c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename OtherScalar>
709c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
710c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                   typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
711c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
712c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
713c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
714c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
715c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
716c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline bool isApprox(const Scalar& x, const Scalar& y,
717c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
718c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
719c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
720c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
721c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
722c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar>
723c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
724c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                    typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
725c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
726c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
727c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
728c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
729c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/******************************************
730c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***  The special case of the  bool type ***
731c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath******************************************/
732c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
733c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct random_impl<bool>
734c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
735c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool run()
736c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
737c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return random<int>(0,1)==0 ? false : true;
738c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
739c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
740c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
741c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct scalar_fuzzy_impl<bool>
742c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
743c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef bool RealScalar;
744c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
745c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename OtherScalar>
746c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
747c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
748c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return !x;
749c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
750c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
751c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isApprox(bool x, bool y, bool)
752c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
753c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return x == y;
754c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
755c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
756c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
757