29 #define UF(T,f,fn) T fn(T &x) { return f(x); }
31 #define UF4(f) UF(ADVar,f,f ## _ADV) UF(DADVar,f,f ## _DADV) UF(FDReal,f,f ## _FDR) UF(AFReal,f,f ## _AFR)
53 #define UF(T,f,fn) T fn(T &x, T &y) { return f(x,y); }
84 #define U4f(f,d) { #f, d, f ## _ADV, f ## _DADV, f ## _FDR, f ## _AFR }
138 return d > 5e-15 * (a + b);
146 fprintf(rc ? stderr : stdout,
"Usage: %s [-v]\n\
147 to compare consistency among several schemes for Hessian-vector computations.\n\
148 -v ==> verbose (show results)\n\
149 No -v ==> just print OK if all goes well; otherwise complain.\n", progname);
159 double a, *ap,
c, h[4], h1[4], v[3];
160 int b0, b1, b2, k, verbose;
161 static double unopargs[] = { .7, -.9, 2.5, -4.2, .1, .3, 1.2, -2.4, 0. };
162 static double binargs[] = { .1,.2, -.3,.4, -.5,-.6, .7,-.8,
163 1.1,2.2, -2.3,3.4, -2.5,-3.6, 2.7,-3.8, 0.};
165 #define Dcl(T,T1) T x ## T1, y ## T1, z ## T1
180 if (argc > 2 || *(s = argv[1]) !=
'-')
185 return usage(s[2] != 0);
189 return usage(strcmp(s,
"--help") ? 1 : 0);
202 #define In(T) p ## T[0] = &x ## T; p ## T[1] = &z ## T
207 fe = UT +
sizeof(
UT)/
sizeof(UT[0]);
208 for(ap = unopargs; (a = *ap++) != 0.; )
209 for(f = UT; f < fe; f++) {
210 if (a < f->dom[0] || a > f->
dom[1])
215 ADVar::Hvprod(1,pADV,v,h);
217 printf(
"%s(%g) = %g\n", f->
name, xADV.val(), yADV.val());
218 printf(
"%s' = %g\n", f->
name, xADV.adj());
219 printf(
"%s\" = %g\n", f->
name, h[0]);
222 yDADV = f->
f2(xDADV);
224 if (
differ(yDADV.val(), yADV.val())) {
226 printf(
"%s(%g): yADV = %g, yDADV = %g, diff = %.2g\n",
227 f->
name, a, yADV.val(), yDADV.val(),
228 yADV.val() - yDADV.val());
230 if (
differ(xADV.adj(), xDADV.adj())) {
232 printf(
"%s'(%g): ADV ==> %g, DADV ==> %g, diff = %.2g\n",
233 f->
name, a, xADV.adj(), xDADV.adj(),
234 xADV.adj() - xDADV.adj());
237 if (
differ(h[0], h1[0])) {
239 printf(
"%s\"(%g): ADV ==> %g, DADV ==> %g, diff = %.2g\n",
240 f->
name, a, h[0], h1[0], h[0] - h1[0]);
245 xFDR = a + tfFDR*v[0];
250 if (
differ(yFDR.val().val(), yADV.val())) {
252 printf(
"%s(%g): yFDR = %g, yADV = %g, diff = %.2g\n",
253 f->
name, a, yFDR.val().val(), yADV.val(),
254 yFDR.val().val() - yADV.val());
256 if (
differ(xFDR.val().adj(), h[0])) {
258 printf(
"%s\"(%g): FDR ==> %g, ADV ==> %g, diff = %.2g\n",
259 f->
name, a, xFDR.val().adj(), h[0],
260 xFDR.val().adj() - h[0]);
265 xAFR = a + tfFR*v[0];
268 if (
differ(yAFR.val().val(), yADV.val())) {
270 printf(
"%s(%g): yAFR = %g, yADV = %g, diff = %.2g\n",
271 f->
name, a, yAFR.val().val(), yADV.val(),
272 yAFR.val().val() - yADV.val());
274 if (
differ(xAFR.adj().val(), xADV.adj())) {
276 printf(
"%s'(%g): AFR ==> %g, ADV ==> %g, diff = %.2g\n",
277 f->
name, a, xAFR.adj().val(), xADV.adj(),
278 xAFR.adj().val() - xADV.adj());
280 if (
differ(xAFR.adj().dx(0), h[0])) {
282 printf(
"%s\"(%g): AFR ==> %g, ADV ==> %g, diff = %.2g\n",
283 f->
name, a, xAFR.adj().dx(0), h[0],
284 xAFR.adj().dx(0) - h[0]);
287 f2e = UT2 +
sizeof(
UT2)/
sizeof(UT2[0]);
288 for(ap = binargs; (a = *ap) != 0.; ap += 2) {
290 for(f2 = UT2; f2 < f2e; f2++) {
291 if (a < f2->xdom[0] || a > f2->
xdom[1])
295 yADV = f2->
f1(xADV, zADV);
297 ADVar::Hvprod(2,pADV,v,h);
298 ADVar::Hvprod(2,pADV,v+1,h+2);
300 printf(
"%s(%g,%g) = %g\n", f2->
name, xADV.val(), zADV.val(), yADV.val());
301 printf(
"%s' = (%g, %g)\n", f2->
name, xADV.adj(), zADV.adj());
302 printf(
"%s\" = (%8g\t%g)\n(%8g\t%g)", f2->
name, h[0],h[1],h[2],h[3]);
306 yDADV = f2->
f2(xDADV, zDADV);
308 if (
differ(yDADV.val(), yADV.val())) {
310 printf(
"%s(%g,%g): yADV = %g, yDADV = %g, diff = %.2g\n",
311 f2->
name, a, c, yADV.val(), yDADV.val(),
312 yADV.val() - yDADV.val());
314 if (
differ(xADV.adj(), xDADV.adj()) ||
differ(zADV.adj(), zDADV.adj())) {
316 printf(
"%s'(%g,%g): ADV ==> (%g,%g) DADV ==> (%g,%g), diff = (%.2g,%.2g)\n",
317 f2->
name, a, c, xADV.adj(), zADV.adj(),
318 xDADV.adj(), zDADV.adj(),
319 xADV.adj() - xDADV.adj(), zADV.adj() - zDADV.adj());
323 for(k = 0; k < 4; k++)
324 if (
differ(h[k], h1[k])) {
326 printf(
"%s\"(%g,%g):\n ADV ==> (%8g\t%8g\t%8g\t%g)\n",
327 f2->
name, a, c, h[0], h[1], h[2], h[3]);
328 printf(
"DADV ==> (%8g\t%8g\t%8g\t%g)\n",
329 h1[0], h1[1], h1[2], h1[3]);
330 printf(
"diff = (%.2g %.2g %.2g %.2g)\n\n",
331 h[0] - h1[0], h[1] - h1[1],
332 h[2] - h1[2], h[3] - h1[3]);
337 xFDR = a + tfFDR*v[0];
338 zFDR = c + tfFDR*v[1];
339 yFDR = f2->
f3(xFDR, zFDR);
343 if (
differ(yFDR.val().val(), yADV.val())) {
345 printf(
"%s(%g,%g): yFDR = %g, yADV = %g, diff = %.2g\n",
346 f2->
name, a, c, yFDR.val().val(), yADV.val(),
347 yFDR.val().val() - yADV.val());
349 if (
differ(xFDR.val().adj(), h[0]) ||
differ(zFDR.val().adj(), h[1])) {
351 printf(
"%s\"(%g,%g) row 1:\nFDR ==> (%g,%g)\nADV ==> (%g,%g)\n",
352 f2->
name, a, c, xFDR.val().adj(), zFDR.val().adj(),
354 printf(
"diff = %.2g %g\n\n",
355 xFDR.val().adj() - h[0], zFDR.val().adj() - h[1]);
358 xFDR = a + tfFDR*v[1];
359 zFDR = c + tfFDR*v[2];
360 yFDR = f2->
f3(xFDR, zFDR);
363 if (
differ(xFDR.val().adj(), h[2]) ||
differ(zFDR.val().adj(), h[3])) {
365 printf(
"%s\"(%g,%g) row 2:\nFDR ==> (%g,%g)\nADV ==> (%g,%g)\n",
366 f2->
name, a, c, xFDR.val().adj(), zFDR.val().adj(),
368 printf(
"diff = %.2g %g\n\n",
369 xFDR.val().adj() - h[2], zFDR.val().adj() - h[3]);
374 xAFR = a + tfFR*v[0];
375 zAFR = c + tfFR*v[1];
376 yAFR = f2->
f4(xAFR, zAFR);
378 if (
differ(yAFR.val().val(), yADV.val())) {
380 printf(
"%s(%g,%g): yAFR = %g, yADV = %g, diff = %.2g\n",
381 f2->
name, a, c, yAFR.val().val(), yADV.val(),
382 yAFR.val().val() - yADV.val());
384 if (
differ(xAFR.adj().val(), xADV.adj()) ||
differ(zAFR.adj().val(), zADV.adj())) {
386 printf(
"%s'(%g,%g):\n AFR ==> (%g,%g)\n ADV ==> (%g,%g)\n",
387 f2->
name, a, c, xAFR.adj().val(), zAFR.adj().val(),
388 xADV.adj(), zADV.adj());
389 printf(
" diff = %.2g %.2g\n\n",
390 xAFR.adj().val() - xADV.adj(),
391 zAFR.adj().val() - zADV.adj());
393 if (
differ(xAFR.adj().dx(0), h[0]) ||
differ(zAFR.adj().dx(0), h[1])) {
395 printf(
"%s\"(%g,%g) row 1:\n AFR ==> (%g,%g)\n",
396 f2->
name, a, c, xAFR.adj().dx(0), zAFR.adj().dx(0));
397 printf(
" ADV = (%g,%g)\n diff = %.2g %.2g\n\n", h[0], h[1],
398 xAFR.adj().dx(0) - h[0],
399 zAFR.adj().dx(0) - h[1]);
402 xAFR = a + tfFR*v[1];
403 zAFR = c + tfFR*v[2];
404 yAFR = f2->
f4(xAFR, zAFR);
406 if (
differ(xAFR.adj().dx(0), h[2]) ||
differ(zAFR.adj().dx(0), h[3])) {
408 printf(
"%s\"(%g,%g) row 2:\n AFR ==> (%g,%g)\n",
409 f2->
name, a, c, xAFR.adj().dx(0), zAFR.adj().dx(0));
410 printf(
" ADV = (%g,%g)\n diff = %.2g %.2g\n\n", h[2], h[3],
411 xAFR.adj().dx(0) - h[2],
412 zAFR.adj().dx(0) - h[3]);
419 if (*s ==
'.' && s[1] ==
'/')
420 for(s += 2; *s ==
'/'; ++s);
421 printf(
"%s: %d errors seen.\n", s, k);
Sacado::RadVec::ADvar< double > ADVar
AFReal(* AFReal_uf)(AFReal &)
Sacado::Fad::SFad< DReal, 1 > FDReal
static void Hvprod(int n, ADVar **vp, Double *v, Double *hv)
ADVar(* ADVar_uf)(ADVar &)
FDReal(* FDReal_uf2)(FDReal &, FDReal &)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
ADVar(* ADVar_uf2)(ADVar &, ADVar &)
Sacado::Fad::SFad< double, 1 > FReal
Sacado::Rad2::ADvar< double > DADVar
static int differ(double a, double b)
atan2(expr1.val(), expr2.val())
Sacado::Rad::ADvar< FReal > AFReal
static double dom_acosh[]
AFReal(* AFReal_uf2)(AFReal &, AFReal &)
SACADO_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
DADVar(* DADVar_uf2)(DADVar &, DADVar &)
DADVar(* DADVar_uf)(DADVar &)
FDReal(* FDReal_uf)(FDReal &)
Sacado::Rad::ADvar< double > DReal
static double dom_invtrig[]