File: sparse.cpp

package info (click to toggle)
cppad 2025.00.00.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,552 kB
  • sloc: cpp: 112,594; sh: 5,972; ansic: 179; python: 71; sed: 12; makefile: 10
file content (139 lines) | stat: -rw-r--r-- 3,825 bytes parent folder | download
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
// 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 json_sparse.cpp}

Json Representation of a Sparse Matrix: Example and Test
########################################################

Discussion
**********
The example using a CppAD Json to represent the sparse matrix

.. math::

   \partial_x f(x, p) = \left( \begin{array}{ccc}
      p_0 & 0    & 0 \\
      0   & p_1  & 0 \\
      0   & 0    & c_0
   \end{array} \right)

where :math:`c_0` is the constant 3.

Source Code
***********
{xrst_literal
   // BEGIN C++
   // END C++
}

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

bool sparse(void)
{  bool ok = true;
   using CppAD::vector;
   typedef vector<size_t> s_vector;
   typedef vector<double> d_vector;
   //
   // An AD graph example
   // node_1 : p[0]
   // node_2 : p[1]
   // node_3 : x[0]
   // node_4 : x[1]
   // node_5 : x[2]
   // node_6 : c[0]
   // node_7 : p[0] * x[0]
   // node_8 : p[1] * x[1]
   // node_9 : c[0] * x[2]
   // y[0]   = p[0] * x[0]
   // y[1]   = p[1] * x[1]
   // y[2]   = c[0] * x[0]
   // use single quote to avoid having to escape double quote
   std::string json =
      "{\n"
      "   'function_name'  : 'sparse example',\n"
      "   'op_define_vec'  : [ 1, [\n"
      "       { 'op_code':1, 'name':'mul', 'n_arg':2 } ]\n"
      "   ],\n"
      "   'n_dynamic_ind'  : 2,\n"
      "   'n_variable_ind' : 3,\n"
      "   'constant_vec'   : [ 1, [ 3.0 ] ],\n"
      "   'op_usage_vec'   : [ 3, [\n"
      "       [ 1, 1, 3 ] , \n"
      "       [ 1, 2, 4 ] , \n"
      "       [ 1, 6, 5 ] ] \n"
      "   ],\n"
      "   'dependent_vec'   : [ 3, [7, 8, 9] ] \n"
      "}\n";
   // Convert the single quote to double quote
   for(size_t i = 0; i < json.size(); ++i)
      if( json[i] == '\'' ) json[i] = '"';
   //
   CppAD::ADFun<double> fun;
   fun.from_json(json);
   ok &= fun.Domain() == 3;
   ok &= fun.Range()  == 3;
   ok &= fun.size_dyn_ind() == 2;
   //
   // Point at which we are going to evaluate the Jacobian of f(x, p).
   // The Jacobian is constant w.r.t. x, so the value of x does not matter.
   vector<double> p(2), x(3);
   p[0] = 1.0;
   p[1] = 2.0;
   for(size_t j = 0; j < x.size(); ++j)
      x[j] = 0.0;
   //
   // set the dynamic parameters
   fun.new_dynamic(p);
   //
   // compute the sparsity pattern for f_x(x, p)
   vector<bool> select_domain(3);
   vector<bool> select_range(3);
   for(size_t i = 0; i < 3; ++i)
   {  select_domain[i] = true;
      select_range[i]  = true;
   }
   bool transpose = false;
   CppAD::sparse_rc<s_vector> pattern;
   fun.subgraph_sparsity(select_domain, select_range, transpose, pattern);
   //
   // compute the entire Jacobian
   CppAD::sparse_rcv<s_vector, d_vector> subset(pattern);
   fun.subgraph_jac_rev(x, subset);
   //
   // information in the sparse Jacobian
   const s_vector& row( subset.row() );
   const s_vector& col( subset.col() );
   const d_vector& val( subset.val() );
   size_t   nnz       = subset.nnz();
   s_vector row_major = subset.row_major();
   //
   // check number of non-zero elements in sparse matrix
   ok      &= nnz == 3;
   //
   // check first element of matrix (in row major order)
   size_t k = row_major[0];
   ok      &= row[k] == 0;
   ok      &= col[k] == 0;
   ok      &= val[k] == p[0];
   //
   // check second element of matrix
   k        = row_major[1];
   ok      &= row[k] == 1;
   ok      &= col[k] == 1;
   ok      &= val[k] == p[1];
   //
   // check third element of matrix
   k        = row_major[2];
   ok      &= row[k] == 2;
   ok      &= col[k] == 2;
   ok      &= val[k] == 3.0;
   //
   return ok;
}
// END C++