tradvec_example.cpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Sacado Package
00005 //                 Copyright (2006) Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00025 // (etphipp@sandia.gov).
00026 //
00027 // ***********************************************************************
00028 // @HEADER
00029 
00030 // tradvec_example
00031 //
00032 //  usage:
00033 //     tradvec_example
00034 //
00035 //  output:
00036 //     prints the results of differentiating two simple functions and their
00037 //     sum with reverse mode AD using functions Outvar_Gradcomp and
00038 //     Weighted_GradcompVec in the Sacado::RadVec::ADvar class.
00039 
00040 /* Simple test of Outvar_Gradcomp and Weighted_GradcompVec. */
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; // value of name
00059   double dvdx;  // partial w.r.t. x
00060   double dvdy;  // partial w.r.t. y
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   /* There should be no round-off error in this simple example, so we */
00091   /* use exact comparisons, rather than, say, relative differences. */
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   }

Generated on Wed May 12 21:59:08 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7