CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
check_for_nan.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_CHECK_FOR_NAN_HPP
2 # define CPPAD_CORE_CHECK_FOR_NAN_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 /*
15 $begin check_for_nan$$
16 $spell
17  std
18  vec
19  Cpp
20  const
21  bool
22  newline
23 $$
24 $section Check an ADFun Object For Nan Results$$
25 
26 $head Syntax$$
27 $icode%f%.check_for_nan(%b%)
28 %$$
29 $icode%b% = %f%.check_for_nan()
30 %$$
31 $codei%get_check_for_nan(%vec%, %file%)
32 %$$
33 
34 $head Debugging$$
35 If $code NDEBUG$$ is not defined, and
36 the result of a $cref/forward/forward_order/$$ or $cref/reverse/reverse_any/$$
37 calculation contains a $cref nan$$,
38 CppAD can halt with an error message.
39 
40 $head f$$
41 For the syntax where $icode b$$ is an argument,
42 $icode f$$ has prototype
43 $codei%
44  ADFun<%Base%> %f%
45 %$$
46 (see $codei%ADFun<%Base%>%$$ $cref/constructor/FunConstruct/$$).
47 For the syntax where $icode b$$ is the result,
48 $icode f$$ has prototype
49 $codei%
50  const ADFun<%Base%> %f%
51 %$$
52 
53 $head b$$
54 This argument or result has prototype
55 $codei%
56  bool %b%
57 %$$
58 Future calls to $icode%f%.Forward%$$ will (will not) check for $code nan$$.
59 depending on if $icode b$$ is true (false).
60 
61 $head Default$$
62 The value for this setting after construction of $icode f$$) is true.
63 The value of this setting is not affected by calling
64 $cref Dependent$$ for this function object.
65 
66 $head Error Message$$
67 If this error is detected during zero order forward mode,
68 the values of the independent variables that resulted in the $code nan$$
69 are written to a temporary binary file.
70 This is so that you can run the original source code with those values
71 to see what is causing the $code nan$$.
72 
73 $subhead vector_size$$
74 The error message with contain the text
75 $codei%vector_size = %vector_size%$$ followed the newline character
76 $code '\n'$$.
77 The value of $icode vector_size$$ is the number of elements
78 in the independent vector.
79 
80 $subhead file_name$$
81 The error message with contain the text
82 $codei%file_name = %file_name%$$ followed the newline character
83 $code '\n'$$.
84 The value of $icode file_name$$ is the name of the temporary file
85 that contains the dependent variable values.
86 
87 $subhead index$$
88 The error message will contain the text
89 $codei%index = %index%$$ followed by the newline character $code '\n'$$.
90 The value of $icode index$$ is the lowest dependent variable index
91 that has the value $code nan$$.
92 
93 $head get_check_for_nan$$
94 This routine can be used to get the independent variable
95 values that result in a $code nan$$.
96 
97 $subhead vec$$
98 This argument has prototype
99 $codei%
100  CppAD::vector<%Base%>& %vec%
101 %$$
102 It size must be equal to the corresponding value of
103 $cref/vector_size/check_for_nan/Error Message/vector_size/$$
104 in the corresponding error message.
105 The input value of its elements does not matter.
106 Upon return, it will contain the values for the independent variables,
107 in the corresponding call to $cref Independent$$,
108 that resulted in the $code nan$$.
109 (Note that the call to $code Independent$$ uses an vector with elements
110 of type $codei%AD<%Base%>%$$ and $icode vec$$ has elements of type
111 $icode Base$$.)
112 
113 $subhead file$$
114 This argument has prototype
115 $codei%
116  const std::string& %file%
117 %$$
118 It must be the value of
119 $cref/file_name/check_for_nan/Error Message/file_name/$$
120 in the corresponding error message.
121 
122 $head Example$$
123 $children%
124  example/general/check_for_nan.cpp
125 %$$
126 The file
127 $cref check_for_nan.cpp$$
128 contains an example and test of these operations.
129 It returns true if it succeeds and false otherwise.
130 
131 $end
132 */
133 
134 # include <cppad/utility/vector.hpp>
135 # include <cppad/configure.hpp>
136 # include <fstream>
137 
138 # if CPPAD_HAS_MKSTEMP
139 # include <stdlib.h>
140 # include <unistd.h>
141 # else
142 # if CPPAD_HAS_TMPNAM_S
143 # include <stdio.h>
144 # else
145 # include <stdlib.h>
146 # endif
147 # endif
148 
149 
150 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
151 
152 /*!
153 Set check_for_nan
154 
155 \param value
156 new value for this flag.
157 */
158 template <class Base>
160 { check_for_nan_ = value; }
161 
162 /*!
163 Get check_for_nan
164 
165 \return
166 current value of check_for_nan_.
167 */
168 template <class Base>
170 { return check_for_nan_; }
171 
172 /*!
173 Stores a vector in a file when nans occur.
174 
175 \param vec [in]
176 is the vector that is stored.
177 
178 \param [out] file_name
179 is the file where the vector is stored
180 */
181 template <class Base>
182 void put_check_for_nan(const CppAD::vector<Base>& vec, std::string& file_name)
183 {
184  size_t char_size = sizeof(Base) * vec.size();
185  const char* char_ptr = reinterpret_cast<const char*>( vec.data() );
186 # if CPPAD_HAS_MKSTEMP
187  char pattern[] = "/tmp/fileXXXXXX";
188  int fd = mkstemp(pattern);
189  file_name = pattern;
190  write(fd, char_ptr, char_size);
191  close(fd);
192 # else
193 # if CPPAD_HAS_TMPNAM_S
194  std::vector<char> name(L_tmpnam_s);
195  if( tmpnam_s( name.data(), L_tmpnam_s ) != 0 )
197  false,
198  "Cannot create a temporary file name"
199  );
200  }
201  file_name = name.data();
202 # else
203  file_name = tmpnam( CPPAD_NULL );
204 # endif
205  std::fstream file_out(file_name.c_str(), std::ios::out|std::ios::binary );
206  file_out.write(char_ptr, char_size);
207  file_out.close();
208 # endif
209  return;
210 }
211 
212 /*!
213 Gets a vector that was stored by put_check_for_nan.
214 
215 \param vec [out]
216 is the vector that is stored.
217 
218 \param file_name [in]
219 is the file where the vector is stored
220 */
221 template <class Base>
222 void get_check_for_nan(CppAD::vector<Base>& vec, const std::string& file_name)
223 { //
224  size_t n = vec.size();
225  size_t char_size = sizeof(Base) * n;
226  char* char_ptr = reinterpret_cast<char*>( vec.data() );
227  //
228  std::fstream file_in(file_name.c_str(), std::ios::in|std::ios::binary );
229  file_in.read(char_ptr, char_size);
230  //
231  return;
232 }
233 
234 } // END_CPPAD_NAMESPACE
235 
236 # endif
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
void put_check_for_nan(const CppAD::vector< Base > &vec, std::string &file_name)
Stores a vector in a file when nans occur.
Type * data(void)
raw pointer to the data
Definition: vector.hpp:391
bool check_for_nan(void) const
get check_for_nan
size_t size(void) const
number of elements currently in this vector.
Definition: vector.hpp:387
File used to define CppAD::vector and CppAD::vectorBool.
void get_check_for_nan(CppAD::vector< Base > &vec, const std::string &file_name)
Gets a vector that was stored by put_check_for_nan.