source: pacpussensors/trunk/Vislab/lib3dv/eigen/Eigen/src/Core/MathFunctions.h@ 136

Last change on this file since 136 was 136, checked in by ldecherf, 7 years ago

Doc

File size: 21.7 KB
Line 
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) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
55#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
56
57/****************************************************************************
58* Implementation of real *
59****************************************************************************/
60
61template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
62struct real_default_impl
63{
64 typedef typename NumTraits<Scalar>::Real RealScalar;
65 static inline RealScalar run(const Scalar& x)
66 {
67 return x;
68 }
69};
70
71template<typename Scalar>
72struct real_default_impl<Scalar,true>
73{
74 typedef typename NumTraits<Scalar>::Real RealScalar;
75 static inline RealScalar run(const Scalar& x)
76 {
77 using std::real;
78 return real(x);
79 }
80};
81
82template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
83
84template<typename Scalar>
85struct real_retval
86{
87 typedef typename NumTraits<Scalar>::Real type;
88};
89
90
91/****************************************************************************
92* Implementation of imag *
93****************************************************************************/
94
95template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
96struct imag_default_impl
97{
98 typedef typename NumTraits<Scalar>::Real RealScalar;
99 static inline RealScalar run(const Scalar&)
100 {
101 return RealScalar(0);
102 }
103};
104
105template<typename Scalar>
106struct imag_default_impl<Scalar,true>
107{
108 typedef typename NumTraits<Scalar>::Real RealScalar;
109 static inline RealScalar run(const Scalar& x)
110 {
111 using std::imag;
112 return imag(x);
113 }
114};
115
116template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
117
118template<typename Scalar>
119struct imag_retval
120{
121 typedef typename NumTraits<Scalar>::Real type;
122};
123
124/****************************************************************************
125* Implementation of real_ref *
126****************************************************************************/
127
128template<typename Scalar>
129struct real_ref_impl
130{
131 typedef typename NumTraits<Scalar>::Real RealScalar;
132 static inline RealScalar& run(Scalar& x)
133 {
134 return reinterpret_cast<RealScalar*>(&x)[0];
135 }
136 static inline const RealScalar& run(const Scalar& x)
137 {
138 return reinterpret_cast<const RealScalar*>(&x)[0];
139 }
140};
141
142template<typename Scalar>
143struct real_ref_retval
144{
145 typedef typename NumTraits<Scalar>::Real & type;
146};
147
148/****************************************************************************
149* Implementation of imag_ref *
150****************************************************************************/
151
152template<typename Scalar, bool IsComplex>
153struct imag_ref_default_impl
154{
155 typedef typename NumTraits<Scalar>::Real RealScalar;
156 static inline RealScalar& run(Scalar& x)
157 {
158 return reinterpret_cast<RealScalar*>(&x)[1];
159 }
160 static inline const RealScalar& run(const Scalar& x)
161 {
162 return reinterpret_cast<RealScalar*>(&x)[1];
163 }
164};
165
166template<typename Scalar>
167struct imag_ref_default_impl<Scalar, false>
168{
169 static inline Scalar run(Scalar&)
170 {
171 return Scalar(0);
172 }
173 static inline const Scalar run(const Scalar&)
174 {
175 return Scalar(0);
176 }
177};
178
179template<typename Scalar>
180struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
181
182template<typename Scalar>
183struct imag_ref_retval
184{
185 typedef typename NumTraits<Scalar>::Real & type;
186};
187
188/****************************************************************************
189* Implementation of conj *
190****************************************************************************/
191
192template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
193struct conj_impl
194{
195 static inline Scalar run(const Scalar& x)
196 {
197 return x;
198 }
199};
200
201template<typename Scalar>
202struct conj_impl<Scalar,true>
203{
204 static inline Scalar run(const Scalar& x)
205 {
206 using std::conj;
207 return conj(x);
208 }
209};
210
211template<typename Scalar>
212struct conj_retval
213{
214 typedef Scalar type;
215};
216
217/****************************************************************************
218* Implementation of abs2 *
219****************************************************************************/
220
221template<typename Scalar,bool IsComplex>
222struct abs2_impl_default
223{
224 typedef typename NumTraits<Scalar>::Real RealScalar;
225 static inline RealScalar run(const Scalar& x)
226 {
227 return x*x;
228 }
229};
230
231template<typename Scalar>
232struct abs2_impl_default<Scalar, true> // IsComplex
233{
234 typedef typename NumTraits<Scalar>::Real RealScalar;
235 static inline RealScalar run(const Scalar& x)
236 {
237 return real(x)*real(x) + imag(x)*imag(x);
238 }
239};
240
241template<typename Scalar>
242struct abs2_impl
243{
244 typedef typename NumTraits<Scalar>::Real RealScalar;
245 static inline RealScalar run(const Scalar& x)
246 {
247 return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
248 }
249};
250
251template<typename Scalar>
252struct abs2_retval
253{
254 typedef typename NumTraits<Scalar>::Real type;
255};
256
257/****************************************************************************
258* Implementation of norm1 *
259****************************************************************************/
260
261template<typename Scalar, bool IsComplex>
262struct norm1_default_impl
263{
264 typedef typename NumTraits<Scalar>::Real RealScalar;
265 static inline RealScalar run(const Scalar& x)
266 {
267 using std::abs;
268 return abs(real(x)) + abs(imag(x));
269 }
270};
271
272template<typename Scalar>
273struct norm1_default_impl<Scalar, false>
274{
275 static inline Scalar run(const Scalar& x)
276 {
277 using std::abs;
278 return abs(x);
279 }
280};
281
282template<typename Scalar>
283struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
284
285template<typename Scalar>
286struct norm1_retval
287{
288 typedef typename NumTraits<Scalar>::Real type;
289};
290
291/****************************************************************************
292* Implementation of hypot *
293****************************************************************************/
294
295template<typename Scalar>
296struct hypot_impl
297{
298 typedef typename NumTraits<Scalar>::Real RealScalar;
299 static inline RealScalar run(const Scalar& x, const Scalar& y)
300 {
301 using std::max;
302 using std::min;
303 using std::abs;
304 using std::sqrt;
305 RealScalar _x = abs(x);
306 RealScalar _y = abs(y);
307 RealScalar p = (max)(_x, _y);
308 if(p==RealScalar(0)) return RealScalar(0);
309 RealScalar q = (min)(_x, _y);
310 RealScalar qp = q/p;
311 return p * sqrt(RealScalar(1) + qp*qp);
312 }
313};
314
315template<typename Scalar>
316struct hypot_retval
317{
318 typedef typename NumTraits<Scalar>::Real type;
319};
320
321/****************************************************************************
322* Implementation of cast *
323****************************************************************************/
324
325template<typename OldType, typename NewType>
326struct cast_impl
327{
328 static inline NewType run(const OldType& x)
329 {
330 return static_cast<NewType>(x);
331 }
332};
333
334// here, for once, we're plainly returning NewType: we don't want cast to do weird things.
335
336template<typename OldType, typename NewType>
337inline NewType cast(const OldType& x)
338{
339 return cast_impl<OldType, NewType>::run(x);
340}
341
342/****************************************************************************
343* Implementation of atanh2 *
344****************************************************************************/
345
346template<typename Scalar, bool IsInteger>
347struct atanh2_default_impl
348{
349 typedef Scalar retval;
350 typedef typename NumTraits<Scalar>::Real RealScalar;
351 static inline Scalar run(const Scalar& x, const Scalar& y)
352 {
353 using std::abs;
354 using std::log;
355 using std::sqrt;
356 Scalar z = x / y;
357 if (y == Scalar(0) || abs(z) > sqrt(NumTraits<RealScalar>::epsilon()))
358 return RealScalar(0.5) * log((y + x) / (y - x));
359 else
360 return z + z*z*z / RealScalar(3);
361 }
362};
363
364template<typename Scalar>
365struct atanh2_default_impl<Scalar, true>
366{
367 static inline Scalar run(const Scalar&, const Scalar&)
368 {
369 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
370 return Scalar(0);
371 }
372};
373
374template<typename Scalar>
375struct atanh2_impl : atanh2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
376
377template<typename Scalar>
378struct atanh2_retval
379{
380 typedef Scalar type;
381};
382
383/****************************************************************************
384* Implementation of pow *
385****************************************************************************/
386
387template<typename Scalar, bool IsInteger>
388struct pow_default_impl
389{
390 typedef Scalar retval;
391 static inline Scalar run(const Scalar& x, const Scalar& y)
392 {
393 using std::pow;
394 return pow(x, y);
395 }
396};
397
398template<typename Scalar>
399struct pow_default_impl<Scalar, true>
400{
401 static inline Scalar run(Scalar x, Scalar y)
402 {
403 Scalar res(1);
404 eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
405 if(y & 1) res *= x;
406 y >>= 1;
407 while(y)
408 {
409 x *= x;
410 if(y&1) res *= x;
411 y >>= 1;
412 }
413 return res;
414 }
415};
416
417template<typename Scalar>
418struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
419
420template<typename Scalar>
421struct pow_retval
422{
423 typedef Scalar type;
424};
425
426/****************************************************************************
427* Implementation of random *
428****************************************************************************/
429
430template<typename Scalar,
431 bool IsComplex,
432 bool IsInteger>
433struct random_default_impl {};
434
435template<typename Scalar>
436struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
437
438template<typename Scalar>
439struct random_retval
440{
441 typedef Scalar type;
442};
443
444template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
445template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
446
447template<typename Scalar>
448struct random_default_impl<Scalar, false, false>
449{
450 static inline Scalar run(const Scalar& x, const Scalar& y)
451 {
452 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
453 }
454 static inline Scalar run()
455 {
456 return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
457 }
458};
459
460enum {
461 floor_log2_terminate,
462 floor_log2_move_up,
463 floor_log2_move_down,
464 floor_log2_bogus
465};
466
467template<unsigned int n, int lower, int upper> struct floor_log2_selector
468{
469 enum { middle = (lower + upper) / 2,
470 value = (upper <= lower + 1) ? int(floor_log2_terminate)
471 : (n < (1 << middle)) ? int(floor_log2_move_down)
472 : (n==0) ? int(floor_log2_bogus)
473 : int(floor_log2_move_up)
474 };
475};
476
477template<unsigned int n,
478 int lower = 0,
479 int upper = sizeof(unsigned int) * CHAR_BIT - 1,
480 int selector = floor_log2_selector<n, lower, upper>::value>
481struct floor_log2 {};
482
483template<unsigned int n, int lower, int upper>
484struct floor_log2<n, lower, upper, floor_log2_move_down>
485{
486 enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
487};
488
489template<unsigned int n, int lower, int upper>
490struct floor_log2<n, lower, upper, floor_log2_move_up>
491{
492 enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
493};
494
495template<unsigned int n, int lower, int upper>
496struct floor_log2<n, lower, upper, floor_log2_terminate>
497{
498 enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
499};
500
501template<unsigned int n, int lower, int upper>
502struct floor_log2<n, lower, upper, floor_log2_bogus>
503{
504 // no value, error at compile time
505};
506
507template<typename Scalar>
508struct random_default_impl<Scalar, false, true>
509{
510 typedef typename NumTraits<Scalar>::NonInteger NonInteger;
511
512 static inline Scalar run(const Scalar& x, const Scalar& y)
513 {
514 return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
515 }
516
517 static inline Scalar run()
518 {
519#ifdef EIGEN_MAKING_DOCS
520 return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
521#else
522 enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
523 scalar_bits = sizeof(Scalar) * CHAR_BIT,
524 shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
525 offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
526 };
527 return Scalar((std::rand() >> shift) - offset);
528#endif
529 }
530};
531
532template<typename Scalar>
533struct random_default_impl<Scalar, true, false>
534{
535 static inline Scalar run(const Scalar& x, const Scalar& y)
536 {
537 return Scalar(random(real(x), real(y)),
538 random(imag(x), imag(y)));
539 }
540 static inline Scalar run()
541 {
542 typedef typename NumTraits<Scalar>::Real RealScalar;
543 return Scalar(random<RealScalar>(), random<RealScalar>());
544 }
545};
546
547template<typename Scalar>
548inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
549{
550 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
551}
552
553template<typename Scalar>
554inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
555{
556 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
557}
558
559} // end namespace internal
560
561/****************************************************************************
562* Generic math function *
563****************************************************************************/
564
565namespace numext {
566
567template<typename Scalar>
568inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
569{
570 return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
571}
572
573template<typename Scalar>
574inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
575{
576 return internal::real_ref_impl<Scalar>::run(x);
577}
578
579template<typename Scalar>
580inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
581{
582 return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
583}
584
585template<typename Scalar>
586inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
587{
588 return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
589}
590
591template<typename Scalar>
592inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
593{
594 return internal::imag_ref_impl<Scalar>::run(x);
595}
596
597template<typename Scalar>
598inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
599{
600 return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
601}
602
603template<typename Scalar>
604inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
605{
606 return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
607}
608
609template<typename Scalar>
610inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
611{
612 return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
613}
614
615template<typename Scalar>
616inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
617{
618 return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
619}
620
621template<typename Scalar>
622inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
623{
624 return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
625}
626
627template<typename Scalar>
628inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y)
629{
630 return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y);
631}
632
633template<typename Scalar>
634inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
635{
636 return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
637}
638
639// std::isfinite is non standard, so let's define our own version,
640// even though it is not very efficient.
641template<typename T> bool (isfinite)(const T& x)
642{
643 return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
644}
645
646} // end namespace numext
647
648namespace internal {
649
650/****************************************************************************
651* Implementation of fuzzy comparisons *
652****************************************************************************/
653
654template<typename Scalar,
655 bool IsComplex,
656 bool IsInteger>
657struct scalar_fuzzy_default_impl {};
658
659template<typename Scalar>
660struct scalar_fuzzy_default_impl<Scalar, false, false>
661{
662 typedef typename NumTraits<Scalar>::Real RealScalar;
663 template<typename OtherScalar>
664 static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
665 {
666 using std::abs;
667 return abs(x) <= abs(y) * prec;
668 }
669 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
670 {
671 using std::min;
672 using std::abs;
673 return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
674 }
675 static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
676 {
677 return x <= y || isApprox(x, y, prec);
678 }
679};
680
681template<typename Scalar>
682struct scalar_fuzzy_default_impl<Scalar, false, true>
683{
684 typedef typename NumTraits<Scalar>::Real RealScalar;
685 template<typename OtherScalar>
686 static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
687 {
688 return x == Scalar(0);
689 }
690 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
691 {
692 return x == y;
693 }
694 static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
695 {
696 return x <= y;
697 }
698};
699
700template<typename Scalar>
701struct scalar_fuzzy_default_impl<Scalar, true, false>
702{
703 typedef typename NumTraits<Scalar>::Real RealScalar;
704 template<typename OtherScalar>
705 static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
706 {
707 return numext::abs2(x) <= numext::abs2(y) * prec * prec;
708 }
709 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
710 {
711 using std::min;
712 return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec;
713 }
714};
715
716template<typename Scalar>
717struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
718
719template<typename Scalar, typename OtherScalar>
720inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
721 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
722{
723 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
724}
725
726template<typename Scalar>
727inline bool isApprox(const Scalar& x, const Scalar& y,
728 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
729{
730 return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
731}
732
733template<typename Scalar>
734inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
735 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
736{
737 return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
738}
739
740/******************************************
741*** The special case of the bool type ***
742******************************************/
743
744template<> struct random_impl<bool>
745{
746 static inline bool run()
747 {
748 return random<int>(0,1)==0 ? false : true;
749 }
750};
751
752template<> struct scalar_fuzzy_impl<bool>
753{
754 typedef bool RealScalar;
755
756 template<typename OtherScalar>
757 static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
758 {
759 return !x;
760 }
761
762 static inline bool isApprox(bool x, bool y, bool)
763 {
764 return x == y;
765 }
766
767 static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
768 {
769 return (!x) || y;
770 }
771
772};
773
774
775} // end namespace internal
776
777} // end namespace Eigen
778
779#endif // EIGEN_MATHFUNCTIONS_H
Note: See TracBrowser for help on using the repository browser.