MathFunctions.h revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_MATHFUNCTIONS_H
11#define EIGEN_MATHFUNCTIONS_H
12
13namespace Eigen {
14
15namespace internal {
16
17/** \internal \struct global_math_functions_filtering_base
18  *
19  * What it does:
20  * Defines a typedef 'type' as follows:
21  * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then
22  *   global_math_functions_filtering_base<T>::type is a typedef for it.
23  * - otherwise, global_math_functions_filtering_base<T>::type is a typedef for T.
24  *
25  * How it's used:
26  * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions.
27  * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know
28  * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase<Derived>.
29  * So we must make sure to use sin_impl<ArrayBase<Derived> > and not sin_impl<Derived>, otherwise our partial specialization
30  * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it.
31  *
32  * How it's implemented:
33  * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace
34  * the typename dummy by an integer template parameter, it doesn't work anymore!
35  */
36
37template<typename T, typename dummy = void>
38struct global_math_functions_filtering_base
39{
40  typedef T type;
41};
42
43template<typename T> struct always_void { typedef void type; };
44
45template<typename T>
46struct global_math_functions_filtering_base
47  <T,
48   typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
49  >
50{
51  typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
52};
53
54#define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type>
55#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type
56
57
58/****************************************************************************
59* Implementation of real                                                 *
60****************************************************************************/
61
62template<typename Scalar>
63struct real_impl
64{
65  typedef typename NumTraits<Scalar>::Real RealScalar;
66  static inline RealScalar run(const Scalar& x)
67  {
68    return x;
69  }
70};
71
72template<typename RealScalar>
73struct real_impl<std::complex<RealScalar> >
74{
75  static inline RealScalar run(const std::complex<RealScalar>& x)
76  {
77    using std::real;
78    return real(x);
79  }
80};
81
82template<typename Scalar>
83struct real_retval
84{
85  typedef typename NumTraits<Scalar>::Real type;
86};
87
88template<typename Scalar>
89inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
90{
91  return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
92}
93
94/****************************************************************************
95* Implementation of imag                                                 *
96****************************************************************************/
97
98template<typename Scalar>
99struct imag_impl
100{
101  typedef typename NumTraits<Scalar>::Real RealScalar;
102  static inline RealScalar run(const Scalar&)
103  {
104    return RealScalar(0);
105  }
106};
107
108template<typename RealScalar>
109struct imag_impl<std::complex<RealScalar> >
110{
111  static inline RealScalar run(const std::complex<RealScalar>& x)
112  {
113    using std::imag;
114    return imag(x);
115  }
116};
117
118template<typename Scalar>
119struct imag_retval
120{
121  typedef typename NumTraits<Scalar>::Real type;
122};
123
124template<typename Scalar>
125inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
126{
127  return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
128}
129
130/****************************************************************************
131* Implementation of real_ref                                             *
132****************************************************************************/
133
134template<typename Scalar>
135struct real_ref_impl
136{
137  typedef typename NumTraits<Scalar>::Real RealScalar;
138  static inline RealScalar& run(Scalar& x)
139  {
140    return reinterpret_cast<RealScalar*>(&x)[0];
141  }
142  static inline const RealScalar& run(const Scalar& x)
143  {
144    return reinterpret_cast<const RealScalar*>(&x)[0];
145  }
146};
147
148template<typename Scalar>
149struct real_ref_retval
150{
151  typedef typename NumTraits<Scalar>::Real & type;
152};
153
154template<typename Scalar>
155inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
156{
157  return real_ref_impl<Scalar>::run(x);
158}
159
160template<typename Scalar>
161inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
162{
163  return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
164}
165
166/****************************************************************************
167* Implementation of imag_ref                                             *
168****************************************************************************/
169
170template<typename Scalar, bool IsComplex>
171struct imag_ref_default_impl
172{
173  typedef typename NumTraits<Scalar>::Real RealScalar;
174  static inline RealScalar& run(Scalar& x)
175  {
176    return reinterpret_cast<RealScalar*>(&x)[1];
177  }
178  static inline const RealScalar& run(const Scalar& x)
179  {
180    return reinterpret_cast<RealScalar*>(&x)[1];
181  }
182};
183
184template<typename Scalar>
185struct imag_ref_default_impl<Scalar, false>
186{
187  static inline Scalar run(Scalar&)
188  {
189    return Scalar(0);
190  }
191  static inline const Scalar run(const Scalar&)
192  {
193    return Scalar(0);
194  }
195};
196
197template<typename Scalar>
198struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
199
200template<typename Scalar>
201struct imag_ref_retval
202{
203  typedef typename NumTraits<Scalar>::Real & type;
204};
205
206template<typename Scalar>
207inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
208{
209  return imag_ref_impl<Scalar>::run(x);
210}
211
212template<typename Scalar>
213inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
214{
215  return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
216}
217
218/****************************************************************************
219* Implementation of conj                                                 *
220****************************************************************************/
221
222template<typename Scalar>
223struct conj_impl
224{
225  static inline Scalar run(const Scalar& x)
226  {
227    return x;
228  }
229};
230
231template<typename RealScalar>
232struct conj_impl<std::complex<RealScalar> >
233{
234  static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x)
235  {
236    using std::conj;
237    return conj(x);
238  }
239};
240
241template<typename Scalar>
242struct conj_retval
243{
244  typedef Scalar type;
245};
246
247template<typename Scalar>
248inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
249{
250  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
251}
252
253/****************************************************************************
254* Implementation of abs                                                  *
255****************************************************************************/
256
257template<typename Scalar>
258struct abs_impl
259{
260  typedef typename NumTraits<Scalar>::Real RealScalar;
261  static inline RealScalar run(const Scalar& x)
262  {
263    using std::abs;
264    return abs(x);
265  }
266};
267
268template<typename Scalar>
269struct abs_retval
270{
271  typedef typename NumTraits<Scalar>::Real type;
272};
273
274template<typename Scalar>
275inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(const Scalar& x)
276{
277  return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x);
278}
279
280/****************************************************************************
281* Implementation of abs2                                                 *
282****************************************************************************/
283
284template<typename Scalar>
285struct abs2_impl
286{
287  typedef typename NumTraits<Scalar>::Real RealScalar;
288  static inline RealScalar run(const Scalar& x)
289  {
290    return x*x;
291  }
292};
293
294template<typename RealScalar>
295struct abs2_impl<std::complex<RealScalar> >
296{
297  static inline RealScalar run(const std::complex<RealScalar>& x)
298  {
299    return real(x)*real(x) + imag(x)*imag(x);
300  }
301};
302
303template<typename Scalar>
304struct abs2_retval
305{
306  typedef typename NumTraits<Scalar>::Real type;
307};
308
309template<typename Scalar>
310inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
311{
312  return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
313}
314
315/****************************************************************************
316* Implementation of norm1                                                *
317****************************************************************************/
318
319template<typename Scalar, bool IsComplex>
320struct norm1_default_impl
321{
322  typedef typename NumTraits<Scalar>::Real RealScalar;
323  static inline RealScalar run(const Scalar& x)
324  {
325    return abs(real(x)) + abs(imag(x));
326  }
327};
328
329template<typename Scalar>
330struct norm1_default_impl<Scalar, false>
331{
332  static inline Scalar run(const Scalar& x)
333  {
334    return abs(x);
335  }
336};
337
338template<typename Scalar>
339struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
340
341template<typename Scalar>
342struct norm1_retval
343{
344  typedef typename NumTraits<Scalar>::Real type;
345};
346
347template<typename Scalar>
348inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
349{
350  return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
351}
352
353/****************************************************************************
354* Implementation of hypot                                                *
355****************************************************************************/
356
357template<typename Scalar>
358struct hypot_impl
359{
360  typedef typename NumTraits<Scalar>::Real RealScalar;
361  static inline RealScalar run(const Scalar& x, const Scalar& y)
362  {
363    using std::max;
364    using std::min;
365    RealScalar _x = abs(x);
366    RealScalar _y = abs(y);
367    RealScalar p = (max)(_x, _y);
368    RealScalar q = (min)(_x, _y);
369    RealScalar qp = q/p;
370    return p * sqrt(RealScalar(1) + qp*qp);
371  }
372};
373
374template<typename Scalar>
375struct hypot_retval
376{
377  typedef typename NumTraits<Scalar>::Real type;
378};
379
380template<typename Scalar>
381inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
382{
383  return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
384}
385
386/****************************************************************************
387* Implementation of cast                                                 *
388****************************************************************************/
389
390template<typename OldType, typename NewType>
391struct cast_impl
392{
393  static inline NewType run(const OldType& x)
394  {
395    return static_cast<NewType>(x);
396  }
397};
398
399// here, for once, we're plainly returning NewType: we don't want cast to do weird things.
400
401template<typename OldType, typename NewType>
402inline NewType cast(const OldType& x)
403{
404  return cast_impl<OldType, NewType>::run(x);
405}
406
407/****************************************************************************
408* Implementation of sqrt                                                 *
409****************************************************************************/
410
411template<typename Scalar, bool IsInteger>
412struct sqrt_default_impl
413{
414  static inline Scalar run(const Scalar& x)
415  {
416    using std::sqrt;
417    return sqrt(x);
418  }
419};
420
421template<typename Scalar>
422struct sqrt_default_impl<Scalar, true>
423{
424  static inline Scalar run(const Scalar&)
425  {
426#ifdef EIGEN2_SUPPORT
427    eigen_assert(!NumTraits<Scalar>::IsInteger);
428#else
429    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
430#endif
431    return Scalar(0);
432  }
433};
434
435template<typename Scalar>
436struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
437
438template<typename Scalar>
439struct sqrt_retval
440{
441  typedef Scalar type;
442};
443
444template<typename Scalar>
445inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x)
446{
447  return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
448}
449
450/****************************************************************************
451* Implementation of standard unary real functions (exp, log, sin, cos, ...  *
452****************************************************************************/
453
454// This macro instanciate all the necessary template mechanism which is common to all unary real functions.
455#define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
456  template<typename Scalar, bool IsInteger> struct NAME##_default_impl {            \
457    static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); }  \
458  };                                                                                \
459  template<typename Scalar> struct NAME##_default_impl<Scalar, true> {              \
460    static inline Scalar run(const Scalar&) {                                       \
461      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)                                       \
462      return Scalar(0);                                                             \
463    }                                                                               \
464  };                                                                                \
465  template<typename Scalar> struct NAME##_impl                                      \
466    : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger>                     \
467  {};                                                                               \
468  template<typename Scalar> struct NAME##_retval { typedef Scalar type; };          \
469  template<typename Scalar>                                                         \
470  inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) {                \
471    return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x);                               \
472  }
473
474EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
475EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
476EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
477EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
478EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
479EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
480EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
481
482/****************************************************************************
483* Implementation of atan2                                                *
484****************************************************************************/
485
486template<typename Scalar, bool IsInteger>
487struct atan2_default_impl
488{
489  typedef Scalar retval;
490  static inline Scalar run(const Scalar& x, const Scalar& y)
491  {
492    using std::atan2;
493    return atan2(x, y);
494  }
495};
496
497template<typename Scalar>
498struct atan2_default_impl<Scalar, true>
499{
500  static inline Scalar run(const Scalar&, const Scalar&)
501  {
502    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
503    return Scalar(0);
504  }
505};
506
507template<typename Scalar>
508struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
509
510template<typename Scalar>
511struct atan2_retval
512{
513  typedef Scalar type;
514};
515
516template<typename Scalar>
517inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y)
518{
519  return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
520}
521
522/****************************************************************************
523* Implementation of pow                                                  *
524****************************************************************************/
525
526template<typename Scalar, bool IsInteger>
527struct pow_default_impl
528{
529  typedef Scalar retval;
530  static inline Scalar run(const Scalar& x, const Scalar& y)
531  {
532    using std::pow;
533    return pow(x, y);
534  }
535};
536
537template<typename Scalar>
538struct pow_default_impl<Scalar, true>
539{
540  static inline Scalar run(Scalar x, Scalar y)
541  {
542    Scalar res(1);
543    eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
544    if(y & 1) res *= x;
545    y >>= 1;
546    while(y)
547    {
548      x *= x;
549      if(y&1) res *= x;
550      y >>= 1;
551    }
552    return res;
553  }
554};
555
556template<typename Scalar>
557struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
558
559template<typename Scalar>
560struct pow_retval
561{
562  typedef Scalar type;
563};
564
565template<typename Scalar>
566inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
567{
568  return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
569}
570
571/****************************************************************************
572* Implementation of random                                               *
573****************************************************************************/
574
575template<typename Scalar,
576         bool IsComplex,
577         bool IsInteger>
578struct random_default_impl {};
579
580template<typename Scalar>
581struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
582
583template<typename Scalar>
584struct random_retval
585{
586  typedef Scalar type;
587};
588
589template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
590template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
591
592template<typename Scalar>
593struct random_default_impl<Scalar, false, false>
594{
595  static inline Scalar run(const Scalar& x, const Scalar& y)
596  {
597    return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
598  }
599  static inline Scalar run()
600  {
601    return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
602  }
603};
604
605enum {
606  floor_log2_terminate,
607  floor_log2_move_up,
608  floor_log2_move_down,
609  floor_log2_bogus
610};
611
612template<unsigned int n, int lower, int upper> struct floor_log2_selector
613{
614  enum { middle = (lower + upper) / 2,
615         value = (upper <= lower + 1) ? int(floor_log2_terminate)
616               : (n < (1 << middle)) ? int(floor_log2_move_down)
617               : (n==0) ? int(floor_log2_bogus)
618               : int(floor_log2_move_up)
619  };
620};
621
622template<unsigned int n,
623         int lower = 0,
624         int upper = sizeof(unsigned int) * CHAR_BIT - 1,
625         int selector = floor_log2_selector<n, lower, upper>::value>
626struct floor_log2 {};
627
628template<unsigned int n, int lower, int upper>
629struct floor_log2<n, lower, upper, floor_log2_move_down>
630{
631  enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
632};
633
634template<unsigned int n, int lower, int upper>
635struct floor_log2<n, lower, upper, floor_log2_move_up>
636{
637  enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
638};
639
640template<unsigned int n, int lower, int upper>
641struct floor_log2<n, lower, upper, floor_log2_terminate>
642{
643  enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
644};
645
646template<unsigned int n, int lower, int upper>
647struct floor_log2<n, lower, upper, floor_log2_bogus>
648{
649  // no value, error at compile time
650};
651
652template<typename Scalar>
653struct random_default_impl<Scalar, false, true>
654{
655  typedef typename NumTraits<Scalar>::NonInteger NonInteger;
656
657  static inline Scalar run(const Scalar& x, const Scalar& y)
658  {
659    return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
660  }
661
662  static inline Scalar run()
663  {
664#ifdef EIGEN_MAKING_DOCS
665    return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
666#else
667    enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
668           scalar_bits = sizeof(Scalar) * CHAR_BIT,
669           shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits))
670    };
671    Scalar x = Scalar(std::rand() >> shift);
672    Scalar offset = NumTraits<Scalar>::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0);
673    return x - offset;
674#endif
675  }
676};
677
678template<typename Scalar>
679struct random_default_impl<Scalar, true, false>
680{
681  static inline Scalar run(const Scalar& x, const Scalar& y)
682  {
683    return Scalar(random(real(x), real(y)),
684                  random(imag(x), imag(y)));
685  }
686  static inline Scalar run()
687  {
688    typedef typename NumTraits<Scalar>::Real RealScalar;
689    return Scalar(random<RealScalar>(), random<RealScalar>());
690  }
691};
692
693template<typename Scalar>
694inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
695{
696  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
697}
698
699template<typename Scalar>
700inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
701{
702  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
703}
704
705/****************************************************************************
706* Implementation of fuzzy comparisons                                       *
707****************************************************************************/
708
709template<typename Scalar,
710         bool IsComplex,
711         bool IsInteger>
712struct scalar_fuzzy_default_impl {};
713
714template<typename Scalar>
715struct scalar_fuzzy_default_impl<Scalar, false, false>
716{
717  typedef typename NumTraits<Scalar>::Real RealScalar;
718  template<typename OtherScalar>
719  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
720  {
721    return abs(x) <= abs(y) * prec;
722  }
723  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
724  {
725    using std::min;
726    return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
727  }
728  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
729  {
730    return x <= y || isApprox(x, y, prec);
731  }
732};
733
734template<typename Scalar>
735struct scalar_fuzzy_default_impl<Scalar, false, true>
736{
737  typedef typename NumTraits<Scalar>::Real RealScalar;
738  template<typename OtherScalar>
739  static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
740  {
741    return x == Scalar(0);
742  }
743  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
744  {
745    return x == y;
746  }
747  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
748  {
749    return x <= y;
750  }
751};
752
753template<typename Scalar>
754struct scalar_fuzzy_default_impl<Scalar, true, false>
755{
756  typedef typename NumTraits<Scalar>::Real RealScalar;
757  template<typename OtherScalar>
758  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
759  {
760    return abs2(x) <= abs2(y) * prec * prec;
761  }
762  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
763  {
764    using std::min;
765    return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec;
766  }
767};
768
769template<typename Scalar>
770struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
771
772template<typename Scalar, typename OtherScalar>
773inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
774                                   typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
775{
776  return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
777}
778
779template<typename Scalar>
780inline bool isApprox(const Scalar& x, const Scalar& y,
781                          typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
782{
783  return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
784}
785
786template<typename Scalar>
787inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
788                                    typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
789{
790  return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
791}
792
793/******************************************
794***  The special case of the  bool type ***
795******************************************/
796
797template<> struct random_impl<bool>
798{
799  static inline bool run()
800  {
801    return random<int>(0,1)==0 ? false : true;
802  }
803};
804
805template<> struct scalar_fuzzy_impl<bool>
806{
807  typedef bool RealScalar;
808
809  template<typename OtherScalar>
810  static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
811  {
812    return !x;
813  }
814
815  static inline bool isApprox(bool x, bool y, bool)
816  {
817    return x == y;
818  }
819
820  static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
821  {
822    return (!x) || y;
823  }
824
825};
826
827/****************************************************************************
828* Special functions                                                          *
829****************************************************************************/
830
831// std::isfinite is non standard, so let's define our own version,
832// even though it is not very efficient.
833template<typename T> bool (isfinite)(const T& x)
834{
835  return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
836}
837
838} // end namespace internal
839
840} // end namespace Eigen
841
842#endif // EIGEN_MATHFUNCTIONS_H
843