Prev Next check_for_nan.cpp Headings

@(@\newcommand{\W}[1]{ \; #1 \; } \newcommand{\R}[1]{ {\rm #1} } \newcommand{\B}[1]{ {\bf #1} } \newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} } \newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} } \newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} } \newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }@)@
ADFun Checking For Nan: Example and Test
# include <cppad/cppad.hpp>
# include <cctype>

namespace {
     void myhandler(
          bool known       ,
          int  line        ,
          const char *file ,
          const char *exp  ,
          const char *msg  )
     {     // error handler must not return, so throw an exception
          std::string message = msg;
          throw message;
     }
}

bool check_for_nan(void)
{     bool ok = true;
     using CppAD::AD;
     using std::string;
     double eps = 10. * std::numeric_limits<double>::epsilon();

     // replace the default CppAD error handler
     CppAD::ErrorHandler info(myhandler);

     CPPAD_TESTVECTOR(AD<double>) ax(2), ay(2);
     ax[0] = 2.0;
     ax[1] = 1.0;
     CppAD::Independent(ax);
     ay[0] = sqrt( ax[0] );
     ay[1] = sqrt( ax[1] );
     CppAD::ADFun<double> f(ax, ay);

     CPPAD_TESTVECTOR(double) x(2), y(2);
     x[0] = 2.0;
     x[1] = -1.0;

     // use try / catch because this causes an exception
     // (assuming that NDEBUG is not defined)
     f.check_for_nan(true);
     try {
          y = f.Forward(0, x);

# ifndef NDEBUG
          // When compiled with NDEBUG defined,
          // CppAD does not spend time checking for nan.
          ok = false;
# endif
     }
     catch(std::string msg)
     {
          // get and check size of the independent variable vector
          string pattern = "vector_size = ";
          size_t start   = msg.find(pattern) + pattern.size();
          string number;
          for(size_t i = start; msg[i] != '\n'; i++)
               number += msg[i];
          size_t vector_size = std::atoi(number.c_str());
          ok &= vector_size == 2;

          // get and check first dependent variable index that is nan
          pattern = "index = ";
          start   = msg.find(pattern) + pattern.size();
          number  = "";
          for(size_t i = start; msg[i] != '\n'; i++)
               number += msg[i];
          size_t index = std::atoi(number.c_str());
          ok &= index == 1;

          // get the name of the file
          pattern = "file_name = ";
          start   = msg.find(pattern) + pattern.size();
          string file_name;
          for(size_t i = start; msg[i] != '\n'; i++)
               file_name += msg[i];

          // get and check independent variable vector that resulted in the nan
          CppAD::vector<double> vec(vector_size);
          CppAD::get_check_for_nan(vec, file_name);
          for(size_t i = 0; i < vector_size; i++)
               ok &= vec[i] == x[i];
     }

     // now do calculation without an exception
     f.check_for_nan(false);
     y = f.Forward(0, x);
     ok &= CppAD::NearEqual(y[0], std::sqrt(x[0]), eps, eps);
     ok &= CppAD::isnan( y[1] );

     return ok;
}

Input File: example/general/check_for_nan.cpp