@(@\newcommand{\W}[1]{ \; #1 \; }
\newcommand{\R}[1]{ {\rm #1} }
\newcommand{\B}[1]{ {\bf #1} }
\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }
\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }
\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} }
\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }@)@
This is cppad-20221105 documentation. Here is a link to its
current documentation
.
Atomic Functions Reverse Dependency Analysis: Example and Test
Purpose
This example demonstrates using atomic_three
function
in the definition of a function that is optimized.
Function
For this example, the atomic function
@(@
g : \B{R}^3 \rightarrow \B{R}^3
@)@ is defined by
@(@
g_0 (x) = x_0 * x_0
@)@,
@(@
g_1 (x) = x_0 * x_1
@)@,
@(@
g_2 (x) = x_1 * x_2
@)@.
# include <cppad/cppad.hpp> // CppAD include filenamespace { // start empty namespaceusing CppAD::vector; // abbreviate CppAD::vector using vector// start definition of atomic derived class using atomic_three interfaceclass atomic_optimize : public CppAD::atomic_three<double> {
public:
// can use const char* name when calling this constructoratomic_optimize(const std::string& name) : // can have more arguments
CppAD::atomic_three<double>(name) // inform base class of name
{ }
private:
// Create the function f(u) = g(c, p, u) for this example.//// constant parameter
double c_0 = 2.0;
//// indepndent dynamic parameter vector
size_t np = 1;
CPPAD_TESTVECTOR(double) p(np);
CPPAD_TESTVECTOR( AD<double> ) ap(np);
ap[0] = p[0] = 3.0;
//// independent variable vector
size_t nu = 1;
double u_0 = 0.5;
CPPAD_TESTVECTOR( AD<double> ) au(nu);
au[0] = u_0;
// declare independent variables and start tape recording
CppAD::Independent(au, ap);
// range space vector
size_t ny = 3;
CPPAD_TESTVECTOR( AD<double> ) ay(ny);
// call atomic function and store result in ay// y = ( c * c, c * p, p * u )CPPAD_TESTVECTOR( AD<double> ) ax(3);
ax[0] = c_0; // x_0 = c
ax[1] = ap[0]; // x_1 = p
ax[2] = au[0]; // x_2 = uafun(ax, ay);
// check type of result
ok &= Constant( ay[0] ); // c * c
ok &= Dynamic( ay[1] ); // c * p
ok &= Variable( ay[2] ); // p * u// create f: u -> y and stop tape recording
CppAD::ADFun<double> f;
f.Dependent (au, ay); // f(u) = (c * c, c * p, p * u)