File: fun_check.cpp

package info (click to toggle)
cppad 2025.00.00.2-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 11,552 kB
  • sloc: cpp: 112,594; sh: 5,972; ansic: 179; python: 71; sed: 12; makefile: 10
file content (133 lines) | stat: -rw-r--r-- 3,738 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-22 Bradley M. Bell
// ----------------------------------------------------------------------------
/*
! WARNING: This file is used as an example by fun_construct and Dependent

{xrst_begin fun_check.cpp}

ADFun Check and Re-Tape: Example and Test
#########################################

{xrst_literal
   // BEGIN C++
   // END C++
}

{xrst_end fun_check.cpp}
*/
// BEGIN C++
# include <cppad/cppad.hpp>

namespace { // -----------------------------------------------------------
// define the template function object Fun<Type,Vector> in empty namespace
template <class Type, class Vector>
class Fun {
private:
   size_t n;
public:
   // function constructor
   Fun(size_t n_) : n(n_)
   { }
   // function evaluator
   Vector operator() (const Vector &x)
   {  Vector y(n);
      size_t i;
      for(i = 0; i < n; i++)
      {  // This operation sequence depends on x
         if( x[i] >= 0 )
            y[i] = exp(x[i]);
         else
            y[i] = exp(-x[i]);
      }
      return y;
   }
};
// template function FunCheckCases<Vector, ADVector> in empty namespace
template <class Vector, class ADVector>
bool FunCheckCases(void)
{  bool ok = true;
   using CppAD::AD;
   using CppAD::ADFun;
   using CppAD::Independent;
   double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

   // use the ADFun default constructor
   ADFun<double> f;

   // domain space vector
   size_t n = 2;
   ADVector X(n);
   X[0] = -1.;
   X[1] = 1.;

   // declare independent variables and starting recording
   Independent(X);

   // create function object to use with AD<double>
   Fun< AD<double>, ADVector > G(n);

   // range space vector
   size_t m = n;
   ADVector Y(m);
   Y = G(X);

   // stop tape and store operation sequence in f : X -> Y
   f.Dependent(X, Y);
   ok &= (f.size_order() == 0);  // no implicit forward operation

   // create function object to use with double
   Fun<double, Vector> g(n);

   // function values should agree when the independent variable
   // values are the same as during recording
   Vector x(n);
   size_t j;
   for(j = 0; j < n; j++)
      x[j] = Value(X[j]);
   double r = eps99;
   double a = eps99;
   ok      &= FunCheck(f, g, x, a, r);

   // function values should not agree when the independent variable
   // values are the negative of values during recording
   for(j = 0; j < n; j++)
      x[j] = - Value(X[j]);
   ok      &= ! FunCheck(f, g, x, a, r);

   // re-tape to obtain the new AD of double operation sequence
   for(j = 0; j < n; j++)
      X[j] = x[j];
   Independent(X);
   Y = G(X);

   // stop tape and store operation sequence in f : X -> Y
   f.Dependent(X, Y);
   ok &= (f.size_order() == 0);  // no implicit forward with this x

   // function values should agree now
   ok      &= FunCheck(f, g, x, a, r);

   return ok;
}
} // End empty namespace
# include <vector>
# include <valarray>
bool FunCheck(void)
{  bool ok = true;
   typedef CppAD::vector<double>                Vector1;
   typedef CppAD::vector< CppAD::AD<double> > ADVector1;
   typedef   std::vector<double>                Vector2;
   typedef   std::vector< CppAD::AD<double> > ADVector2;
   typedef std::valarray<double>                Vector3;
   typedef std::valarray< CppAD::AD<double> > ADVector3;
   // Run with Vector and ADVector equal to three different cases
   // all of which are Simple Vectors with elements of type
   // double and AD<double> respectively.
   ok &= FunCheckCases< Vector1, ADVector2 >();
   ok &= FunCheckCases< Vector2, ADVector3 >();
   ok &= FunCheckCases< Vector3, ADVector1 >();
   return ok;
}
// END C++