casadi_jac.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 
21 // SYMBOL "jac_prob"
22 template<typename T1>
24  // Number of outputs, i.e. rows of the Jacobian
25  casadi_int n_out;
26  // Number of inputs, i.e. columns of the Jacobian
27  casadi_int n_in;
28  // Number of colors
29  casadi_int n_color;
30  // Extended Jacobian sparsity
31  const casadi_int* sp_ext;
32  // Jacobian coloring
33  const casadi_int* coloring;
34  // Nominal values for inputs, if any
35  const T1* nom_in;
36  // Index mapping for outputs (i.e. Jacobian rows), if any
37  const size_t* map_out;
38  // Index mapping for inputs (i.e. Jacobian columns), if any
39  const size_t* map_in;
40 };
41 // C-REPLACE "casadi_jac_prob<T1>" "struct casadi_jac_prob"
42 
43 // SYMBOL "jac_setup"
44 template<typename T1>
45 void casadi_jac_setup(casadi_jac_prob<T1>* p, const casadi_int* sp_ext,
46  const casadi_int* coloring) {
47  // Set pointers
48  p->sp_ext = sp_ext;
49  p->coloring = coloring;
50  // Dimensions are given by the sparsity patterns
51  p->n_out = sp_ext[0];
52  p->n_in = sp_ext[1];
53  p->n_color = coloring[1];
54  // The following defaults to null
55  p->nom_in = 0;
56  p->map_out = 0;
57  p->map_in = 0;
58 }
59 
60 // SYMBOL "jac_work"
61 template<typename T1>
62 void casadi_jac_work(const casadi_jac_prob<T1>* p, casadi_int* sz_iw, casadi_int* sz_w) {
63  // Reset sz_w, sz_iw
64  *sz_w = *sz_iw = 0;
65  // Work vectors in data struct
66  *sz_iw += p->n_in; // iseed
67  *sz_w += p->n_in; // seed
68  *sz_iw += p->n_out; // isens
69  *sz_w += p->n_out; // sens
70  *sz_w += p->n_out; // scal
71  *sz_iw += p->n_out; // wrt
72  *sz_iw += p->n_out; // nzind
73 }
74 
75 // SYMBOL "jac_data"
76 template<typename T1>
78  // Number of seeds, sensitivities for the current color
79  casadi_int nseed, nsens;
80  // Inputs that are being seeded
81  casadi_int *iseed;
82  // Set of seeds for the seeded inputs
83  T1 *seed;
84  // Set of outputs for which sensitivities are calculated
85  casadi_int *isens;
86  // Set of values for the calculated sensitivities
87  T1 *sens;
88  // Scaling factors for calculated sensitivities
89  T1 *scal;
90  // Input corresponding to calculated sensitivities
91  casadi_int *wrt;
92  // Jacobian nonzero corresponding to calculated sensitivities
93  casadi_int *nzind;
94 };
95 // C-REPLACE "casadi_jac_data<T1>" "struct casadi_jac_data"
96 
97 // SYMBOL "jac_init"
98 template<typename T1>
99 void casadi_jac_init(const casadi_jac_prob<T1>* p, casadi_jac_data<T1>* d,
100  casadi_int** iw, T1** w) {
101  // Set work vectors
102  d->iseed = *iw; *iw += p->n_in;
103  d->seed = *w; *w += p->n_in;
104  d->isens = *iw; *iw += p->n_out;
105  d->sens = *w; *w += p->n_out;
106  d->scal = *w; *w += p->n_out;
107  d->wrt = *iw; *iw += p->n_out;
108  d->nzind = *iw; *iw += p->n_out;
109 }
110 
111 // SYMBOL "jac_pre"
112 template<typename T1>
113 void casadi_jac_pre(const casadi_jac_prob<T1>* p, casadi_jac_data<T1>* d, casadi_int c) {
114  // Local variables
115  casadi_int i, kc, vin, vout, Jk;
116  double nom, inv_nom;
117  const casadi_int *color_colind, *color_row, *jac_colind, *jac_row;
118  // Extract sparsities
119  color_colind = p->coloring + 2;
120  color_row = color_colind + p->n_color + 1;
121  jac_colind = p->sp_ext + 2;
122  jac_row = jac_colind + p->n_in + 1;
123  // Loop over input indices for color
124  d->nseed = d->nsens = 0;
125  for (kc = color_colind[c]; kc < color_colind[c + 1]; ++kc) {
126  vin = color_row[kc];
127  // Nominal value, used as a seed for the column
128  nom = p->nom_in ? p->nom_in[vin] : 1;
129  inv_nom = 1. / nom;
130  // Collect seeds for column
131  d->seed[d->nseed] = nom;
132  d->iseed[d->nseed] = vin;
133  d->nseed++;
134  // Request corresponding outputs
135  for (Jk = jac_colind[vin]; Jk < jac_colind[vin + 1]; ++Jk) {
136  vout = jac_row[Jk];
137  d->scal[d->nsens] = inv_nom;
138  d->isens[d->nsens] = vout;
139  d->wrt[d->nsens] = vin;
140  d->nzind[d->nsens] = Jk;
141  d->nsens++;
142  }
143  }
144  // Map indices
145  if (p->map_in) {
146  for (i = 0; i < d->nseed; ++i) d->iseed[i] = p->map_in[d->iseed[i]];
147  for (i = 0; i < d->nsens; ++i) d->wrt[i] = p->map_in[d->wrt[i]];
148  }
149  if (p->map_out) {
150  for (i = 0; i < d->nsens; ++i) d->isens[i] = p->map_out[d->isens[i]];
151  }
152 }
153 
154 // SYMBOL "jac_scale"
155 template<typename T1>
156 void casadi_jac_scale(const casadi_jac_prob<T1>* p, casadi_jac_data<T1>* d) {
157  // Local variables
158  casadi_int i;
159  // Scale derivatives
160  for (i = 0; i < d->nsens; ++i) d->sens[i] *= d->scal[i];
161 }
162 
163 // SYMBOL "get_sub"
164 template<typename T1>
165 void casadi_get_sub(T1* sub, const casadi_int* sp_a, const T1* nz_a,
166  casadi_int rbegin, casadi_int rend, casadi_int cbegin, casadi_int cend) {
167  // Local variables
168  casadi_int nc, r, c, k;
169  const casadi_int *colind, *row;
170  // Quick return if null
171  if (sub == 0) return;
172  // Extract sparsity
173  nc = sp_a[1];
174  colind = sp_a + 2;
175  row = colind + nc + 1;
176  // Loop over columns
177  for (c = cbegin; c < cend; ++c) {
178  // Loop over nonzeros
179  for (k = colind[c]; k < colind[c + 1]; ++k) {
180  // Get row
181  r = row[k];
182  // Save, if in range
183  if (r >= rbegin && r < rend) *sub++ = nz_a[k];
184  }
185  }
186 }
casadi_int nseed
Definition: casadi_jac.hpp:79
casadi_int * nzind
Definition: casadi_jac.hpp:93
casadi_int * isens
Definition: casadi_jac.hpp:85
casadi_int * iseed
Definition: casadi_jac.hpp:81
casadi_int * wrt
Definition: casadi_jac.hpp:91
casadi_int nsens
Definition: casadi_jac.hpp:79
casadi_int n_out
Definition: casadi_jac.hpp:25
const size_t * map_in
Definition: casadi_jac.hpp:39
casadi_int n_in
Definition: casadi_jac.hpp:27
const T1 * nom_in
Definition: casadi_jac.hpp:35
casadi_int n_color
Definition: casadi_jac.hpp:29
const casadi_int * coloring
Definition: casadi_jac.hpp:33
const size_t * map_out
Definition: casadi_jac.hpp:37
const casadi_int * sp_ext
Definition: casadi_jac.hpp:31