Changeset 2756 for trunk/test_more/limits.cpp
 Timestamp:
 Feb 27, 2013 1:49:28 PM (7 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

trunk/test_more/limits.cpp
r2722 r2756 21 21 $index test, limits$$ 22 22 23 $head Assumption$$ 24 This code assumes that the decimal point is infront of the mantissa. 25 Hence dividing the minimum normalized value looses precision, 26 while multiplying the maximum normalized value results in infinity. 27 28 $head Externals$$ 29 This example using external routines to get and set values 30 so that the complier does not set the correspdong code and optimize 31 it out. 32 23 33 $code 24 34 $verbatim%example/limits.cpp%0%// BEGIN C++%// END C++%1%$$ … … 40 50 # include <cppad/cppad.hpp> 41 51 # include <complex> 52 # include "extern_value.hpp" 42 53 43 54 namespace { … … 52 63 bool check_epsilon(void) 53 64 { bool ok = true; 54 vector<Type> eps(1), one(1), two(1), eps2(1), check(1); 55 eps[0] = CppAD::numeric_limits<Type>::epsilon(); 56 one[0] = 1; 57 two[0] = 2; 58 eps2[0] = eps[0] / two[0]; 59 check[0] = add_one(eps[0]); 60 ok &= one[0] != check[0]; 61 check[0] = add_one(eps2[0]); 62 ok &= one[0] == check[0]; 65 typedef extern_value<Type> value; 66 value eps( CppAD::numeric_limits<Type>::epsilon() ); 67 value one( Type(1) ); 68 value two( Type(2) ); 69 value tmp( Type(0) ); 70 // 71 tmp.set( add_one( eps.get() / two.get() ) ); 72 ok &= one.get() == tmp.get(); 73 // 74 tmp.set( add_one( eps.get() ) ); 75 ok &= one.get() != tmp.get(); 63 76 return ok; 64 77 } … … 67 80 bool check_min(void) 68 81 { bool ok = true; 69 vector<Type> min(1),eps(1),one(1),three(1),hun(1),tmp(1),match(1);70 min[0] = CppAD::numeric_limits<Type>::min();71 eps[0] = CppAD::numeric_limits<Type>::epsilon();72 one[0] = Type(1);73 three[0] = Type(3);74 hun[0] = Type(100);82 typedef extern_value<Type> value; 83 value min( CppAD::numeric_limits<Type>::min() ); 84 value eps3( Type(3) * CppAD::numeric_limits<Type>::epsilon() ); 85 value one( Type(1) ); 86 value hun( Type(100) ); 87 value tmp( Type(0) ); 75 88 // 76 tmp [0] = min[0] / hun[0];77 match[0] = tmp[0] * hun[0];78 ok &= abs_geq( match[0]/min[0]  one[0], three[0]*eps[0]);89 tmp.set( min.get() / hun.get() ); 90 tmp.set( tmp.get() * hun.get() ); 91 ok &= abs_geq(tmp.get()/min.get()  one.get(), eps3.get()); 79 92 // 80 tmp [0] = min[0] * hun[0];81 match[0] = tmp[0] / (hun[0] * (Type(1)  eps[0]) );82 ok &= ! abs_geq( match[0]/min[0]  one[0], three[0]*eps[0]);93 tmp.set( min.get() * hun.get() ); 94 tmp.set( tmp.get() / hun.get() ); 95 ok &= ! abs_geq(tmp.get()/min.get()  one.get(), eps3.get()); 83 96 return ok; 84 97 } 98 85 99 //  86 100 template <class Type> 87 101 bool check_max(void) 88 102 { bool ok = true; 89 vector<Type> max(1),eps(1),one(1),three(1),hun(1),tmp(1),match(1);90 max[0] = CppAD::numeric_limits<Type>::max();91 eps[0] = CppAD::numeric_limits<Type>::epsilon();92 one[0] = Type(1);93 three[0] = Type(3);94 hun[0] = Type(100);103 typedef extern_value<Type> value; 104 value max2( CppAD::numeric_limits<Type>::max() / Type(2) ); 105 value eps3( Type(3) * CppAD::numeric_limits<Type>::epsilon() ); 106 value one( Type(1) ); 107 value hun( Type(100) ); 108 value tmp( Type(0) ); 95 109 // 96 tmp[0] = max[0] * hun[0]; 97 match[0] = tmp[0] / hun[0]; 98 ok &= abs_geq(match[0]/max[0]  one[0], three[0]*eps[0]); 110 tmp.set( max2.get() * hun.get() ); 111 tmp.set( tmp.get() / hun.get() ); 112 // tmp is infinite 113 ok &= abs_geq(tmp.get() / max2.get()  one.get(), eps3.get() ); 99 114 // 100 tmp[0] = max[0] / hun[0]; 101 match[0] = tmp[0] * (hun[0] * (Type(1)  eps[0]) ); 102 ok &= ! abs_geq(match[0]/max[0]  one[0], three[0]*eps[0]); 103 return ok; 104 } 105 //  106 template <class Type> 107 bool check_max_complex(void) 108 { typedef std::complex<Type> Complex; 109 bool ok = true; 110 vector<Complex> c_max(1), c_eps(1); 111 vector<Type> max(1),eps(1),one(1),three(1),hun(1),tmp(1),match(1); 112 c_max[0] = CppAD::numeric_limits<Complex>::max(); 113 c_eps[0] = CppAD::numeric_limits<Type>::epsilon(); 114 ok &= c_eps[0].imag() == Type(0); 115 ok &= c_max[0].imag() == Type(0); 116 max[0] = c_max[0].real(); 117 eps[0] = c_eps[0].real(); 118 one[0] = Type(1); 119 three[0] = Type(3); 120 hun[0] = Type(100); 121 // 122 tmp[0] = max[0] * hun[0]; 123 match[0] = tmp[0] / hun[0]; 124 ok &= CppAD::abs(match[0]/max[0]  one[0]) > three[0] * eps[0]; 125 // 126 tmp[0] = max[0] / hun[0]; 127 match[0] = tmp[0] * (hun[0] * (Type(1)  eps[0])); 128 ok &= CppAD::abs(match[0]/max[0]  one[0]) < three[0] * eps[0]; 129 return ok; 130 } 131 // 132 template <class Base> 133 bool check_max_ad_complex() 134 { using CppAD::AD; 135 bool ok = true; 136 AD<Base> c_max = CppAD::numeric_limits< AD<Base> >::max(); 137 ok &= Value(c_max).imag() == Base(0); 138 ok &= Value(c_max).real() == CppAD::numeric_limits<Base>::max(); 139 115 tmp.set( max2.get() / hun.get() ); 116 tmp.set( tmp.get() * hun.get() ); 117 ok &= ! abs_geq(tmp.get() / max2.get()  one.get(), eps3.get() ); 140 118 return ok; 141 119 } … … 176 154 ok &= check_max<float>(); 177 155 ok &= check_max<double>(); 178 ok &= check_max _complex<float>();179 ok &= check_max _complex<double>();156 ok &= check_max< std::complex<float> >(); 157 ok &= check_max< std::complex<double> >(); 180 158 181 159 // max for some AD types. 182 160 ok &= check_max< AD<float> >(); 183 161 ok &= check_max< AD<double> >(); 184 ok &= check_max _ad_complex< std::complex<float> >();185 ok &= check_max _ad_complex< std::complex<double> >();162 ok &= check_max< AD< std::complex<float> > >(); 163 ok &= check_max< AD< std::complex<double> > >(); 186 164 187 165 return ok;
Note: See TracChangeset
for help on using the changeset viewer.