cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

AnnoyingScalar.h (5707B)


      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2011-2018 Gael Guennebaud <gael.guennebaud@inria.fr>
      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_TEST_ANNOYING_SCALAR_H
     11 #define EIGEN_TEST_ANNOYING_SCALAR_H
     12 
     13 #include <ostream>
     14 
     15 #if EIGEN_COMP_GNUC
     16 #pragma GCC diagnostic ignored "-Wshadow"
     17 #endif
     18 
     19 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
     20 struct my_exception
     21 {
     22   my_exception() {}
     23   ~my_exception() {}
     24 };
     25 #endif
     26 
     27 // An AnnoyingScalar is a pseudo scalar type that:
     28 // - can randomly through an exception in operator +
     29 // - randomly allocate on the heap or initialize a reference to itself making it non trivially copyable, nor movable, nor relocatable.
     30 
     31 class AnnoyingScalar
     32 {
     33   public:
     34     AnnoyingScalar()                { init(); *v = 0;  }
     35     AnnoyingScalar(long double _v)  { init(); *v = _v; }
     36     AnnoyingScalar(double _v)       { init(); *v = _v; }
     37     AnnoyingScalar(float _v)        { init(); *v = _v; }
     38     AnnoyingScalar(int _v)          { init(); *v = _v; }
     39     AnnoyingScalar(long _v)         { init(); *v = _v; }
     40     #if EIGEN_HAS_CXX11
     41     AnnoyingScalar(long long _v)    { init(); *v = _v; }
     42     #endif
     43     AnnoyingScalar(const AnnoyingScalar& other) { init(); *v = *(other.v); }
     44     ~AnnoyingScalar() {
     45       if(v!=&data)
     46         delete v;
     47       instances--;
     48     }
     49 
     50     void init() {
     51       if(internal::random<bool>())
     52         v = new float;
     53       else
     54         v = &data;
     55       instances++;
     56     }
     57 
     58     AnnoyingScalar operator+(const AnnoyingScalar& other) const
     59     {
     60       #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
     61       countdown--;
     62       if(countdown<=0 && !dont_throw)
     63         throw my_exception();
     64       #endif
     65       return AnnoyingScalar(*v+*other.v);
     66     }
     67 
     68     AnnoyingScalar operator-() const
     69     { return AnnoyingScalar(-*v); }
     70     
     71     AnnoyingScalar operator-(const AnnoyingScalar& other) const
     72     { return AnnoyingScalar(*v-*other.v); }
     73     
     74     AnnoyingScalar operator*(const AnnoyingScalar& other) const
     75     { return AnnoyingScalar((*v)*(*other.v)); }
     76 
     77     AnnoyingScalar operator/(const AnnoyingScalar& other) const
     78     { return AnnoyingScalar((*v)/(*other.v)); }
     79 
     80     AnnoyingScalar& operator+=(const AnnoyingScalar& other) { *v += *other.v; return *this; }
     81     AnnoyingScalar& operator-=(const AnnoyingScalar& other) { *v -= *other.v; return *this; }
     82     AnnoyingScalar& operator*=(const AnnoyingScalar& other) { *v *= *other.v; return *this; }
     83     AnnoyingScalar& operator/=(const AnnoyingScalar& other) { *v /= *other.v; return *this; }
     84     AnnoyingScalar& operator= (const AnnoyingScalar& other) { *v  = *other.v; return *this; }
     85 
     86     bool operator==(const AnnoyingScalar& other) const { return *v == *other.v; }
     87     bool operator!=(const AnnoyingScalar& other) const { return *v != *other.v; }
     88     bool operator<=(const AnnoyingScalar& other) const { return *v <= *other.v; }
     89     bool operator< (const AnnoyingScalar& other) const { return *v <  *other.v; }
     90     bool operator>=(const AnnoyingScalar& other) const { return *v >= *other.v; }
     91     bool operator> (const AnnoyingScalar& other) const { return *v >  *other.v; }
     92   
     93     float* v;
     94     float data;
     95     static int instances;
     96 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
     97     static int countdown;
     98     static bool dont_throw;
     99 #endif
    100 };
    101 
    102 AnnoyingScalar real(const AnnoyingScalar &x) { return x; }
    103 AnnoyingScalar imag(const AnnoyingScalar & ) { return 0; }
    104 AnnoyingScalar conj(const AnnoyingScalar &x) { return x; }
    105 AnnoyingScalar sqrt(const AnnoyingScalar &x) { return std::sqrt(*x.v); }
    106 AnnoyingScalar abs (const AnnoyingScalar &x) { return std::abs(*x.v); }
    107 AnnoyingScalar cos (const AnnoyingScalar &x) { return std::cos(*x.v); }
    108 AnnoyingScalar sin (const AnnoyingScalar &x) { return std::sin(*x.v); }
    109 AnnoyingScalar acos(const AnnoyingScalar &x) { return std::acos(*x.v); }
    110 AnnoyingScalar atan2(const AnnoyingScalar &y,const AnnoyingScalar &x) { return std::atan2(*y.v,*x.v); }
    111 
    112 std::ostream& operator<<(std::ostream& stream,const AnnoyingScalar& x) {
    113   stream << (*(x.v));
    114   return stream;
    115 }
    116 
    117 int AnnoyingScalar::instances = 0;
    118 
    119 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
    120 int AnnoyingScalar::countdown = 0;
    121 bool AnnoyingScalar::dont_throw = false;
    122 #endif
    123 
    124 namespace Eigen {
    125 template<>
    126 struct NumTraits<AnnoyingScalar> : NumTraits<float>
    127 {
    128   enum {
    129     RequireInitialization = 1,
    130   };
    131   typedef AnnoyingScalar Real;
    132   typedef AnnoyingScalar Nested;
    133   typedef AnnoyingScalar Literal;
    134   typedef AnnoyingScalar NonInteger;
    135 };
    136 
    137 template<> inline AnnoyingScalar test_precision<AnnoyingScalar>() { return test_precision<float>(); }
    138 
    139 namespace numext {
    140 template<>
    141 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
    142 bool (isfinite)(const AnnoyingScalar& x) {
    143   return (numext::isfinite)(*x.v);
    144 }
    145 }
    146 
    147 namespace internal {
    148   template<> EIGEN_STRONG_INLINE double cast(const AnnoyingScalar& x) { return double(*x.v); }
    149   template<> EIGEN_STRONG_INLINE float  cast(const AnnoyingScalar& x) { return *x.v; }
    150 }
    151 }  // namespace Eigen
    152 
    153 AnnoyingScalar get_test_precision(const AnnoyingScalar&)
    154 { return Eigen::test_precision<AnnoyingScalar>(); }
    155 
    156 AnnoyingScalar test_relative_error(const AnnoyingScalar &a, const AnnoyingScalar &b)
    157 { return test_relative_error(*a.v, *b.v); }
    158 
    159 inline bool test_isApprox(const AnnoyingScalar &a, const AnnoyingScalar &b)
    160 { return internal::isApprox(*a.v, *b.v, test_precision<float>()); }
    161 
    162 inline bool test_isMuchSmallerThan(const AnnoyingScalar &a, const AnnoyingScalar &b)
    163 { return test_isMuchSmallerThan(*a.v, *b.v); }
    164 
    165 #endif // EIGEN_TEST_ANNOYING_SCALAR_H