MathFunctions.h
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 
13 namespace Eigen {
14 
15 namespace internal {
16 
37 template<typename T, typename dummy = void>
38 struct global_math_functions_filtering_base
39 {
40  typedef T type;
41 };
42 
43 template<typename T> struct always_void { typedef void type; };
44 
45 template<typename T>
46 struct 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 
62 template<typename Scalar>
63 struct 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 
72 template<typename RealScalar>
73 struct 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 
82 template<typename Scalar>
83 struct real_retval
84 {
85  typedef typename NumTraits<Scalar>::Real type;
86 };
87 
88 template<typename Scalar>
89 inline 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 
98 template<typename Scalar>
99 struct 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 
108 template<typename RealScalar>
109 struct 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 
118 template<typename Scalar>
119 struct imag_retval
120 {
121  typedef typename NumTraits<Scalar>::Real type;
122 };
123 
124 template<typename Scalar>
125 inline 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 
134 template<typename Scalar>
135 struct 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 
148 template<typename Scalar>
149 struct real_ref_retval
150 {
151  typedef typename NumTraits<Scalar>::Real & type;
152 };
153 
154 template<typename Scalar>
155 inline 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 
160 template<typename Scalar>
161 inline 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 
170 template<typename Scalar, bool IsComplex>
171 struct 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 
184 template<typename Scalar>
185 struct 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 
197 template<typename Scalar>
198 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
199 
200 template<typename Scalar>
201 struct imag_ref_retval
202 {
203  typedef typename NumTraits<Scalar>::Real & type;
204 };
205 
206 template<typename Scalar>
207 inline 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 
212 template<typename Scalar>
213 inline 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 
222 template<typename Scalar>
223 struct conj_impl
224 {
225  static inline Scalar run(const Scalar& x)
226  {
227  return x;
228  }
229 };
230 
231 template<typename RealScalar>
232 struct 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 
241 template<typename Scalar>
242 struct conj_retval
243 {
244  typedef Scalar type;
245 };
246 
247 template<typename Scalar>
248 inline 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 
257 template<typename Scalar>
258 struct 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 
268 template<typename Scalar>
269 struct abs_retval
270 {
271  typedef typename NumTraits<Scalar>::Real type;
272 };
273 
274 template<typename Scalar>
275 inline 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 
284 template<typename Scalar>
285 struct 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 
294 template<typename RealScalar>
295 struct 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 
303 template<typename Scalar>
304 struct abs2_retval
305 {
306  typedef typename NumTraits<Scalar>::Real type;
307 };
308 
309 template<typename Scalar>
310 inline 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 
319 template<typename Scalar, bool IsComplex>
320 struct 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 
329 template<typename Scalar>
330 struct norm1_default_impl<Scalar, false>
331 {
332  static inline Scalar run(const Scalar& x)
333  {
334  return abs(x);
335  }
336 };
337 
338 template<typename Scalar>
339 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
340 
341 template<typename Scalar>
342 struct norm1_retval
343 {
344  typedef typename NumTraits<Scalar>::Real type;
345 };
346 
347 template<typename Scalar>
348 inline 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 
357 template<typename Scalar>
358 struct 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 
374 template<typename Scalar>
375 struct hypot_retval
376 {
377  typedef typename NumTraits<Scalar>::Real type;
378 };
379 
380 template<typename Scalar>
381 inline 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 
390 template<typename OldType, typename NewType>
391 struct 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 
401 template<typename OldType, typename NewType>
402 inline NewType cast(const OldType& x)
403 {
404  return cast_impl<OldType, NewType>::run(x);
405 }
406 
407 /****************************************************************************
408 * Implementation of sqrt *
409 ****************************************************************************/
410 
411 template<typename Scalar, bool IsInteger>
412 struct sqrt_default_impl
413 {
414  static inline Scalar run(const Scalar& x)
415  {
416  using std::sqrt;
417  return sqrt(x);
418  }
419 };
420 
421 template<typename Scalar>
422 struct 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 
435 template<typename Scalar>
436 struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
437 
438 template<typename Scalar>
439 struct sqrt_retval
440 {
441  typedef Scalar type;
442 };
443 
444 template<typename Scalar>
445 inline 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 
474 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
475 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
476 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
477 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
478 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
479 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
480 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
481 
482 /****************************************************************************
483 * Implementation of atan2 *
484 ****************************************************************************/
485 
486 template<typename Scalar, bool IsInteger>
487 struct 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 
497 template<typename Scalar>
498 struct 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 
507 template<typename Scalar>
508 struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
509 
510 template<typename Scalar>
511 struct atan2_retval
512 {
513  typedef Scalar type;
514 };
515 
516 template<typename Scalar>
517 inline 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 
526 template<typename Scalar, bool IsInteger>
527 struct 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 
537 template<typename Scalar>
538 struct 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 
556 template<typename Scalar>
557 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
558 
559 template<typename Scalar>
560 struct pow_retval
561 {
562  typedef Scalar type;
563 };
564 
565 template<typename Scalar>
566 inline 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 
575 template<typename Scalar,
576  bool IsComplex,
577  bool IsInteger>
578 struct random_default_impl {};
579 
580 template<typename Scalar>
581 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
582 
583 template<typename Scalar>
584 struct random_retval
585 {
586  typedef Scalar type;
587 };
588 
589 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
590 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
591 
592 template<typename Scalar>
593 struct 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 
605 enum {
606  floor_log2_terminate,
607  floor_log2_move_up,
608  floor_log2_move_down,
609  floor_log2_bogus
610 };
611 
612 template<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 
622 template<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>
626 struct floor_log2 {};
627 
628 template<unsigned int n, int lower, int upper>
629 struct 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 
634 template<unsigned int n, int lower, int upper>
635 struct 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 
640 template<unsigned int n, int lower, int upper>
641 struct floor_log2<n, lower, upper, floor_log2_terminate>
642 {
643  enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
644 };
645 
646 template<unsigned int n, int lower, int upper>
647 struct floor_log2<n, lower, upper, floor_log2_bogus>
648 {
649  // no value, error at compile time
650 };
651 
652 template<typename Scalar>
653 struct 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 
678 template<typename Scalar>
679 struct 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 
693 template<typename Scalar>
694 inline 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 
699 template<typename Scalar>
700 inline 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 
709 template<typename Scalar,
710  bool IsComplex,
711  bool IsInteger>
712 struct scalar_fuzzy_default_impl {};
713 
714 template<typename Scalar>
715 struct 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 
734 template<typename Scalar>
735 struct 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 
753 template<typename Scalar>
754 struct 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 
769 template<typename Scalar>
770 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
771 
772 template<typename Scalar, typename OtherScalar>
773 inline 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 
779 template<typename Scalar>
780 inline 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 
786 template<typename Scalar>
787 inline 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 
797 template<> struct random_impl<bool>
798 {
799  static inline bool run()
800  {
801  return random<int>(0,1)==0 ? false : true;
802  }
803 };
804 
805 template<> 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.
833 template<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