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++
|