1 # ifndef CPPAD_CORE_FUN_CHECK_HPP 2 # define CPPAD_CORE_FUN_CHECK_HPP 3 /* -------------------------------------------------------------------------- 4 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell 5 6 CppAD is distributed under the terms of the 7 Eclipse Public License Version 2.0. 8 9 This Source Code may also be made available under the following 10 Secondary License when the conditions for such availability set forth 11 in the Eclipse Public License, Version 2.0 are satisfied: 12 GNU General Public License, Version 2.0 or later. 13 ---------------------------------------------------------------------------- */ 14 15 /* 16 $begin FunCheck$$ 17 $spell 18 exp 19 bool 20 const 21 Taylor 22 $$ 23 24 25 $section Check an ADFun Sequence of Operations$$ 26 27 $head Syntax$$ 28 $icode%ok% = FunCheck(%f%, %g%, %x%, %r%, %a%)%$$ 29 $pre 30 $$ 31 $bold See Also$$ 32 $cref CompareChange$$ 33 34 35 $head Purpose$$ 36 We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the 37 $cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$. 38 We use $latex G : \B{R}^n \rightarrow \B{R}^m$$ to denote the 39 function corresponding to the C++ function object $icode g$$. 40 This routine check if 41 $latex \[ 42 F(x) = G(x) 43 \]$$ 44 If $latex F(x) \neq G(x)$$, the 45 $cref/operation sequence/glossary/Operation/Sequence/$$ 46 corresponding to $icode f$$ does not represents the algorithm used 47 by $icode g$$ to calculate values for $latex G$$ 48 (see $cref/Discussion/FunCheck/Discussion/$$ below). 49 50 $head f$$ 51 The $code FunCheck$$ argument $icode f$$ has prototype 52 $codei% 53 ADFun<%Base%> %f% 54 %$$ 55 Note that the $cref ADFun$$ object $icode f$$ is not $code const$$ 56 (see $cref/Forward/FunCheck/FunCheck Uses Forward/$$ below). 57 58 $head g$$ 59 The $code FunCheck$$ argument $icode g$$ has prototype 60 $codei% 61 %Fun% &%g% 62 %$$ 63 ($icode Fun$$ is defined the properties of $icode g$$). 64 The C++ function object $icode g$$ supports the syntax 65 $codei% 66 %y% = %g%(%x%) 67 %$$ 68 which computes $latex y = G(x)$$. 69 70 $subhead x$$ 71 The $icode g$$ argument $icode x$$ has prototype 72 $codei% 73 const %Vector% &%x% 74 %$$ 75 (see $cref/Vector/FunCheck/Vector/$$ below) 76 and its size 77 must be equal to $icode n$$, the dimension of the 78 $cref/domain/seq_property/Domain/$$ space for $icode f$$. 79 80 $head y$$ 81 The $icode g$$ result $icode y$$ has prototype 82 $codei% 83 %Vector% %y% 84 %$$ 85 and its value is $latex G(x)$$. 86 The size of $icode y$$ 87 is equal to $icode m$$, the dimension of the 88 $cref/range/seq_property/Range/$$ space for $icode f$$. 89 90 $head x$$ 91 The $code FunCheck$$ argument $icode x$$ has prototype 92 $codei% 93 const %Vector% &%x% 94 %$$ 95 and its size 96 must be equal to $icode n$$, the dimension of the 97 $cref/domain/seq_property/Domain/$$ space for $icode f$$. 98 This specifies that point at which to compare the values 99 calculated by $icode f$$ and $icode G$$. 100 101 $head r$$ 102 The $code FunCheck$$ argument $icode r$$ has prototype 103 $codei% 104 const %Base% &%r% 105 %$$ 106 It specifies the relative error the element by element 107 comparison of the value of $latex F(x)$$ and $latex G(x)$$. 108 109 $head a$$ 110 The $code FunCheck$$ argument $icode a$$ has prototype 111 $codei% 112 const %Base% &%a% 113 %$$ 114 It specifies the absolute error the element by element 115 comparison of the value of $latex F(x)$$ and $latex G(x)$$. 116 117 $head ok$$ 118 The $code FunCheck$$ result $icode ok$$ has prototype 119 $codei% 120 bool %ok% 121 %$$ 122 It is true, if for $latex i = 0 , \ldots , m-1$$ 123 either the relative error bound is satisfied 124 $latex \[ 125 | F_i (x) - G_i (x) | 126 \leq 127 r ( | F_i (x) | + | G_i (x) | ) 128 \] $$ 129 or the absolute error bound is satisfied 130 $latex \[ 131 | F_i (x) - G_i (x) | \leq a 132 \] $$ 133 It is false if for some $latex (i, j)$$ neither 134 of these bounds is satisfied. 135 136 $head Vector$$ 137 The type $icode Vector$$ must be a $cref SimpleVector$$ class with 138 $cref/elements of type/SimpleVector/Elements of Specified Type/$$ 139 $icode Base$$. 140 The routine $cref CheckSimpleVector$$ will generate an error message 141 if this is not the case. 142 143 $head FunCheck Uses Forward$$ 144 After each call to $cref Forward$$, 145 the object $icode f$$ contains the corresponding 146 $cref/Taylor coefficients/glossary/Taylor Coefficient/$$. 147 After $code FunCheck$$, 148 the previous calls to $cref Forward$$ are undefined. 149 150 $head Discussion$$ 151 Suppose that the algorithm corresponding to $icode g$$ contains 152 $codei% 153 if( %x% >= 0 ) 154 %y% = exp(%x%) 155 else 156 %y% = exp(-%x%) 157 %$$ 158 where $icode x$$ and $icode y$$ are $codei%AD<double>%$$ objects. 159 It follows that the 160 AD of $code double$$ $cref/operation sequence/glossary/Operation/Sequence/$$ 161 depends on the value of $icode x$$. 162 If the sequence of operations stored in $icode f$$ corresponds to 163 $icode g$$ with $latex x \geq 0$$, 164 the function values computed using $icode f$$ when $latex x < 0$$ 165 will not agree with the function values computed by $latex g$$. 166 This is because the operation sequence corresponding to $icode g$$ changed 167 (and hence the object $icode f$$ does not represent the function 168 $latex G$$ for this value of $icode x$$). 169 In this case, you probably want to re-tape the calculations 170 performed by $icode g$$ with the 171 $cref/independent variables/glossary/Tape/Independent Variable/$$ 172 equal to the values in $icode x$$ 173 (so AD operation sequence properly represents the algorithm 174 for this value of independent variables). 175 176 177 $head Example$$ 178 $children% 179 example/general/fun_check.cpp 180 %$$ 181 The file 182 $cref fun_check.cpp$$ 183 contains an example and test of this function. 184 185 $end 186 --------------------------------------------------------------------------- 187 */ 188 189 namespace CppAD { 190 template <class Base, class RecBase, class Fun, class Vector> FunCheck(ADFun<Base,RecBase> & f,Fun & g,const Vector & x,const Base & r,const Base & a)191 bool FunCheck( 192 ADFun<Base, RecBase> &f , 193 Fun &g , 194 const Vector &x , 195 const Base &r , 196 const Base &a ) 197 { bool ok = true; 198 199 size_t m = f.Range(); 200 Vector yf = f.Forward(0, x); 201 Vector yg = g(x); 202 203 size_t i; 204 for(i = 0; i < m; i++) 205 ok &= NearEqual(yf[i], yg[i], r, a); 206 return ok; 207 } 208 } 209 210 # endif 211