Changeset 2756


Ignore:
Timestamp:
Feb 27, 2013 1:49:28 PM (7 years ago)
Author:
bradbell
Message:

Make testing of numeric limits more robust by
using external functions, instead of arrays, for storing temporary values.

extern_value.cpp: external functions for getting and setting values.

Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/omh/whats_new/whats_new_13.omh

    r2754 r2756  
    3434The purpose of this section is to
    3535assist you in learning about changes between various versions of CppAD.
     36
     37$head 02-27$$
     38The test $cref limits.cpp$$ was failing during testing of Fedora-19; see
     39$href%https://bugzilla.redhat.com/show_bug.cgi?id=913929% Bug 913929%$$.
     40This has been fixed.
    3641
    3742$head 02-20$$
  • trunk/test_more/CMakeLists.txt

    r2722 r2756  
    101101        erf.cpp
    102102        exp.cpp
     103        extern_value.cpp
    103104        for_hess.cpp
    104105        for_sparse_jac.cpp
  • trunk/test_more/limits.cpp

    r2722 r2756  
    2121$index test, limits$$
    2222
     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
    2333$code
    2434$verbatim%example/limits.cpp%0%// BEGIN C++%// END C++%1%$$
     
    4050# include <cppad/cppad.hpp>
    4151# include <complex>
     52# include "extern_value.hpp"
    4253
    4354namespace {
     
    5263        bool check_epsilon(void)
    5364        {       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();
    6376                return ok;
    6477        }
     
    6780        bool check_min(void)
    6881        {       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) );
    7588                //
    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());
    7992                //
    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());
    8396                return ok;
    8497        }
     98
    8599        // -----------------------------------------------------------------
    86100        template <class Type>
    87101        bool check_max(void)
    88102        {       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) );
    95109                //
    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() );
    99114                //
    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() );
    140118                return ok;
    141119        }
     
    176154        ok &= check_max<float>();
    177155        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> >();
    180158
    181159        // max for some AD types.
    182160        ok &= check_max< AD<float> >();
    183161        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> > >();
    186164
    187165        return ok;
  • trunk/test_more/makefile.am

    r2722 r2756  
    114114        erf.cpp \
    115115        exp.cpp \
     116        extern_value.cpp \
     117        extern_value.hpp \
    116118        for_hess.cpp \
    117119        for_sparse_jac.cpp \
  • trunk/test_more/makefile.in

    r2755 r2756  
    7676        compare_change.cpp cond_exp.cpp cond_exp_ad.cpp copy.cpp \
    7777        cos.cpp cosh.cpp dbl_epsilon.cpp div.cpp div_eq.cpp \
    78         div_zero_one.cpp erf.cpp exp.cpp for_hess.cpp \
    79         for_sparse_jac.cpp forward.cpp from_base.cpp fun_check.cpp \
    80         jacobian.cpp limits.cpp log.cpp log10.cpp mul.cpp mul_eq.cpp \
    81         mul_level.cpp mul_zero_one.cpp ndebug.cpp near_equal_ext.cpp \
    82         neg.cpp ode_err_control.cpp optimize.cpp parameter.cpp \
    83         poly.cpp pow.cpp pow_int.cpp print_for.cpp romberg_one.cpp \
    84         rosen_34.cpp runge_45.cpp reverse.cpp rev_sparse_hes.cpp \
    85         rev_sparse_jac.cpp rev_two.cpp simple_vector.cpp sin.cpp \
    86         sin_cos.cpp sinh.cpp sparse_hessian.cpp sparse_jacobian.cpp \
    87         sparse_vec_ad.cpp sqrt.cpp std_math.cpp sub.cpp sub_eq.cpp \
    88         sub_zero.cpp tan.cpp test_vector.cpp track_new_del.cpp \
    89         value.cpp vec_ad.cpp vec_ad_par.cpp vec_unary.cpp
     78        div_zero_one.cpp erf.cpp exp.cpp extern_value.cpp \
     79        extern_value.hpp for_hess.cpp for_sparse_jac.cpp forward.cpp \
     80        from_base.cpp fun_check.cpp jacobian.cpp limits.cpp log.cpp \
     81        log10.cpp mul.cpp mul_eq.cpp mul_level.cpp mul_zero_one.cpp \
     82        ndebug.cpp near_equal_ext.cpp neg.cpp ode_err_control.cpp \
     83        optimize.cpp parameter.cpp poly.cpp pow.cpp pow_int.cpp \
     84        print_for.cpp romberg_one.cpp rosen_34.cpp runge_45.cpp \
     85        reverse.cpp rev_sparse_hes.cpp rev_sparse_jac.cpp rev_two.cpp \
     86        simple_vector.cpp sin.cpp sin_cos.cpp sinh.cpp \
     87        sparse_hessian.cpp sparse_jacobian.cpp sparse_vec_ad.cpp \
     88        sqrt.cpp std_math.cpp sub.cpp sub_eq.cpp sub_zero.cpp tan.cpp \
     89        test_vector.cpp track_new_del.cpp value.cpp vec_ad.cpp \
     90        vec_ad_par.cpp vec_unary.cpp
    9091@CppAD_ADOLC_TRUE@am__objects_1 = base_adolc.$(OBJEXT)
    9192@CppAD_IPOPT_TRUE@am__objects_2 = ipopt_solve.$(OBJEXT)
     
    101102        cosh.$(OBJEXT) dbl_epsilon.$(OBJEXT) div.$(OBJEXT) \
    102103        div_eq.$(OBJEXT) div_zero_one.$(OBJEXT) erf.$(OBJEXT) \
    103         exp.$(OBJEXT) for_hess.$(OBJEXT) for_sparse_jac.$(OBJEXT) \
    104         forward.$(OBJEXT) from_base.$(OBJEXT) fun_check.$(OBJEXT) \
    105         jacobian.$(OBJEXT) limits.$(OBJEXT) log.$(OBJEXT) \
    106         log10.$(OBJEXT) mul.$(OBJEXT) mul_eq.$(OBJEXT) \
     104        exp.$(OBJEXT) extern_value.$(OBJEXT) for_hess.$(OBJEXT) \
     105        for_sparse_jac.$(OBJEXT) forward.$(OBJEXT) from_base.$(OBJEXT) \
     106        fun_check.$(OBJEXT) jacobian.$(OBJEXT) limits.$(OBJEXT) \
     107        log.$(OBJEXT) log10.$(OBJEXT) mul.$(OBJEXT) mul_eq.$(OBJEXT) \
    107108        mul_level.$(OBJEXT) mul_zero_one.$(OBJEXT) ndebug.$(OBJEXT) \
    108109        near_equal_ext.$(OBJEXT) neg.$(OBJEXT) \
     
    136137CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
    137138        -o $@
     139COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
     140        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
     141CCLD = $(CC)
     142LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
    138143SOURCES = $(libeigen_a_SOURCES) $(test_more_SOURCES)
    139144DIST_SOURCES = $(am__libeigen_a_SOURCES_DIST) \
     
    394399        erf.cpp \
    395400        exp.cpp \
     401        extern_value.cpp \
     402        extern_value.hpp \
    396403        for_hess.cpp \
    397404        for_sparse_jac.cpp \
     
    526533@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/erf.Po@am__quote@
    527534@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp.Po@am__quote@
     535@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extern_value.Po@am__quote@
    528536@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/for_hess.Po@am__quote@
    529537@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/for_sparse_jac.Po@am__quote@
Note: See TracChangeset for help on using the changeset viewer.