File: colpack_jac.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 (120 lines) | stat: -rw-r--r-- 3,047 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
// 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 colpack_jac.cpp}

ColPack: Sparse Jacobian Example and Test
#########################################

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

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

# include <cppad/cppad.hpp>
bool colpack_jac(void)
{  bool ok = true;
   using CppAD::AD;
   using CppAD::NearEqual;
   typedef CPPAD_TESTVECTOR(AD<double>)            a_vector;
   typedef CPPAD_TESTVECTOR(double)                d_vector;
   typedef CppAD::vector<size_t>                   i_vector;
   typedef CppAD::sparse_rc<i_vector>              sparsity;
   typedef CppAD::sparse_rcv<i_vector, d_vector>   sparse_matrix;

   // domain space vector
   size_t n = 4;
   a_vector  a_x(n);
   for(size_t j = 0; j < n; j++)
      a_x[j] = AD<double> (0);

   // declare independent variables and starting recording
   CppAD::Independent(a_x);

   size_t m = 3;
   a_vector  a_y(m);
   a_y[0] = a_x[0] + a_x[1];
   a_y[1] = a_x[2] + a_x[3];
   a_y[2] = a_x[0] + a_x[1] + a_x[2] + a_x[3] * a_x[3] / 2.;

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

   // new value for the independent variable vector
   d_vector x(n);
   for(size_t j = 0; j < n; j++)
      x[j] = double(j);

   /*
          [ 1 1 0 0  ]
   jac = [ 0 0 1 1  ]
          [ 1 1 1 x_3]
   */
   // Normally one would use CppAD to compute sparsity pattern, but for this
   // example we set it directly
   size_t nr  = m;
   size_t nc  = n;
   size_t nnz = 8;
   sparsity pattern(nr, nc, nnz);
   d_vector check(nnz);
   for(size_t k = 0; k < nnz; k++)
   {  size_t r, c;
      if( k < 2 )
      {  r = 0;
         c = k;
      }
      else if( k < 4 )
      {  r = 1;
         c = k;
      }
      else
      {  r = 2;
         c = k - 4;
      }
      pattern.set(k, r, c);
      if( k == nnz - 1 )
         check[k] = x[3];
      else
         check[k] = 1.0;
   }

   // using row and column indices to compute non-zero in rows 1 and 2
   sparse_matrix subset( pattern );

   // check results for both CppAD and Colpack
   for(size_t i_method = 0; i_method < 4; i_method++)
   {  // coloring method
      std::string coloring;
      if( i_method % 2 == 0 )
         coloring = "cppad";
      else
         coloring = "colpack";
      //
      CppAD::sparse_jac_work work;
      size_t group_max = 1;
      if( i_method / 2 == 0 )
      {  size_t n_sweep = f.sparse_jac_for(
            group_max, x, subset, pattern, coloring, work
         );
         ok &= n_sweep == 4;
      }
      else
      {  size_t n_sweep = f.sparse_jac_rev(
            x, subset, pattern, coloring, work
         );
         ok &= n_sweep == 2;
      }
      const d_vector& hes( subset.val() );
      for(size_t k = 0; k < nnz; k++)
         ok &= check[k] == hes[k];
   }
   return ok;
}
// END C++