source: trunk/test_more/limits.cpp @ 3008

Last change on this file since 3008 was 2884, checked in by bradbell, 7 years ago

Fix failure of test_more/limits.cpp on some systems.

  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1/* $Id: limits.cpp 2884 2013-08-06 14:29:20Z bradbell $ */
2/* --------------------------------------------------------------------------
3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
4
5CppAD is distributed under multiple licenses. This distribution is under
6the terms of the
7                    Eclipse Public License Version 1.0.
8
9A copy of this license is included in the COPYING file of this distribution.
10Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
11-------------------------------------------------------------------------- */
12
13/*
14$begin limits.cpp$$
15$spell
16$$
17
18$section Numeric Limits: Example and Test$$
19$index limits$$
20$index example, limits$$
21$index test, limits$$
22
23$head Assumption$$
24This code assumes that the decimal point is infront of the mantissa.
25Hence dividing the minimum normalized value looses precision,
26while multiplying the maximum normalized value results in infinity.
27
28$head Externals$$
29This example using external routines to get and set values
30so that the complier does not set the correspdong code and optimize
31it out.
32
33$code
34$verbatim%example/limits.cpp%0%// BEGIN C++%// END C++%1%$$
35$$
36
37$end
38*/
39// BEGIN C++
40
41# ifdef _MSC_VER
42// Supress Microsoft compiler warning about possible loss of precision,
43// in the constructors (when converting to std::complex<float>)
44//      Type one = 1
45//      Type two = 2
46// 1 and 2 are small enough so no loss of precision when converting to float.
47# pragma warning(disable:4244)
48# endif
49
50# include <cppad/cppad.hpp>
51# include <complex>
52# include "extern_value.hpp"
53
54namespace {
55        using CppAD::vector;
56        using CppAD::abs_geq;
57
58        template <class Type>
59        Type add_one(const Type& value)
60        {       return( Type(1) + value ); }
61        // -----------------------------------------------------------------
62        template <class Type>
63        bool check_epsilon(void)
64        {       bool ok    = true;
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();
76                return ok;
77        }
78        // -----------------------------------------------------------------
79        template <class Type>
80        bool check_min(void)
81        {       bool ok    = true;
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) );
88                //
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());
92                //
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());
96                return ok;
97        }
98
99        // -----------------------------------------------------------------
100        template <class Type>
101        bool check_max(void)
102        {       bool ok    = true;
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) );
109
110                // In complex case, this operaiton can result in (inf, 0)
111                tmp.set( max2.get() * hun.get() );
112
113                // In complex case, this operaiotn can result in (inf,-nan)
114                // (where nan corresponds to inf * 0)
115                tmp.set( tmp.get() / hun.get() );
116
117                if( ! CppAD::isnan( tmp.get() ) ) ok &= abs_geq(
118                        tmp.get() / max2.get() - one.get(), eps3.get()
119                );
120                //
121                tmp.set( max2.get() / hun.get() );
122                tmp.set( tmp.get() * hun.get() );
123                ok        &= ! abs_geq(tmp.get() / max2.get() - one.get(), eps3.get() );
124                return ok;
125        }
126}
127
128bool limits(void)
129{       bool ok = true;
130        using CppAD::AD;
131
132        // -------------------------------------------------------------------
133        // epsilon for Base types defined by CppAD
134        ok &= check_epsilon<float>();
135        ok &= check_epsilon<double>();
136        ok &= check_epsilon< std::complex<float> >();
137        ok &= check_epsilon< std::complex<double> >();
138
139        // epsilon for some AD types.
140        ok &= check_epsilon< AD<float> >();
141        ok &= check_epsilon< AD<double> >();
142        ok &= check_epsilon<  AD<std::complex<float> > >();
143        ok &= check_epsilon<  AD<std::complex<double> > >();
144
145        // -------------------------------------------------------------------
146        // min for Base types defined by CppAD
147        ok &= check_min<float>();
148        ok &= check_min<double>();
149        ok &= check_min< std::complex<float> >();
150        ok &= check_min< std::complex<double> >();
151
152        // min for some AD types.
153        ok &= check_min< AD<float> >();
154        ok &= check_min< AD<double> >();
155        ok &= check_min<  AD<std::complex<float> > >();
156        ok &= check_min<  AD<std::complex<double> > >();
157
158        // -------------------------------------------------------------------
159        // max for Base types defined by CppAD
160        ok &= check_max<float>();
161        ok &= check_max<double>();
162        ok &= check_max< std::complex<float> >();
163        ok &= check_max< std::complex<double> >();
164
165        // max for some AD types.
166        ok &= check_max< AD<float> >();
167        ok &= check_max< AD<double> >();
168        ok &= check_max< AD< std::complex<float> > >();
169        ok &= check_max< AD< std::complex<double> > >();
170
171        return ok;
172}
173// END C++
Note: See TracBrowser for help on using the repository browser.