Changeset 3744


Ignore:
Timestamp:
Nov 6, 2015 10:33:15 AM (5 years ago)
Author:
bradbell
Message:

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 5c92f4e222d7edf44cc2633c5671418dd05473d0
end hash code: 079578bc3de0b44d7c647216b46090f45bbeca9d

commit 079578bc3de0b44d7c647216b46090f45bbeca9d
Author: Brad Bell <bradbell@…>
Date: Fri Nov 6 07:02:07 2015 -0800

Store and recover independent variables when nan occurs during Forward(0, x).


forward.hpp: remove invisible white space.
forward.cpp: remove invisible white space.

Location:
trunk
Files:
1 added
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/cppad/CMakeLists.txt

    r3685 r3744  
    279279        )
    280280ENDIF( NOT cppad_max_num_threads_is_integer_ge_4 )
    281 
     281# -----------------------------------------------------------------------------
     282# cppad_has_mkstemp
     283#
     284SET(CMAKE_REQUIRED_INCLUDES  "")
     285SET(CMAKE_REQUIRED_LIBRARIES "")
     286SET(CMAKE_REQUIRED_FLAGS     )
     287SET(source "
     288# include <stdlib.h>
     289int main(void)
     290{
     291        char pattern[] = \"/tmp/fileXXXXXX\";
     292        int fd = mkstemp(pattern);
     293        return 0;
     294}
     295" )
     296CHECK_CXX_SOURCE_RUNS("${source}" cppad_has_mkstemp )
    282297# -----------------------------------------------------------------------------
    283298# Copy a file to another location and modify its contents.
  • trunk/cppad/configure.hpp.in

    r3732 r3744  
    186186# endif
    187187
     188/*!
     189\def CPPAD_HAS_MKSTEMP
     190It true, mkstemp works in C++ on this system.
     191*/
     192# define CPPAD_HAS_MKSTEMP @cppad_has_mkstemp@
     193
    188194# endif
  • trunk/cppad/local/ad_fun.hpp

    r3712 r3744  
    5252        cppad/local/fun_check.hpp%
    5353        cppad/local/optimize.hpp%
    54         omh/check_for_nan.omh
     54        cppad/local/check_for_nan.hpp
    5555%$$
    5656
  • trunk/cppad/local/forward.hpp

    r3607 r3744  
    77
    88CppAD is distributed under multiple licenses. This distribution is under
    9 the terms of the 
     9the terms of the
    1010                    Eclipse Public License Version 1.0.
    1111
     
    1717# include <cppad/local/capacity_order.hpp>
    1818# include <cppad/local/num_skip.hpp>
     19# include <cppad/local/check_for_nan.hpp>
    1920
    2021namespace CppAD { // BEGIN_CPPAD_NAMESPACE
     
    3536
    3637\param q
    37 is the hightest order for this forward mode computation; i.e., 
     38is the hightest order for this forward mode computation; i.e.,
    3839after this calculation there will be <code>q+1</code>
    3940Taylor coefficients per variable.
     
    4243contains Taylor coefficients for the independent variables.
    4344The size of xq must either be n or <code>(q+1)*n</code>,
    44 We define <code>p = q + 1 - xq.size()/n</code>. 
     45We define <code>p = q + 1 - xq.size()/n</code>.
    4546For <code>j = 0 , ... , n-1</code>,
    4647<code>k = p, ... , q</code>, are
     
    5657For <code>i = 0, ... , m-1</code>,
    5758<code>k = p, ..., q</code>,
    58 <code>y[(q+1-p)*i + (k-p)]</code> 
     59<code>y[(q+1-p)*i + (k-p)]</code>
    5960is the k-th order coefficient for the i-th dependent variable.
    6061
     
    7071is the k-th order cofficent,
    7172for the i-th varaible on the tape.
    72 (The first independent variable has index one on the tape 
     73(The first independent variable has index one on the tape
    7374and there is no variable with index zero.)
    7475*/
     
    7778template <typename VectorBase>
    7879VectorBase ADFun<Base>::Forward(
    79         size_t              q         , 
    80         const VectorBase&   xq        , 
     80        size_t              q         ,
     81        const VectorBase&   xq        ,
    8182              std::ostream& s         )
    8283{       // temporary indices
     
    105106                "Forward(q, xq): Number of Taylor coefficient orders stored in this"
    106107                " ADFun\nis less than q and xq.size() != n*(q+1)."
    107         ); 
     108        );
    108109        CPPAD_ASSERT_KNOWN(
    109110                p <= 1 || num_direction_taylor_ == 1,
     
    149150        if( q == 0 )
    150151        {       forward0sweep(s, true,
    151                         n, num_var_tape_, &play_, C, 
     152                        n, num_var_tape_, &play_, C,
    152153                        taylor_.data(), cskip_op_.data(), load_op_,
    153154                        compare_change_count_,
     
    157158        }
    158159        else
    159         {       forward1sweep(s, true, p, q, 
    160                         n, num_var_tape_, &play_, C, 
     160        {       forward1sweep(s, true, p, q,
     161                        n, num_var_tape_, &play_, C,
    161162                        taylor_.data(), cskip_op_.data(), load_op_,
    162163                        compare_change_count_,
     
    177178        else
    178179        {       yq.resize(m * (q+1) );
    179                 for(i = 0; i < m; i++) 
     180                for(i = 0; i < m; i++)
    180181                {       for(k = 0; k <= q; k++)
    181                                 yq[ (q+1) * i + k] = 
    182                                         taylor_[ C * dep_taddr_[i] + k ]; 
     182                                yq[ (q+1) * i + k] =
     183                                        taylor_[ C * dep_taddr_[i] + k ];
    183184                }
    184185        }
     
    191192                                ok &= ! CppAD::isnan( yq[ (q+1) * i + 0 ] );
    192193                        }
    193                 }
     194                }
     195                if( ! ok )
     196                {       CppAD::vector<Base> x0(n);
     197                        for(j = 0; j < n; j++)
     198                                x0[j] = taylor_[ C * ind_taddr_[j] + 0 ];
     199                        std::string  file_name;
     200                        put_check_for_nan(x0, file_name);
     201                        std::stringstream ss;
     202                        ss <<
     203                        "yq = f.Forward(q, xq): a zero order Taylor coefficient is nan.\n"
     204                        "Corresponding independent variables vector was written "
     205                        "to binary a file.\n"
     206                        "vector_size = " << n << "\n" <<
     207                        "file_name = " << file_name << "\n";
     208                        const char* msg = ss.str().c_str();
     209                        ErrorHandler::Call(
     210                                true,
     211                                __LINE__,
     212                                __FILE__,
     213                                "! CppAD::isnan( yq[ (q+1) * i + 0 ] )",
     214                                msg
     215                        );
     216                }
    194217                CPPAD_ASSERT_KNOWN(ok,
    195                         "yq = f.Forward(q, xq): has a zero order Taylor coefficient "
    196218                        "with the value nan."
    197                 ); 
     219                );
    198220                if( 0 < q )
    199221                {       for(i = 0; i < m; i++)
     
    244266The size of xq must either be <code>r*n</code>,
    245267For <code>j = 0 , ... , n-1</code>,
    246 <code>ell = 0, ... , r-1</code>, 
     268<code>ell = 0, ... , r-1</code>,
    247269<code>xq[ ( r*j + ell ]</code>
    248270is the q-th order coefficient for the j-th independent variable
     
    253275The size of the return value \c y is <code>r*m</code>.
    254276For <code>i = 0, ... , m-1</code>,
    255 <code>ell = 0, ... , r-1</code>, 
    256 <code>y[ r*i + ell ]</code> 
     277<code>ell = 0, ... , r-1</code>,
     278<code>y[ r*i + ell ]</code>
    257279is the q-th order coefficient for the i-th dependent variable
    258280and the ell-th direction.
     
    274296is the k-th order cofficent,
    275297for the i-th varaible, and ell-th direction.
    276 (The first independent variable has index one on the tape 
     298(The first independent variable has index one on the tape
    277299and there is no variable with index zero.)
    278300*/
     
    281303template <typename VectorBase>
    282304VectorBase ADFun<Base>::Forward(
    283         size_t              q         , 
    284         size_t              r         , 
     305        size_t              q         ,
     306        size_t              r         ,
    285307        const VectorBase&   xq        )
    286308{       // temporary indices
     
    305327                "Forward(q, r, xq): Number of Taylor coefficient orders stored in"
    306328                " this ADFun is less than q"
    307         ); 
     329        );
    308330        CPPAD_ASSERT_KNOWN(
    309331                q == 1 || num_direction_taylor_ == r ,
     
    311333                " is not same as previous Forward(1, r, xq)"
    312334        );
    313                
     335
    314336        // does taylor_ need more orders or new number of directions
    315337        if( cap_order_taylor_ <= q || num_direction_taylor_ != r )
     
    343365        CPPAD_ASSERT_UNKNOWN( load_op_.size()  == play_.num_load_op_rec() );
    344366        forward2sweep(
    345                 q, 
    346                 r, 
    347                 n, 
    348                 num_var_tape_, 
    349                 &play_, 
    350                 c, 
    351                 taylor_.data(), 
    352                 cskip_op_.data(), 
     367                q,
     368                r,
     369                n,
     370                num_var_tape_,
     371                &play_,
     372                c,
     373                taylor_.data(),
     374                cskip_op_.data(),
    353375                load_op_
    354376        );
  • trunk/cppad/local/undef.hpp

    r3740 r3744  
    7575# undef CPPAD_HAS_COLPACK
    7676# undef CPPAD_HAS_GETTIMEOFDAY
     77# undef CPPAD_HAS_MKSTEMP
    7778# undef CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
    7879# undef CPPAD_MAX_NUM_CAPACITY
  • trunk/example/check_for_nan.cpp

    r3738 r3744  
    2424// BEGIN C++
    2525# include <cppad/cppad.hpp>
     26# include <cctype>
    2627
    2728namespace {
     
    3334                const char *msg  )
    3435        {       // error handler must not return, so throw an exception
    35                 throw std::string("myhandler");
     36                std::string message = msg;
     37                throw message;
    3638        }
    3739}
     
    4042{       bool ok = true;
    4143        using CppAD::AD;
     44        using std::string;
     45        double eps = 10. * std::numeric_limits<double>::epsilon();
    4246
    4347        // replace the default CppAD error handler
     
    4549
    4650        CPPAD_TESTVECTOR(AD<double>) ax(2), ay(2);
    47         ax[0] = 0.0;
     51        ax[0] = 2.0;
    4852        ax[1] = 1.0;
    4953        CppAD::Independent(ax);
    50         ay    = ax;
     54        ay[0] = sqrt( ax[0] );
     55        ay[1] = sqrt( ax[1] );
    5156        CppAD::ADFun<double> f(ax, ay);
    5257
    5358        CPPAD_TESTVECTOR(double) x(2), y(2);
    5459        x[0] = 2.0;
    55         x[1] = CppAD::numeric_limits<double>::quiet_NaN();
     60        x[1] = -1.0;
    5661
    5762        // use try / catch because this causes an exception
     
    6873        }
    6974        catch(std::string msg)
    70         {       ok &= msg == "myhandler";
     75        {       // check size of the independent variable vector
     76                string pattern = "vector_size = ";
     77                size_t start   = msg.find(pattern) + pattern.size();
     78                string number;
     79                for(size_t i = start; msg[i] != '\n'; i++)
     80                        number += msg[i];
     81                size_t vec_size = std::atoi(number.c_str());
     82                ok &= vec_size == 2;
     83
     84                // get the name of the file
     85                pattern = "file_name = ";
     86                start   = msg.find(pattern) + pattern.size();
     87                string file_name;
     88                for(size_t i = start; msg[i] != '\n'; i++)
     89                        file_name += msg[i];
     90
     91                // get the independent variable vector that resulted in the nan
     92                CppAD::vector<double> vec(vec_size);
     93                CppAD::get_check_for_nan(vec, file_name);
     94                for(size_t i = 0; i < vec_size; i++)
     95                        ok &= vec[i] == x[i];
    7196        }
    7297
     
    7499        f.check_for_nan(false);
    75100        y = f.Forward(0, x);
    76         ok &= y[0] == x[0];
     101        ok &= CppAD::NearEqual(y[0], std::sqrt(x[0]), eps, eps);
    77102        ok &= CppAD::isnan( y[1] );
    78103
  • trunk/makefile.am

    r3738 r3744  
    160160        cppad/local/capacity_order.hpp \
    161161        cppad/local/checkpoint.hpp \
     162        cppad/local/check_for_nan.hpp \
    162163        cppad/local/color_general.hpp \
    163164        cppad/local/color_symmetric.hpp \
  • trunk/makefile.in

    r3738 r3744  
    551551        cppad/local/capacity_order.hpp \
    552552        cppad/local/checkpoint.hpp \
     553        cppad/local/check_for_nan.hpp \
    553554        cppad/local/color_general.hpp \
    554555        cppad/local/color_symmetric.hpp \
  • trunk/omh/whats_new/whats_new_15.omh

    r3743 r3744  
    7575assist you in learning about changes between various versions of CppAD.
    7676
     77$head 11-06$$
     78It is often difficult to determine what cause a $code nan$$ result
     79during an operation with an $cref ADFun$$ object.
     80The new feature
     81$cref/get_check_for_nan/check_for_nan/get_check_for_nan/$$ was
     82added to make this easier.
     83
    7784$head 10-21$$
    7885There was a mistake in the documentation for $cref index_sort$$,
  • trunk/test_more/forward.cpp

    r2570 r3744  
    11/* $Id$ */
    22/* --------------------------------------------------------------------------
    3 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
     3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    44
    55CppAD is distributed under multiple licenses. This distribution is under
    6 the terms of the 
     6the terms of the
    77                    Eclipse Public License Version 1.0.
    88
     
    2525        using namespace CppAD;
    2626
    27         // independent variable vector 
     27        // independent variable vector
    2828        CPPAD_TESTVECTOR(AD<double>) X(2);
    29         X[0] = 0.; 
     29        X[0] = 0.;
    3030        X[1] = 1.;
    3131        Independent(X);
     
    3838        ADFun<double> F(X, Y);
    3939
    40         // use zero order to evaluate F[ (3, 4) ] 
     40        // use zero order to evaluate F[ (3, 4) ]
    4141        VectorDouble x0( F.Domain() );
    4242        VectorDouble y0( F.Range() );
     
    9494        using namespace CppAD;
    9595
    96         // independent variable vector 
     96        // independent variable vector
    9797        CPPAD_TESTVECTOR(AD<double>) U(3);
    9898        U[0] = 0.; U[1] = 1.; U[2] = 2.;
     
    108108        }
    109109
    110         // dependent variable vector 
     110        // dependent variable vector
    111111        CPPAD_TESTVECTOR(AD<double>) V(2);
    112112        V[0] = sum;
     
    146146
    147147        // compare values
    148         ok &= NearEqual(v1[0] , 
     148        ok &= NearEqual(v1[0] ,
    149149                g0[0]*u1[0] + g0[1]*u1[1] + g0[2]*u1[2] , 1e-10, 1e-10);
    150         ok &= NearEqual(v1[1] , 
     150        ok &= NearEqual(v1[1] ,
    151151                g1[0]*u1[0] + g1[1]*u1[1] + g1[2]*u1[2] , 1e-10, 1e-10);
    152152
     
    156156        CPPAD_TESTVECTOR(double) v2( f.Range() );
    157157        p     = 2;
    158         u2[0] = .5; u2[1] = .4; u2[2] = .3; 
     158        u2[0] = .5; u2[1] = .4; u2[2] = .3;
    159159        v2    = f.Forward(p, u2);
    160160
     
    167167
    168168        // compare values
    169         ok &= NearEqual(v2[0] , 
     169        ok &= NearEqual(v2[0] ,
    170170                g0[0]*u2[0] + g0[1]*u2[1] + g0[2]*u2[2] , 1e-10, 1e-10);
    171171
     
    173173        double v2_1 = 0.;
    174174        for(i = 0; i < 3; i++)
    175         {       v2_1 += g1[i] * u2[i];   
     175        {       v2_1 += g1[i] * u2[i];
    176176                for(j = 0; j < 3; j++)
    177177                        v2_1 += .5 * u1[i] * H1[i * 3 + j] * u1[j];
     
    190190        const char *msg      )
    191191{       // error hander must not return, so throw an exception
    192         throw std::string(msg);
     192        std::string message = msg;
     193        throw message;
    193194}
    194195
    195196bool forward_nan(void)
    196 {       
     197{
    197198
    198199        using CppAD::vector;
     
    219220        }
    220221        catch( std::string msg )
    221         {       // check that the message contains "nan"
    222                 ok = msg.find("nan") != std::string::npos;
    223         }
    224 
    225         return ok;
    226 }
    227 } // END empty namespace
     222        {       // check that the message contains
     223                // "vector_size = " and "file_name = "
     224                ok = msg.find("vector_size = ") != std::string::npos;
     225                ok = msg.find("file_name = ") != std::string::npos;
     226        }
     227
     228        return ok;
     229}
     230} // END empty namespace
    228231
    229232# include <vector>
Note: See TracChangeset for help on using the changeset viewer.