File: fun_property.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 (155 lines) | stat: -rw-r--r-- 5,081 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// 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
// ----------------------------------------------------------------------------

/*
{xrst_begin fun_property.cpp}

ADFun Function Properties: Example and Test
###########################################

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

{xrst_end fun_property.cpp}
*/
// BEGIN C++

# include <cppad/cppad.hpp>

// Note that CPPAD_VEC_ENUM_TYPE is not part of CppAD API and may change
# define CPPAD_VEC_ENUM_TYPE unsigned char

bool fun_property(void)
{  bool ok = true;
   using CppAD::AD;

   // Use nvar to track the number of variables in the operation sequence.
   // Start with one for the phantom variable at tape address zero.
   size_t nvar = 1;

   // Use npar to track the number of parameters in the operation sequence.
   // Start with one for the phantom parameter at index zero.
   size_t npar = 1;

   // Use ndyn to track the number of dynamic parameters.
   size_t ndyn = 0;

   // Use ndyn to track number of arguments to dynamic parameter operators.
   size_t ndyn_arg = 0;

   // Start with one for operator corresponding to phantom variable
   size_t nop  = 1;

   // Start with one for operator corresponding to phantom argument
   size_t narg = 1;

   // Use ntext to track the number of characters used to label
   // output generated using PrintFor commands.
   size_t ntext = 0;

   // Use nvecad to track the number of VecAD vectors, plus the number
   // of VecAD vector elements, in the operation sequence.
   size_t nvecad = 0;

   // a VecAD vector
   CppAD::VecAD<double> v(2);
   v[0]     = 0; // requires the parameter 0, when becomes a variable
   v[1]     = 1; // requires the parameter 1, when becomes a variable

   // domain space vector
   size_t n = 2;
   CPPAD_TESTVECTOR(AD<double>) x(n);
   x[0]     = 0.;
   x[1]     = 1.;

   // dynamic parameter vector
   CPPAD_TESTVECTOR(AD<double>) dynamic(1);
   dynamic[0] = 1.;


   // declare independent variables and start tape recording
   size_t abort_op_index = 0;
   bool   record_compare = true;
   CppAD::Independent(x, abort_op_index, record_compare, dynamic);
   nvar    += n;
   nop     += n;
   ndyn    += dynamic.size();
   npar    += ndyn;

   // a computation that adds to the operation sequence
   AD<double> I = 0;
   v[I]         = x[0];
   nvecad      +=   3;  // one for vector, two for its elements
   npar        +=   2;  // need parameters 0 and 1 for initial v
   nop         +=   1;  // operator for storing in a VecAD object
   narg        +=   3;  // the three arguments are v, I, and x[0]

   // some operations that do not add to the operation sequence
   AD<double> u = x[0];  // use same variable as x[0]
   AD<double> w = x[1];  // use same variable as x[1]

   // a computation that adds to the operation sequence
   w      = w * (u + w);
   nop   += 2;   // requires two new operators, an add and a multiply
   nvar  += 2;   // each operator results in its own variable
   narg  += 4;   // each operator has two arguments

   // range space vector
   size_t m = 3;
   CPPAD_TESTVECTOR(AD<double>) y(m);

   // operations that do not add to the operation sequence
   y[0]   = 1.;  // re-use the parameter 1
   y[1]   = u;   // use same variable as u

   // a computation that adds to the operation sequence
   y[2]   = w + 2.;
   nop   += 1;   // requires a new add operator
   npar  += 1;   // new parameter 2 is new, so it must be included
   nvar  += 1;   // variable corresponding to the result
   narg  += 2;   // operator has two arguments

   // create f: x -> y and stop tape recording
   CppAD::ADFun<double> f(x, y);
   nop   += 1;   // special operator for y[0] because it is a parameter
   nvar  += 1;   // special variable for y[0] because it is a parameter
   narg  += 1;   // identifies which parameter corresponds to y[0]
   nop   += 1;   // special operator at the end of operation sequence

   // check the sequence property functions
   ok &= f.Domain()        == n;
   ok &= f.Range()         == m;
   ok &= f.Parameter(0)    == true;
   ok &= f.Parameter(1)    == false;
   ok &= f.Parameter(2)    == false;
   ok &= f.size_var()      == nvar;
   ok &= f.size_op()       == nop;
   ok &= f.size_op_arg()   == narg;
   ok &= f.size_par()      == npar;
   ok &= f.size_text()     == ntext;
   ok &= f.size_VecAD()    == nvecad;
   ok &= f.size_dyn_ind()  == ndyn;
   ok &= f.size_dyn_par()  == ndyn;
   ok &= f.size_dyn_arg()  == ndyn_arg;

   //
   size_t sum = 0;
   sum += nop        * sizeof(CPPAD_VEC_ENUM_TYPE);
   sum += narg       * sizeof(CPPAD_TAPE_ADDR_TYPE);
   sum += npar       * sizeof(double);
   sum += npar       * sizeof(bool);
   sum += ndyn       * sizeof(CPPAD_VEC_ENUM_TYPE);
   sum += ndyn       * sizeof(CPPAD_TAPE_ADDR_TYPE);
   sum += ndyn_arg   * sizeof(CPPAD_TAPE_ADDR_TYPE);
   sum += ntext      * sizeof(char);
   sum += nvecad     * sizeof(CPPAD_TAPE_ADDR_TYPE);
   ok &= f.size_op_seq() == sum;

   return ok;
}

// END C++