Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tradvec_example.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 // tradvec_example
31 //
32 // usage:
33 // tradvec_example
34 //
35 // output:
36 // prints the results of differentiating two simple functions and their
37 // sum with reverse mode AD using functions Outvar_Gradcomp and
38 // Weighted_GradcompVec in the Sacado::RadVec::ADvar class.
39 
40 /* Simple test of Outvar_Gradcomp and Weighted_GradcompVec. */
41 
42 #include "Sacado_tradvec.hpp"
43 #include <stdio.h>
44 
45 #ifdef _MSC_VER
46 # define snprintf _snprintf
47 #endif
48 
50 
51  ADVar
52 foo(double d, ADVar x, ADVar y)
53 { return d*x*y; }
54 
55  ADVar
56 goo(double d, ADVar x, ADVar y)
57 { return d*(x*x + y*y); }
58 
59  struct
61  const char *name;
62  double v; // value of name
63  double dvdx; // partial w.r.t. x
64  double dvdy; // partial w.r.t. y
65  };
66 
67  static ExpectedAnswer expected[4] = {
68  { "a", 6., 3., 2. },
69  { "b", 13., 4., 6. },
70  { "c", 19., 7., 8. },
71  { "(a + b + c)", 38., 14., 16. }};
72 
73  int
74 botch(ExpectedAnswer *e, const char *partial, double got, double wanted)
75 {
76  char buf[32];
77  const char *what;
78 
79  what = e->name;
80  if (partial) {
81  snprintf(buf, sizeof(buf), "d%s/d%s", what, partial);
82  what = buf;
83  }
84  fprintf(stderr, "Expected %s = %g, but got %g\n", what, wanted, got);
85  return 1;
86  }
87 
88  int
89 acheck(int k, double d, double v, double dvdx, double dvdy)
90 {
91  ExpectedAnswer *e = &expected[k];
92  int nbad = 0;
93 
94  /* There should be no round-off error in this simple example, so we */
95  /* use exact comparisons, rather than, say, relative differences. */
96 
97  if (v != d*e->v)
98  nbad += botch(e, 0, v, d*e->v);
99  if (dvdx != d*e->dvdx)
100  nbad += botch(e, "x", dvdx, d*e->dvdx);
101  if (dvdy != d*e->dvdy)
102  nbad += botch(e, "y", dvdy, d*e->dvdy);
103  return nbad;
104  }
105 
106  int
107 main(void)
108 {
109  double d, z[4];
110  int i, nbad;
111 
112  static ADVar a, b, c, x, y, *v[3] = {&a, &b, &c};
113  static ADVar **V[4] = {v, v+1, v+2, v};
114  static size_t np[4] = {1, 1, 1, 3};
115  static double w[3] = { 1., 1., 1. };
116  static double *W[4] = {w, w, w, w};
117 
118  nbad = 0;
119  for(d = 1.; d <= 2.; ++d) {
120  printf("\nd = %g\n", d);
121  x = 2;
122  y = 3;
123  a = foo(d,x,y);
124  b = goo(d,x,y);
125  c = a + b;
126 
128  printf("a = %g\n", a.val());
129  printf("da/dx = %g\n", x.adj());
130  printf("da/dy = %g\n", y.adj());
131  nbad += acheck(0, d, a.val(), x.adj(), y.adj());
132  z[0] = a.val();
133 
135  printf("b = %g\n", b.val());
136  printf("db/dx = %g\n", x.adj());
137  printf("db/dy = %g\n", y.adj());
138  nbad += acheck(1, d, b.val(), x.adj(), y.adj());
139  z[1] = b.val();
140 
142  printf("c = %g (should be a + b)\n", c.val());
143  printf("dc/dx = %g\n", x.adj());
144  printf("dc/dy = %g\n", y.adj());
145  nbad += acheck(2, d, c.val(), x.adj(), y.adj());
146  z[2] = c.val();
147  z[3] = z[0] + z[1] + z[2];
148 
149  ADVar::Weighted_GradcompVec(4,np,V,W);
150  for(i = 0; i < 4; ++i) {
151  printf("w %d:\td/dx = %g\td/dy = %g\n", i, x.adj(i), y.adj(i));
152  nbad += acheck(i, d, z[i], x.adj(i), y.adj(i));
153  }
154  }
155  if (nbad == 0)
156  printf("\nExample passed!\n");
157  else
158  printf("\nSomething is wrong, example failed!\n");
159  return nbad > 0;
160  }
int botch(ExpectedAnswer *e, const char *partial, double got, double wanted)
Sacado::RadVec::ADvar< double > ADVar
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
static void Outvar_Gradcomp(ADvar &v)
int main()
Definition: ad_example.cpp:191
ADVar foo(double d, ADVar x, ADVar y)
int acheck(int k, double d, double v, double dvdx, double dvdy)
const char * name
static void Weighted_GradcompVec(size_t n, size_t *np, ADvar ***v, Double **w)
ADVar goo(double d, ADVar x, ADVar y)
static ExpectedAnswer expected[4]