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