setnonzeros_param_impl.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_SETNONZEROS_PARAM_IMPL_HPP
27 #define CASADI_SETNONZEROS_PARAM_IMPL_HPP
28 
29 #include "setnonzeros_param.hpp"
30 #include "casadi_misc.hpp"
31 #include "serializing_stream.hpp"
32 
34 
35 namespace casadi {
36 
37  template<bool Add>
38  MX SetNonzerosParam<Add>::create(const MX& y, const MX& x, const MX& nz) {
39  return MX::create(new SetNonzerosParamVector<Add>(y, x, nz));
40  }
41 
42  template<bool Add>
43  MX SetNonzerosParam<Add>::create(const MX& y, const MX& x, const Slice& inner, const MX& outer) {
44  casadi_assert(outer.is_vector() && outer.is_dense(), "outer must be dense vector");
45  return MX::create(new SetNonzerosSliceParam<Add>(y, x, inner, outer));
46  }
47 
48  template<bool Add>
49  MX SetNonzerosParam<Add>::create(const MX& y, const MX& x, const MX& inner, const Slice& outer) {
50  casadi_assert(inner.is_vector() && inner.is_dense(), "inner must be dense vector");
51  return MX::create(new SetNonzerosParamSlice<Add>(y, x, inner, outer));
52  }
53 
54  template<bool Add>
55  MX SetNonzerosParam<Add>::create(const MX& y, const MX& x, const MX& inner, const MX& outer) {
56  casadi_assert(inner.is_vector() && inner.is_dense(), "inner must be dense vector");
57  casadi_assert(outer.is_vector() && outer.is_dense(), "outer must be dense vector");
58  return MX::create(new SetNonzerosParamParam<Add>(y, x, inner, outer));
59  }
60 
61  template<bool Add>
62  SetNonzerosParam<Add>::SetNonzerosParam(const MX& y, const MX& x, const MX& nz) {
63  this->set_sparsity(y.sparsity());
64  this->set_dep(y, x, nz);
65  }
66 
67  template<bool Add>
68  SetNonzerosParam<Add>::SetNonzerosParam(const MX& y, const MX& x, const MX& nz, const MX& nz2) {
69  this->set_sparsity(y.sparsity());
70  this->set_dep({y, x, nz, nz2});
71  }
72 
73  template<bool Add>
75  const MX& nz) : SetNonzerosParam<Add>(y, x, nz) {
76  }
77 
78  template<bool Add>
80  }
81 
82  template<bool Add>
84  eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
85  // Add to the element to the sensitivity, if any
86  MX arg0 = project(arg[0], this->dep(0).sparsity());
87  MX arg1 = project(arg[1], this->dep(1).sparsity());
88  MX nz = arg[2];
89  if (Add) {
90  res[0] = arg1->get_nzadd(arg0, nz);
91  } else {
92  res[0] = arg1->get_nzassign(arg0, nz);
93  }
94  }
95 
96  template<bool Add>
98  eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
99  // Add to the element to the sensitivity, if any
100  MX arg0 = project(arg[0], this->dep(0).sparsity());
101  MX arg1 = project(arg[1], this->dep(1).sparsity());
102  MX inner = arg[2];
103  if (Add) {
104  res[0] = arg1->get_nzadd(arg0, inner, outer_);
105  } else {
106  res[0] = arg1->get_nzassign(arg0, inner, outer_);
107  }
108  }
109 
110  template<bool Add>
112  eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
113  // Add to the element to the sensitivity, if any
114  MX arg0 = project(arg[0], this->dep(0).sparsity());
115  MX arg1 = project(arg[1], this->dep(1).sparsity());
116  MX outer = arg[2];
117  if (Add) {
118  res[0] = arg1->get_nzadd(arg0, inner_, outer);
119  } else {
120  res[0] = arg1->get_nzassign(arg0, inner_, outer);
121  }
122  }
123 
124  template<bool Add>
126  eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
127  // Add to the element to the sensitivity, if any
128  MX arg0 = project(arg[0], this->dep(0).sparsity());
129  MX arg1 = project(arg[1], this->dep(1).sparsity());
130  MX inner = arg[2];
131  MX outer = arg[3];
132  if (Add) {
133  res[0] = arg1->get_nzadd(arg0, inner, outer);
134  } else {
135  res[0] = arg1->get_nzassign(arg0, inner, outer);
136  }
137  }
138 
139  template<bool Add>
140  void SetNonzerosParamVector<Add>::ad_forward(const std::vector<std::vector<MX> >& fseed,
141  std::vector<std::vector<MX> >& fsens) const {
142  const MX& nz = this->dep(2);
143  // Nondifferentiated function and forward sensitivities
144  for (casadi_int d=0; d<fsens.size(); ++d) {
145 
146  // Get references to arguments and results
147  MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
148  MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
149 
150  /*
151  dep(0) <-> y
152  dep(1) <-> x
153 
154  y[nz]+=x
155 
156  dot(y)[nz]+=dot(x)
157 
158  dot(x)->get_nzadd(dot(y), nz)
159 
160  */
161 
162  MX& res = fsens[d][0];
163  res = arg0;
164 
165  if (Add) {
166  res = arg1->get_nzadd(res, nz);
167  } else {
168  res = arg1->get_nzassign(res, nz);
169  }
170  }
171  }
172 
173  template<bool Add>
174  void SetNonzerosParamVector<Add>::ad_reverse(const std::vector<std::vector<MX> >& aseed,
175  std::vector<std::vector<MX> >& asens) const {
176  const MX& nz = this->dep(2);
177  for (casadi_int d=0; d<aseed.size(); ++d) {
178  MX seed = project(aseed[d][0], this->sparsity());
179 
180  /*
181  dep(0) <-> y
182  dep(1) <-> x
183 
184  z: y[nz]+=x
185 
186  bar(x) += bar(z)[nz]
187  bar(y) += bar(z)
188  */
189  asens[d][1] += seed->get_nz_ref(nz);
190  if (!Add) {
191  asens[d][0] += MX::zeros(this->dep(1).sparsity())->get_nzassign(seed, nz);
192  } else {
193  asens[d][0] += seed;
194  }
195  }
196  }
197 
198 
199  template<bool Add>
200  void SetNonzerosParamSlice<Add>::ad_forward(const std::vector<std::vector<MX> >& fseed,
201  std::vector<std::vector<MX> >& fsens) const {
202  const MX& inner = this->dep(2);
203  for (casadi_int d=0; d<fsens.size(); ++d) {
204  MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
205  MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
206 
207  MX& res = fsens[d][0];
208  res = arg0;
209 
210  if (Add) {
211  res = arg1->get_nzadd(res, inner, outer_);
212  } else {
213  res = arg1->get_nzassign(res, inner, outer_);
214  }
215  }
216  }
217 
218  template<bool Add>
219  void SetNonzerosParamSlice<Add>::ad_reverse(const std::vector<std::vector<MX> >& aseed,
220  std::vector<std::vector<MX> >& asens) const {
221  const MX& inner = this->dep(2);
222  for (casadi_int d=0; d<aseed.size(); ++d) {
223  MX seed = project(aseed[d][0], this->sparsity());
224  asens[d][1] += seed->get_nz_ref(inner, outer_);
225  if (!Add) {
226  asens[d][0] += MX::zeros(this->dep(1).sparsity())->get_nzassign(seed, inner, outer_);
227  } else {
228  asens[d][0] += seed;
229  }
230  }
231  }
232 
233  template<bool Add>
234  void SetNonzerosSliceParam<Add>::ad_forward(const std::vector<std::vector<MX> >& fseed,
235  std::vector<std::vector<MX> >& fsens) const {
236  const MX& outer = this->dep(2);
237  for (casadi_int d=0; d<fsens.size(); ++d) {
238  MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
239  MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
240 
241  MX& res = fsens[d][0];
242  res = arg0;
243 
244  if (Add) {
245  res = arg1->get_nzadd(res, inner_, outer);
246  } else {
247  res = arg1->get_nzassign(res, inner_, outer);
248  }
249  }
250  }
251 
252  template<bool Add>
253  void SetNonzerosSliceParam<Add>::ad_reverse(const std::vector<std::vector<MX> >& aseed,
254  std::vector<std::vector<MX> >& asens) const {
255  const MX& outer = this->dep(2);
256  for (casadi_int d=0; d<aseed.size(); ++d) {
257  MX seed = project(aseed[d][0], this->sparsity());
258  asens[d][1] += seed->get_nz_ref(inner_, outer);
259  if (!Add) {
260  asens[d][0] += MX::zeros(this->dep(1).sparsity())->get_nzassign(seed, inner_, outer);
261  } else {
262  asens[d][0] += seed;
263  }
264  }
265  }
266 
267  template<bool Add>
268  void SetNonzerosParamParam<Add>::ad_forward(const std::vector<std::vector<MX> >& fseed,
269  std::vector<std::vector<MX> >& fsens) const {
270  const MX& inner = this->dep(2);
271  const MX& outer = this->dep(3);
272  for (casadi_int d=0; d<fsens.size(); ++d) {
273  MX arg0 = project(fseed[d][0], this->dep(0).sparsity());
274  MX arg1 = project(fseed[d][1], this->dep(1).sparsity());
275 
276  MX& res = fsens[d][0];
277  res = arg0;
278 
279  if (Add) {
280  res = arg1->get_nzadd(res, inner, outer);
281  } else {
282  res = arg1->get_nzassign(res, inner, outer);
283  }
284  }
285  }
286 
287  template<bool Add>
288  void SetNonzerosParamParam<Add>::ad_reverse(const std::vector<std::vector<MX> >& aseed,
289  std::vector<std::vector<MX> >& asens) const {
290  const MX& inner = this->dep(2);
291  const MX& outer = this->dep(3);
292  for (casadi_int d=0; d<aseed.size(); ++d) {
293  MX seed = project(aseed[d][0], this->sparsity());
294  asens[d][1] += seed->get_nz_ref(inner, outer);
295  if (!Add) {
296  asens[d][0] += MX::zeros(this->dep(1).sparsity())->get_nzassign(seed, inner, outer);
297  } else {
298  asens[d][0] += seed;
299  }
300  }
301  }
302 
303  template<bool Add>
305  eval(const double** arg, double** res, casadi_int* iw, double* w) const {
306  const double* idata0 = arg[0];
307  const double* idata = arg[1];
308  const double* nz = arg[2];
309  double* odata = res[0];
310  // Dimensions
311  casadi_int nnz = this->dep(2).nnz();
312  casadi_int max_ind = this->dep(0).nnz();
313  if (idata0 != odata) {
314  std::copy(idata0, idata0+this->dep(0).nnz(), odata);
315  }
316  for (casadi_int k=0; k<nnz; ++k) {
317  // Get index
318  casadi_int index = static_cast<casadi_int>(*nz++);
319  if (Add) {
320  if (index>=0 && index<max_ind) odata[index] += *idata;
321  } else {
322  if (index>=0 && index<max_ind) odata[index] = *idata;
323  }
324  idata++;
325  }
326  return 0;
327  }
328 
329  template<bool Add>
331  eval(const double** arg, double** res, casadi_int* iw, double* w) const {
332  const double* idata0 = arg[0];
333  const double* idata = arg[1];
334  const double* nz = arg[2];
335  double* odata = res[0];
336  // Dimensions
337  casadi_int nnz = this->dep(2).nnz();
338  casadi_int max_ind = this->dep(0).nnz();
339  if (idata0 != odata) {
340  std::copy(idata0, idata0+this->dep(0).nnz(), odata);
341  }
342 
343  casadi_int* inner = iw; iw += nnz;
344  for (casadi_int i=0; i<nnz; ++i) {
345  // Get index
346  inner[i] = static_cast<casadi_int>(*nz++);
347  }
348  for (casadi_int i=outer_.start;i<outer_.stop;i+= outer_.step) {
349  // Get index
350  for (casadi_int* inner_it=inner; inner_it!=inner+nnz; ++inner_it) {
351  casadi_int index = i+*inner_it;
352  if (Add) {
353  if (index>=0 && index<max_ind) odata[index] += *idata;
354  } else {
355  if (index>=0 && index<max_ind) odata[index] = *idata;
356  }
357  idata++;
358  }
359  }
360  return 0;
361  }
362 
363  template<bool Add>
365  eval(const double** arg, double** res, casadi_int* iw, double* w) const {
366  const double* idata0 = arg[0];
367  const double* idata = arg[1];
368  const double* nz = arg[2];
369  double* odata = res[0];
370  // Dimensions
371  casadi_int nnz = this->dep(2).nnz();
372  casadi_int max_ind = this->dep(0).nnz();
373  if (idata0 != odata) {
374  std::copy(idata0, idata0+this->dep(0).nnz(), odata);
375  }
376  for (casadi_int k=0; k<nnz; ++k) {
377  // Get index
378  casadi_int ind = static_cast<casadi_int>(*nz++);
379  for (casadi_int j=0;j<inner_.stop;j+= inner_.step) {
380  casadi_int index = ind+j;
381  if (Add) {
382  if (index>=0 && index<max_ind) odata[index] += *idata;
383  } else {
384  if (index>=0 && index<max_ind) odata[index] = *idata;
385  }
386  idata++;
387  }
388  }
389  return 0;
390  }
391 
392  template<bool Add>
394  eval(const double** arg, double** res, casadi_int* iw, double* w) const {
395  const double* idata0 = arg[0];
396  const double* idata = arg[1];
397  const double* nz = arg[2];
398  const double* nz2 = arg[3];
399  double* odata = res[0];
400  // Dimensions
401  casadi_int nnz = this->dep(2).nnz();
402  casadi_int nnz2 = this->dep(3).nnz();
403  casadi_int max_ind = this->dep(0).nnz();
404  if (idata0 != odata) {
405  std::copy(idata0, idata0+this->dep(0).nnz(), odata);
406  }
407 
408  casadi_int* inner = iw; iw += nnz;
409  for (casadi_int i=0; i<nnz; ++i) {
410  // Get index
411  inner[i] = static_cast<casadi_int>(*nz++);
412  }
413 
414  for (casadi_int k=0; k<nnz2; ++k) {
415  // Get index
416  casadi_int ind = static_cast<casadi_int>(*nz2++);
417  for (casadi_int* inner_it=inner; inner_it!=inner+nnz; ++inner_it) {
418  casadi_int index = ind+*inner_it;
419  if (Add) {
420  if (index>=0 && index<max_ind) odata[index] += *idata;
421  } else {
422  if (index>=0 && index<max_ind) odata[index] = *idata;
423  }
424  idata++;
425  }
426  }
427  return 0;
428  }
429 
430  template<bool Add>
432  sz_iw() const {
433  return this->dep(2).nnz();
434  }
435 
436  template<bool Add>
438  sz_iw() const {
439  return this->dep(2).nnz();
440  }
441 
442 
443  template<bool Add>
445  sp_forward(const bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
446  // Parametric index -> any input disturbance propagates to any output
447  bvec_t arg0 = bvec_or(arg[0], this->dep(0).nnz());
448  bvec_t arg1 = bvec_or(arg[1], this->dep(1).nnz());
449 
450  bvec_t *r = res[0];
451  std::fill(r, r+this->nnz(), arg0 | arg1);
452  return 0;
453  }
454 
455  template<bool Add>
457  sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
458  bvec_t *arg0 = arg[0];
459  bvec_t *arg1 = arg[1];
460  bvec_t r = bvec_or(res[0], this->nnz());
461  std::fill(res[0], res[0]+this->nnz(), bvec_t(0));
462 
463  for (casadi_int i=0;i<this->dep(0).nnz();++i) {
464  *arg0++ |= r;
465  }
466  for (casadi_int i=0;i<this->dep(1).nnz();++i) {
467  *arg1++ |= r;
468  }
469  return 0;
470  }
471 
472  template<bool Add>
473  std::string SetNonzerosParamVector<Add>::disp(const std::vector<std::string>& arg) const {
474  std::stringstream ss;
475  ss << "(" << arg.at(0) << "[" << arg.at(2) << "]";
476  ss << (Add ? " += " : " = ") << arg.at(1) << ")";
477  return ss.str();
478  }
479 
480  template<bool Add>
481  std::string SetNonzerosParamSlice<Add>::disp(const std::vector<std::string>& arg) const {
482  std::stringstream ss;
483  ss << "(" << arg.at(0) << "[(" << arg.at(2) << ";" << outer_ << ")]";
484  ss << (Add ? " += " : " = ") << arg.at(1) << ")";
485  return ss.str();
486  }
487 
488  template<bool Add>
489  std::string SetNonzerosSliceParam<Add>::disp(const std::vector<std::string>& arg) const {
490  std::stringstream ss;
491  ss << "(" << arg.at(0) << "[(" << inner_ << ";" << arg.at(2) << ")]";
492  ss << (Add ? " += " : " = ") << arg.at(1) << ")";
493  return ss.str();
494  }
495 
496  template<bool Add>
497  std::string SetNonzerosParamParam<Add>::disp(const std::vector<std::string>& arg) const {
498  std::stringstream ss;
499  ss << "(" << arg.at(0) << "[(" << arg.at(2) << ";" << arg.at(3) << ")]";
500  ss << (Add ? " += " : " = ") << arg.at(1) << ")";
501  return ss.str();
502  }
503 
504  template<bool Add>
507  const std::vector<casadi_int>& arg,
508  const std::vector<casadi_int>& res,
509  const std::vector<bool>& arg_is_ref,
510  std::vector<bool>& res_is_ref) const {
511  // Copy first argument if not inplace
512  if (arg[0]!=res[0] || arg_is_ref[0]) {
513  g << g.copy(g.work(arg[0], this->dep(0).nnz(), arg_is_ref[0]), this->nnz(),
514  g.work(res[0], this->nnz(), false)) << '\n';
515  }
516  }
517 
518  template<bool Add>
521  const std::vector<casadi_int>& arg,
522  const std::vector<casadi_int>& res,
523  const std::vector<bool>& arg_is_ref,
524  std::vector<bool>& res_is_ref) const {
525  SetNonzerosParam<Add>::generate(g, arg, res, arg_is_ref, res_is_ref);
526 
527  casadi_int n = this->dep(1).nnz();
528 
529  std::string a1 = g.work(arg[1], n, arg_is_ref[1]);
530  std::string a2 = g.work(arg[2], n, arg_is_ref[2]);
531 
532  g.local("i", "casadi_int");
533  g.local("cr", "const casadi_real", "*");
534  g.local("cs", "const casadi_real", "*");
535  g << "for (cs=" << a1 << ", cr=" << a2
536  << "; cs!=" << a1 << "+" << n
537  << "; ++cs) { i=(int) *cr++; if (i>=0 && i<" << this->dep(0).nnz() << ") "
538  << g.work(res[0], this->nnz(), false) << "[i] " << (Add?"+= ":"= ")
539  << "*cs; }\n";
540  }
541 
542  template<bool Add>
545  const std::vector<casadi_int>& arg,
546  const std::vector<casadi_int>& res,
547  const std::vector<bool>& arg_is_ref,
548  std::vector<bool>& res_is_ref) const {
549  SetNonzerosParam<Add>::generate(g, arg, res, arg_is_ref, res_is_ref);
550 
551  casadi_int n = this->dep(1).nnz();
552  casadi_int n_inner = this->dep(2).nnz();
553 
554  g.local("cii", "const casadi_int", "*");
555  g.local("i", "casadi_int");
556  g << "for (i=0;i<" << n_inner << ";++i) iw[i] = (int) "
557  << g.work(arg[2], n_inner, arg_is_ref[2]) << "[i];\n";
558 
559  g.local("cs", "const casadi_real", "*");
560  g.local("k", "casadi_int");
561  g << "for (cs=" << g.work(arg[1], n, arg_is_ref[1])
562  << ", k=" << outer_.start << ";k<" << outer_.stop << ";k+=" << outer_.step << ") ";
563  g << "for (cii=iw; cii!=iw" << "+" << n_inner << "; ++cii) { i=k+*cii; "
564  << "if (i>=0 && i<" << this->dep(0).nnz() << ") "
565  << g.work(res[0], this->nnz(), false) << "[i] " << (Add?"+= ":"= ")
566  << "*cs; cs++; }\n";
567  }
568 
569  template<bool Add>
572  const std::vector<casadi_int>& arg,
573  const std::vector<casadi_int>& res,
574  const std::vector<bool>& arg_is_ref,
575  std::vector<bool>& res_is_ref) const {
576  SetNonzerosParam<Add>::generate(g, arg, res, arg_is_ref, res_is_ref);
577 
578  casadi_int n = this->dep(1).nnz();
579  casadi_int n_outer = this->dep(2).nnz();
580 
581  g.local("i", "casadi_int");
582  g.local("j", "casadi_int");
583  g.local("k", "casadi_int");
584  g.local("cr", "const casadi_real", "*");
585  g.local("cs", "const casadi_real", "*");
586  g << "for (cr=" << g.work(arg[2], n_outer, arg_is_ref[2])
587  << ", cs=" << g.work(arg[1], n, arg_is_ref[1])
588  << "; cr!=" << g.work(arg[2], n_outer, arg_is_ref[2]) << "+" << n_outer
589  << "; ++cr) ";
590  g << "for (j=(int) *cr, "
591  << "k=" << inner_.start << ";k<" << inner_.stop << ";k+=" << inner_.step << ") ";
592  g << "{ i=k+j; "
593  << "if (i>=0 && i<" << this->dep(0).nnz() << ") "
594  << g.work(res[0], this->nnz(), false) << "[i] " << (Add?"+= ":"= ")
595  << "*cs; cs++; }\n";
596  }
597 
598  template<bool Add>
601  const std::vector<casadi_int>& arg,
602  const std::vector<casadi_int>& res,
603  const std::vector<bool>& arg_is_ref,
604  std::vector<bool>& res_is_ref) const {
605  SetNonzerosParam<Add>::generate(g, arg, res, arg_is_ref, res_is_ref);
606  casadi_int n = this->dep(1).nnz();
607  casadi_int n_outer = this->dep(3).nnz();
608  casadi_int n_inner = this->dep(2).nnz();
609 
610  g.local("cii", "const casadi_int", "*");
611  g.local("i", "casadi_int");
612  g << "for (i=0;i<" << n_inner << ";++i) iw[i] = (int) "
613  << g.work(arg[2], n_inner, arg_is_ref[2]) << "[i];\n";
614 
615  g.local("j", "casadi_int");
616  g.local("cr", "const casadi_real", "*");
617  g.local("cs", "const casadi_real", "*");
618  g << "for (cr=" << g.work(arg[3], n_outer, arg_is_ref[3])
619  << ", cs=" << g.work(arg[1], n, arg_is_ref[1])
620  << "; cr!=" << g.work(arg[3], n_outer, arg_is_ref[3]) << "+" << n_outer
621  << "; ++cr) ";
622  g << "for (j=(int) *cr, cii=iw; cii!=iw" << "+" << n_inner << "; ++cii) { i=j+*cii; "
623  << "if (i>=0 && i<" << this->dep(0).nnz() << ") "
624  << g.work(res[0], this->nnz(), false) << "[i] " << (Add?"+= ":"= ")
625  << "*cs; cs++; }\n";
626  }
627 
628  template<bool Add>
631  }
632 
633  template<bool Add>
635  SetNonzerosParam<Add>(s) {
636  }
637 
638  template<bool Add>
641  s.pack("SetNonzerosParam::type", 'a');
642  }
643 
644  template<bool Add>
647  s.pack("SetNonzerosParamSlice::outer", outer_);
648  }
649 
650  template<bool Add>
652  SetNonzerosParam<Add>(s) {
653  s.unpack("SetNonzerosParamSlice::outer", outer_);
654  }
655 
656  template<bool Add>
659  s.pack("SetNonzerosParam::type", 'b');
660  }
661 
662  template<bool Add>
665  s.pack("SetNonzerosSliceParam::inner", inner_);
666  }
667 
668  template<bool Add>
670  SetNonzerosParam<Add>(s) {
671  s.unpack("SetNonzerosSliceParam::inner", inner_);
672  }
673 
674  template<bool Add>
677  s.pack("SetNonzerosParam::type", 'c');
678  }
679 
680 
681  template<bool Add>
684  s.pack("SetNonzerosParam::type", 'd');
685  }
686 
687  template<bool Add>
689  SetNonzerosParam<Add>(s) {
690  }
691 
692  template<bool Add>
694  char t;
695  s.unpack("SetNonzerosParam::type", t);
696  switch (t) {
697  case 'a': return new SetNonzerosParamVector<Add>(s);
698  case 'b': return new SetNonzerosParamSlice<Add>(s);
699  case 'c': return new SetNonzerosSliceParam<Add>(s);
700  case 'd': return new SetNonzerosParamParam<Add>(s);
701  default: casadi_assert_dev(false);
702  }
703  }
704 
705 } // namespace casadi
706 
708 
709 #endif // CASADI_SETNONZEROS_PARAM_IMPL_HPP
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string copy(const std::string &arg, std::size_t n, const std::string &res)
Create a copy operation.
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
bool is_dense() const
Check if the matrix expression is dense.
bool is_vector() const
Check if the matrix is a row or column vector.
static MX zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
Node class for MX objects.
Definition: mx_node.hpp:51
virtual void serialize_type(SerializingStream &s) const
Serialize type information.
Definition: mx_node.cpp:528
virtual MX get_nzassign(const MX &y, const std::vector< casadi_int > &nz) const
Assign the nonzeros of a matrix to another matrix.
Definition: mx_node.cpp:688
virtual MX get_nz_ref(const MX &nz) const
Get the nonzeros of matrix, parametrically.
Definition: mx_node.cpp:664
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.
Definition: mx_node.cpp:523
virtual MX get_nzadd(const MX &y, const std::vector< casadi_int > &nz) const
Add the nonzeros of a matrix to another matrix.
Definition: mx_node.cpp:700
MX - Matrix expression.
Definition: mx.hpp:92
static MX create(MXNode *node)
Create from node.
Definition: mx.cpp:67
const Sparsity & sparsity() const
Get the sparsity pattern.
Definition: mx.cpp:592
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
SetNonzerosParamParam(const MX &y, const MX &x, const MX &inner, const MX &outer)
Constructor.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
size_t sz_iw() const override
Get required length of iw field.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
void serialize_type(SerializingStream &s) const override
Serialize type information.
SetNonzerosParamSlice(const MX &y, const MX &x, const MX &inner, const Slice &outer)
Constructor.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void serialize_type(SerializingStream &s) const override
Serialize type information.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
size_t sz_iw() const override
Get required length of iw field.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
Add the nonzeros of a matrix to another matrix, parametrically.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void serialize_type(SerializingStream &s) const override
Serialize type information.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
SetNonzerosParamVector(const MX &y, const MX &x, const MX &nz)
Constructor.
Assign or add entries to a matrix, parametrically.
static MXNode * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
SetNonzerosParam(const MX &y, const MX &x, const MX &nz)
Constructor.
~SetNonzerosParam() override=0
Destructor.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
static MX create(const MX &y, const MX &x, const MX &nz)
Create functions.
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
void serialize_type(SerializingStream &s) const override
Serialize type information.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
SetNonzerosSliceParam(const MX &y, const MX &x, const Slice &inner, const MX &outer)
Constructor.
Class representing a Slice.
Definition: slice.hpp:48
The casadi namespace.
Definition: archiver.cpp:28
unsigned long long bvec_t
bvec_t bvec_or(const bvec_t *arg, casadi_int n)
Bit-wise or operation on bvec_t array.