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
13namespace Eigen {
14
15namespace internal {
16
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
Definition LDLT.h:18