00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "Sacado_tradvec.hpp"
00043 #include <stdio.h>
00044
00045 typedef Sacado::RadVec::ADvar<double> ADVar;
00046
00047 ADVar
00048 foo(double d, ADVar x, ADVar y)
00049 { return d*x*y; }
00050
00051 ADVar
00052 goo(double d, ADVar x, ADVar y)
00053 { return d*(x*x + y*y); }
00054
00055 typedef struct
00056 ExpectedAnswer {
00057 const char *name;
00058 double v;
00059 double dvdx;
00060 double dvdy;
00061 };
00062
00063 static ExpectedAnswer expected[4] = {
00064 { "a", 6., 3., 2. },
00065 { "b", 13., 4., 6. },
00066 { "c", 19., 7., 8. },
00067 { "(a + b + c)", 38., 14., 16. }};
00068
00069 int
00070 botch(ExpectedAnswer *e, const char *partial, double got, double wanted)
00071 {
00072 char buf[32];
00073 const char *what;
00074
00075 what = e->name;
00076 if (partial) {
00077 snprintf(buf, sizeof(buf), "d%s/d%s", what, partial);
00078 what = buf;
00079 }
00080 fprintf(stderr, "Expected %s = %g, but got %g\n", what, wanted, got);
00081 return 1;
00082 }
00083
00084 int
00085 acheck(int k, double d, double v, double dvdx, double dvdy)
00086 {
00087 ExpectedAnswer *e = &expected[k];
00088 int nbad = 0;
00089
00090
00091
00092
00093 if (v != d*e->v)
00094 nbad += botch(e, 0, v, d*e->v);
00095 if (dvdx != d*e->dvdx)
00096 nbad += botch(e, "x", dvdx, d*e->dvdx);
00097 if (dvdy != d*e->dvdy)
00098 nbad += botch(e, "y", dvdy, d*e->dvdy);
00099 return nbad;
00100 }
00101
00102 int
00103 main(void)
00104 {
00105 double d, z[4];
00106 int i, nbad;
00107
00108 static ADVar a, b, c, x, y, *v[3] = {&a, &b, &c};
00109 static ADVar **V[4] = {v, v+1, v+2, v};
00110 static size_t np[4] = {1, 1, 1, 3};
00111 static double w[3] = { 1., 1., 1. };
00112 static double *W[4] = {w, w, w, w};
00113
00114 nbad = 0;
00115 for(d = 1.; d <= 2.; ++d) {
00116 printf("\nd = %g\n", d);
00117 x = 2;
00118 y = 3;
00119 a = foo(d,x,y);
00120 b = goo(d,x,y);
00121 c = a + b;
00122
00123 ADVar::Outvar_Gradcomp(a);
00124 printf("a = %g\n", a.val());
00125 printf("da/dx = %g\n", x.adj());
00126 printf("da/dy = %g\n", y.adj());
00127 nbad += acheck(0, d, a.val(), x.adj(), y.adj());
00128 z[0] = a.val();
00129
00130 ADVar::Outvar_Gradcomp(b);
00131 printf("b = %g\n", b.val());
00132 printf("db/dx = %g\n", x.adj());
00133 printf("db/dy = %g\n", y.adj());
00134 nbad += acheck(1, d, b.val(), x.adj(), y.adj());
00135 z[1] = b.val();
00136
00137 ADVar::Outvar_Gradcomp(c);
00138 printf("c = %g (should be a + b)\n", c.val());
00139 printf("dc/dx = %g\n", x.adj());
00140 printf("dc/dy = %g\n", y.adj());
00141 nbad += acheck(2, d, c.val(), x.adj(), y.adj());
00142 z[2] = c.val();
00143 z[3] = z[0] + z[1] + z[2];
00144
00145 ADVar::Weighted_GradcompVec(4,np,V,W);
00146 for(i = 0; i < 4; ++i) {
00147 printf("w %d:\td/dx = %g\td/dy = %g\n", i, x.adj(i), y.adj(i));
00148 nbad += acheck(i, d, z[i], x.adj(i), y.adj(i));
00149 }
00150 }
00151 if (nbad == 0)
00152 printf("\nExample passed!\n");
00153 else
00154 printf("\nSomething is wrong, example failed!\n");
00155 return nbad > 0;
00156 }