File: dependency.cpp

package info (click to toggle)
cppad 2026.00.00.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,584 kB
  • sloc: cpp: 112,960; sh: 6,146; ansic: 179; python: 71; sed: 12; makefile: 10
file content (136 lines) | stat: -rw-r--r-- 4,137 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
// 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
// ----------------------------------------------------------------------------

/*
Old example for deprecated interface.
$spell
   CppAD
   Jac
$$

$section Computing Dependency: Example and Test$$

$head Discussion$$
The partial of an dependent variable with respect to an independent variable
might always be zero even though the dependent variable depends on the
value of the dependent variable. Consider the following case
$latex \[
f(x) = {\rm sign} (x) =
\left\{ \begin{array}{rl}
   +1 & {\rm if} \; x > 0 \\
   0  & {\rm if} \; x = 0 \\
   -1 & {\rm if} \; x < 0
\end{array} \right.
\] $$
In this case the value of $latex f(x)$$ depends on the value of $latex x$$
but CppAD always returns zero for the derivative of the $cref sign$$ function.

$head Dependency Pattern$$
If the $th i$$ dependent variables depends on the
value of the $th j$$ independent variable,
the corresponding entry in the dependency pattern is non-zero (true).
Otherwise it is zero (false).
CppAD uses $cref/sparsity patterns/glossary/Sparsity Pattern/$$
to represent dependency matrices.
The $icode dependency$$ argument to
$cref/ForSparseJac/ForSparseJac/dependency/$$ and
$cref/RevSparseJac/RevSparseJac/dependency/$$ is a flag that signals
that the dependency pattern (instead of the sparsity pattern) is computed.

$srcthisfile%0%// BEGIN C++%// END C++%1%$$

$end
*/
// BEGIN C++
# include <cppad/cppad.hpp>
namespace {
   double heavyside(const double& x)
   {  if( x <= 0.0 )
         return 0.0;
      return 1.0;
   }
   CPPAD_DISCRETE_FUNCTION(double, heavyside)
}

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

   // VecAD object for use later
   CppAD::VecAD<double> vec_ad(2);
   vec_ad[0] = 0.0;
   vec_ad[1] = 1.0;

   // domain space vector
   size_t n  = 5;
   CPPAD_TESTVECTOR(AD<double>) ax(n);
   for(size_t j = 0; j < n; j++)
      ax[j] = AD<double>(j + 1);

   // declare independent variables and start tape recording
   CppAD::Independent(ax);

   // some AD constants
   AD<double> azero(0.0), aone(1.0);

   // range space vector
   size_t m  = n;
   size_t m1 = n - 1;
   CPPAD_TESTVECTOR(AD<double>) ay(m);
   ay[m1-0] = sign( ax[0] );
   ay[m1-1] = CondExpLe( ax[1], azero, azero, aone);
   ay[m1-2] = CondExpLe( azero, ax[2], azero, aone);
   ay[m1-3] = heavyside( ax[3] );
   ay[m1-4] = vec_ad[ ax[4] - AD<double>(4.0) ];

   // create f: x -> y and stop tape recording
   CppAD::ADFun<double> f(ax, ay);

   // -----------------------------------------------------------
   // ForSparseJac and bool dependency
   bool transpose  = false;
   bool dependency;
   // could replace CppAD::vectorBooll by CPPAD_TESTVECTOR<bool>
   CppAD::vectorBool eye_bool(n * n), depend_bool(m * n);
   for(size_t i = 0; i < n; i++)
   {  for(size_t j = 0; j < n; j++)
         eye_bool[i * n + j] = (i == j);
   }
   dependency = true;
   depend_bool = f.ForSparseJac(n, eye_bool, transpose, dependency);
   for(size_t i = 0; i < m; i++)
   {  for(size_t j = 0; j < n; j++)
         ok &= depend_bool[i * n + j] == (i == (m1-j));
   }
   dependency = false;
   depend_bool = f.ForSparseJac(n, eye_bool, transpose, dependency);
   for(size_t i = 0; i < m; i++)
   {  for(size_t j = 0; j < n; j++)
         ok &= depend_bool[i * n + j] == false;
   }

   // -----------------------------------------------------------
   // RevSparseJac and set dependency
   CppAD::vector<    std::set<size_t> > eye_set(m), depend_set(m);
   for(size_t i = 0; i < m; i++)
   {  ok &= eye_set[i].empty();
      eye_set[i].insert(i);
   }
   dependency = true;
   depend_set = f.RevSparseJac(n, eye_set, transpose, dependency);
   for(size_t i = 0; i < m; i++)
   {  std::set<size_t> check;
      check.insert(m1 - i);
      ok &= depend_set[i] == check;
   }
   dependency = false;
   depend_set = f.RevSparseJac(n, eye_set, transpose, dependency);
   for(size_t i = 0; i < m; i++)
      ok &= depend_set[i].empty();
   return ok;
}

// END C++