concat.cpp
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 #include "concat.hpp"
27 #include "casadi_misc.hpp"
28 
29 namespace casadi {
30 
31  Concat::Concat(const std::vector<MX>& x) {
32  set_dep(x);
33  }
34 
36  }
37 
38  int Concat::eval(const double** arg, double** res, casadi_int* iw, double* w) const {
39  return eval_gen<double>(arg, res, iw, w);
40  }
41 
42  int Concat::eval_sx(const SXElem** arg, SXElem** res, casadi_int* iw, SXElem* w) const {
43  return eval_gen<SXElem>(arg, res, iw, w);
44  }
45 
46  template<typename T>
47  int Concat::eval_gen(const T* const* arg, T* const* res, casadi_int* iw, T* w) const {
48  T* r = res[0];
49  for (casadi_int i=0; i<n_dep(); ++i) {
50  casadi_int n = dep(i).nnz();
51  std::copy(arg[i], arg[i]+n, r);
52  r += n;
53  }
54  return 0;
55  }
56 
57  int Concat::sp_forward(const bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
58  bvec_t *res_ptr = res[0];
59  for (casadi_int i=0; i<n_dep(); ++i) {
60  casadi_int n_i = dep(i).nnz();
61  const bvec_t *arg_i_ptr = arg[i];
62  std::copy(arg_i_ptr, arg_i_ptr+n_i, res_ptr);
63  res_ptr += n_i;
64  }
65  return 0;
66  }
67 
68  int Concat::sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
69  bvec_t *res_ptr = res[0];
70  for (casadi_int i=0; i<n_dep(); ++i) {
71  casadi_int n_i = dep(i).nnz();
72  bvec_t *arg_i_ptr = arg[i];
73  for (casadi_int k=0; k<n_i; ++k) {
74  *arg_i_ptr++ |= *res_ptr;
75  *res_ptr++ = 0;
76  }
77  }
78  return 0;
79  }
80 
82  const std::vector<casadi_int>& arg,
83  const std::vector<casadi_int>& res,
84  const std::vector<bool>& arg_is_ref,
85  std::vector<bool>& res_is_ref) const {
86  g.local("rr", "casadi_real", "*");
87  g << "rr=" << g.work(res[0], nnz(), false) << ";\n";
88  for (casadi_int i=0; i<arg.size(); ++i) {
89  casadi_int nz = dep(i).nnz();
90  if (nz==1) {
91  g << "*rr++ = " << g.workel(arg[i]) << ";\n";
92  } else if (nz!=0) {
93  g.local("i", "casadi_int");
94  g.local("cs", "const casadi_real", "*");
95  g << "for (i=0, " << "cs=" << g.work(arg[i], nz, arg_is_ref[i]) << "; "
96  << "i<" << nz << "; ++i) *rr++ = *cs++;\n";
97  }
98  }
99  }
100 
101  MX Concat::get_nzref(const Sparsity& sp, const std::vector<casadi_int>& nz,
102  bool unique) const {
103  // Get the first nonnegative nz
104  casadi_int nz_test = -1;
105  for (auto&& i : nz) {
106  if (i>=0) {
107  nz_test = i;
108  break;
109  }
110  }
111 
112  // Quick return if none
113  if (nz_test<0) return MX::zeros(sp);
114 
115  // Find out to which dependency it might depend
116  casadi_int begin=0, end=0;
117  casadi_int i;
118  for (i=0; i<n_dep(); ++i) {
119  begin = end;
120  end += dep(i).nnz();
121  if (nz_test < end) break;
122  }
123 
124  // Check if any nz refer to a different nonzero
125  for (auto&& j : nz) {
126  if (j>=0 && (j < begin || j >= end)) {
127 
128  // Fallback to the base class
129  return MXNode::get_nzref(sp, nz);
130  }
131  }
132 
133  // All nz refer to the same dependency, update the nonzero indices
134  if (begin==0) {
135  return dep(i)->get_nzref(sp, nz);
136  } else {
137  std::vector<casadi_int> nz_new(nz);
138  for (auto&& j : nz_new) if (j>=0) j -= begin;
139  return dep(i)->get_nzref(sp, nz_new);
140  }
141  }
142 
143 
144  Diagcat::Diagcat(const std::vector<MX>& x) : Concat(x) {
145  casadi_assert_dev(x.size()>1);
146  std::vector<Sparsity> sp(x.size());
147  for (casadi_int i=0; i<x.size(); ++i) sp[i] = x[i].sparsity();
148  set_sparsity(diagcat(sp));
149  }
150 
151  std::string Diagcat::disp(const std::vector<std::string>& arg) const {
152  std::stringstream ss;
153  ss << "diagcat(" << arg.at(0);
154  for (casadi_int i=1; i<n_dep(); ++i) ss << ", " << arg.at(i);
155  ss << ")";
156  return ss.str();
157  }
158 
159  void Diagcat::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res,
160  const std::vector<bool>& unique) const {
161  res[0] = diagcat(arg);
162  }
163 
164  void Diagcat::ad_forward(const std::vector<std::vector<MX> >& fseed,
165  std::vector<std::vector<MX> >& fsens) const {
166  casadi_int nfwd = fsens.size();
167  for (casadi_int d = 0; d<nfwd; ++d) fsens[d][0] = diagcat(fseed[d]);
168  }
169 
170  std::pair<std::vector<casadi_int>, std::vector<casadi_int> > Diagcat::off() const {
171  std::vector<casadi_int> offset1(n_dep()+1, 0);
172  std::vector<casadi_int> offset2(n_dep()+1, 0);
173  for (casadi_int i=0; i<n_dep(); ++i) {
174  casadi_int ncol = dep(i).sparsity().size2();
175  casadi_int nrow = dep(i).sparsity().size1();
176  offset2[i+1] = offset2[i] + ncol;
177  offset1[i+1] = offset1[i] + nrow;
178  }
179  return std::make_pair(offset1, offset2);
180  }
181 
182  void Diagcat::ad_reverse(const std::vector<std::vector<MX> >& aseed,
183  std::vector<std::vector<MX> >& asens) const {
184  // Get offsets for each row and column
185  auto off = this->off();
186 
187  // Adjoint sensitivities
188  casadi_int nadj = aseed.size();
189  for (casadi_int d=0; d<nadj; ++d) {
190  std::vector<MX> s = diagsplit(aseed[d][0], off.first, off.second);
191  for (casadi_int i=0; i<n_dep(); ++i) {
192  asens[d][i] += s[i];
193  }
194  }
195  }
196 
197  Horzcat::Horzcat(const std::vector<MX>& x) : Concat(x) {
198  casadi_assert_dev(x.size()>1);
199  std::vector<Sparsity> sp(x.size());
200  for (casadi_int i=0; i<x.size(); ++i)
201  sp[i] = x[i].sparsity();
202  set_sparsity(horzcat(sp));
203  }
204 
205  std::string Horzcat::disp(const std::vector<std::string>& arg) const {
206  std::stringstream ss;
207  ss << "horzcat(" << arg.at(0);
208  for (casadi_int i=1; i<n_dep(); ++i) ss << ", " << arg.at(i);
209  ss << ")";
210  return ss.str();
211  }
212 
213  void Horzcat::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res,
214  const std::vector<bool>& unique) const {
215  res[0] = horzcat(arg);
216  }
217 
218  void Horzcat::ad_forward(const std::vector<std::vector<MX> >& fseed,
219  std::vector<std::vector<MX> >& fsens) const {
220  casadi_int nfwd = fsens.size();
221  for (casadi_int d = 0; d<nfwd; ++d) {
222  fsens[d][0] = horzcat(fseed[d]);
223  }
224  }
225 
226  std::vector<casadi_int> Horzcat::off() const {
227  std::vector<casadi_int> col_offset(n_dep()+1, 0);
228  for (casadi_int i=0; i<n_dep(); ++i) {
229  casadi_int ncol = dep(i).sparsity().size2();
230  col_offset[i+1] = col_offset[i] + ncol;
231  }
232  return col_offset;
233  }
234 
235  void Horzcat::ad_reverse(const std::vector<std::vector<MX> >& aseed,
236  std::vector<std::vector<MX> >& asens) const {
237  // Get offsets for each column
238  std::vector<casadi_int> col_offset = off();
239 
240  // Adjoint sensitivities
241  casadi_int nadj = aseed.size();
242  for (casadi_int d=0; d<nadj; ++d) {
243  std::vector<MX> s = horzsplit(aseed[d][0], col_offset);
244  for (casadi_int i=0; i<n_dep(); ++i) {
245  asens[d][i] += s[i];
246  }
247  }
248  }
249 
250  Vertcat::Vertcat(const std::vector<MX>& x) : Concat(x) {
251  casadi_assert_dev(x.size()>1);
252  std::vector<Sparsity> sp(x.size());
253  for (casadi_int i=0; i<x.size(); ++i) sp[i] = x[i].sparsity();
254  set_sparsity(vertcat(sp));
255  }
256 
257  std::string Vertcat::disp(const std::vector<std::string>& arg) const {
258  std::stringstream ss;
259  ss << "vertcat(" << arg.at(0);
260  for (casadi_int i=1; i<n_dep(); ++i) ss << ", " << arg.at(i);
261  ss << ")";
262  return ss.str();
263  }
264 
265  void Vertcat::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res,
266  const std::vector<bool>& unique) const {
267  res[0] = vertcat(arg);
268  }
269 
270  void Vertcat::ad_forward(const std::vector<std::vector<MX> >& fseed,
271  std::vector<std::vector<MX> >& fsens) const {
272  casadi_int nfwd = fsens.size();
273  for (casadi_int d = 0; d<nfwd; ++d) {
274  fsens[d][0] = vertcat(fseed[d]);
275  }
276  }
277 
278  std::vector<casadi_int> Vertcat::off() const {
279  std::vector<casadi_int> row_offset(n_dep()+1, 0);
280  for (casadi_int i=0; i<n_dep(); ++i) {
281  casadi_int nrow = dep(i).sparsity().size1();
282  row_offset[i+1] = row_offset[i] + nrow;
283  }
284  return row_offset;
285  }
286 
287  void Vertcat::ad_reverse(const std::vector<std::vector<MX> >& aseed,
288  std::vector<std::vector<MX> >& asens) const {
289  // Get offsets for each row
290  std::vector<casadi_int> row_offset = off();
291 
292  // Adjoint sensitivities
293  casadi_int nadj = aseed.size();
294  for (casadi_int d=0; d<nadj; ++d) {
295  std::vector<MX> s = vertsplit(aseed[d][0], row_offset);
296  for (casadi_int i=0; i<n_dep(); ++i) {
297  asens[d][i] += s[i];
298  }
299  }
300  }
301 
302  bool Concat::is_valid_input() const {
303  for (casadi_int i=0; i<n_dep(); ++i) {
304  if (!dep(i)->is_valid_input()) return false;
305  }
306  return true;
307  }
308 
309  casadi_int Concat::n_primitives() const {
310  casadi_int nprim = 0;
311  for (casadi_int i=0; i<n_dep(); ++i) {
312  nprim += dep(i)->n_primitives();
313  }
314  return nprim;
315  }
316 
317  template<typename T>
318  void Horzcat::split_primitives_gen(const T& x, typename std::vector<T>::iterator& it) const {
319  std::vector<T> s = horzsplit(x, off());
320  for (casadi_int i=0; i<s.size(); ++i) {
321  dep(i)->split_primitives(s[i], it);
322  }
323  }
324 
325  void Horzcat::split_primitives(const MX& x, std::vector<MX>::iterator& it) const {
326  split_primitives_gen<MX>(x, it);
327  }
328 
329  void Horzcat::split_primitives(const SX& x, std::vector<SX>::iterator& it) const {
330  split_primitives_gen<SX>(x, it);
331  }
332 
333  void Horzcat::split_primitives(const DM& x, std::vector<DM>::iterator& it) const {
334  split_primitives_gen<DM>(x, it);
335  }
336 
337  template<typename T>
338  T Horzcat::join_primitives_gen(typename std::vector<T>::const_iterator& it) const {
339  std::vector<T> s(n_dep());
340  for (casadi_int i=0; i<s.size(); ++i) {
341  s[i] = dep(i)->join_primitives(it);
342  }
343  return horzcat(s);
344  }
345 
346  MX Horzcat::join_primitives(std::vector<MX>::const_iterator& it) const {
347  return join_primitives_gen<MX>(it);
348  }
349 
350  SX Horzcat::join_primitives(std::vector<SX>::const_iterator& it) const {
351  return join_primitives_gen<SX>(it);
352  }
353 
354  DM Horzcat::join_primitives(std::vector<DM>::const_iterator& it) const {
355  return join_primitives_gen<DM>(it);
356  }
357 
358  template<typename T>
359  void Vertcat::split_primitives_gen(const T& x, typename std::vector<T>::iterator& it) const {
360  std::vector<T> s = vertsplit(x, off());
361  for (casadi_int i=0; i<s.size(); ++i) {
362  dep(i)->split_primitives(s[i], it);
363  }
364  }
365 
366  template<typename T>
367  T Vertcat::join_primitives_gen(typename std::vector<T>::const_iterator& it) const {
368  std::vector<T> s(n_dep());
369  for (casadi_int i=0; i<s.size(); ++i) {
370  s[i] = dep(i)->join_primitives(it);
371  }
372  return vertcat(s);
373  }
374 
375  void Vertcat::split_primitives(const MX& x, std::vector<MX>::iterator& it) const {
376  split_primitives_gen<MX>(x, it);
377  }
378 
379  void Vertcat::split_primitives(const SX& x, std::vector<SX>::iterator& it) const {
380  split_primitives_gen<SX>(x, it);
381  }
382 
383  void Vertcat::split_primitives(const DM& x, std::vector<DM>::iterator& it) const {
384  split_primitives_gen<DM>(x, it);
385  }
386 
387  MX Vertcat::join_primitives(std::vector<MX>::const_iterator& it) const {
388  return join_primitives_gen<MX>(it);
389  }
390 
391  SX Vertcat::join_primitives(std::vector<SX>::const_iterator& it) const {
392  return join_primitives_gen<SX>(it);
393  }
394 
395  DM Vertcat::join_primitives(std::vector<DM>::const_iterator& it) const {
396  return join_primitives_gen<DM>(it);
397  }
398 
399  template<typename T>
400  void Diagcat::split_primitives_gen(const T& x, typename std::vector<T>::iterator& it) const {
401  std::pair<std::vector<casadi_int>, std::vector<casadi_int> > off = this->off();
402  std::vector<T> s = diagsplit(x, off.first, off.second);
403  for (casadi_int i=0; i<s.size(); ++i) {
404  dep(i)->split_primitives(s[i], it);
405  }
406  }
407 
408  template<typename T>
409  T Diagcat::join_primitives_gen(typename std::vector<T>::const_iterator& it) const {
410  std::vector<T> s(n_dep());
411  for (casadi_int i=0; i<s.size(); ++i) {
412  s[i] = dep(i)->join_primitives(it);
413  }
414  return diagcat(s);
415  }
416 
417  void Diagcat::split_primitives(const MX& x, std::vector<MX>::iterator& it) const {
418  split_primitives_gen<MX>(x, it);
419  }
420 
421  void Diagcat::split_primitives(const SX& x, std::vector<SX>::iterator& it) const {
422  split_primitives_gen<SX>(x, it);
423  }
424 
425  void Diagcat::split_primitives(const DM& x, std::vector<DM>::iterator& it) const {
426  split_primitives_gen<DM>(x, it);
427  }
428 
429  MX Diagcat::join_primitives(std::vector<MX>::const_iterator& it) const {
430  return join_primitives_gen<MX>(it);
431  }
432 
433  SX Diagcat::join_primitives(std::vector<SX>::const_iterator& it) const {
434  return join_primitives_gen<SX>(it);
435  }
436 
437  DM Diagcat::join_primitives(std::vector<DM>::const_iterator& it) const {
438  return join_primitives_gen<DM>(it);
439  }
440 
441  bool Concat::has_duplicates() const {
442  bool has_duplicates = false;
443  for (casadi_int i=0; i<n_dep(); ++i) {
445  }
446  return has_duplicates;
447  }
448 
449  void Concat::reset_input() const {
450  for (casadi_int i=0; i<n_dep(); ++i) {
451  dep(i)->reset_input();
452  }
453  }
454 
455  void Concat::primitives(std::vector<MX>::iterator& it) const {
456  for (casadi_int i=0; i<n_dep(); ++i) {
457  dep(i)->primitives(it);
458  }
459  }
460 
461 } // namespace casadi
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
std::string workel(casadi_int n) const
Concatenation: Join multiple expressions stacking the nonzeros.
Definition: concat.hpp:42
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
Definition: concat.cpp:57
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.
Definition: concat.cpp:81
~Concat() override=0
Destructor.
Definition: concat.cpp:35
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
Definition: concat.cpp:68
bool has_duplicates() const override
Detect duplicate symbolic expressions.
Definition: concat.cpp:441
void reset_input() const override
Reset the marker for an input expression.
Definition: concat.cpp:449
MX get_nzref(const Sparsity &sp, const std::vector< casadi_int > &nz, bool unique=false) const override
Get the nonzeros of matrix.
Definition: concat.cpp:101
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
Definition: concat.cpp:42
casadi_int n_primitives() const override
Get the number of symbolic primitives.
Definition: concat.cpp:309
void primitives(std::vector< MX >::iterator &it) const override
Get symbolic primitives.
Definition: concat.cpp:455
bool is_valid_input() const override
Check if valid function input.
Definition: concat.cpp:302
int eval_gen(const T *const *arg, T *const *res, casadi_int *iw, T *w) const
Evaluate the function (template)
Definition: concat.cpp:47
Concat(const std::vector< MX > &x)
Constructor.
Definition: concat.cpp:31
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
Definition: concat.cpp:38
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
Definition: concat.cpp:164
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
Definition: concat.cpp:400
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
Definition: concat.cpp:182
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
Definition: concat.cpp:429
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
Definition: concat.cpp:409
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: concat.cpp:151
Diagcat(const std::vector< MX > &x)
Constructor.
Definition: concat.cpp:144
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
Definition: concat.cpp:159
std::pair< std::vector< casadi_int >, std::vector< casadi_int > > off() const
Get offsets for split.
Definition: concat.cpp:170
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
Definition: concat.cpp:417
casadi_int nnz() const
Get the number of (structural) non-zero elements.
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.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: concat.cpp:205
std::vector< casadi_int > off() const
Get offsets for split.
Definition: concat.cpp:226
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
Definition: concat.cpp:346
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
Definition: concat.cpp:325
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
Definition: concat.cpp:218
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
Definition: concat.cpp:235
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
Definition: concat.cpp:338
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
Definition: concat.cpp:213
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
Definition: concat.cpp:318
Horzcat(const std::vector< MX > &x)
Constructor.
Definition: concat.cpp:197
virtual MX get_nzref(const Sparsity &sp, const std::vector< casadi_int > &nz, bool unique=false) const
Get the nonzeros of matrix.
Definition: mx_node.cpp:660
virtual void reset_input() const
Reset the marker for an input expression.
Definition: mx_node.cpp:152
virtual casadi_int n_primitives() const
Get the number of symbolic primitives.
Definition: mx_node.cpp:144
virtual bool has_duplicates() const
Detect duplicate symbolic expressions.
Definition: mx_node.cpp:148
virtual bool is_valid_input() const
Check if valid function input.
Definition: mx_node.hpp:269
virtual MX join_primitives(std::vector< MX >::const_iterator &it) const
Join an expression along symbolic primitives.
Definition: mx_node.cpp:183
const Sparsity & sparsity() const
Get the sparsity.
Definition: mx_node.hpp:410
casadi_int nnz(casadi_int i=0) const
Definition: mx_node.hpp:427
const MX & dep(casadi_int ind=0) const
dependencies - functions that have to be evaluated before this one
Definition: mx_node.hpp:392
casadi_int n_dep() const
Number of dependencies.
Definition: mx_node.cpp:208
virtual void primitives(std::vector< MX >::iterator &it) const
Get symbolic primitives.
Definition: mx_node.cpp:156
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
Definition: mx_node.cpp:224
void set_dep(const MX &dep)
Set unary dependency.
Definition: mx_node.cpp:228
virtual void split_primitives(const MX &x, std::vector< MX >::iterator &it) const
Split up an expression along symbolic primitives.
Definition: mx_node.cpp:160
MX - Matrix expression.
Definition: mx.hpp:92
const Sparsity & sparsity() const
Get the sparsity pattern.
Definition: mx.cpp:612
Sparse matrix class. SX and DM are specializations.
Definition: matrix_decl.hpp:99
The basic scalar symbolic class of CasADi.
Definition: sx_elem.hpp:75
General sparsity class.
Definition: sparsity.hpp:106
casadi_int size1() const
Get the number of rows.
Definition: sparsity.cpp:124
casadi_int size2() const
Get the number of columns.
Definition: sparsity.cpp:128
Vertcat(const std::vector< MX > &x)
Constructor.
Definition: concat.cpp:250
std::vector< casadi_int > off() const
Get offsets for split.
Definition: concat.cpp:278
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: concat.cpp:257
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
Definition: concat.cpp:359
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
Definition: concat.cpp:265
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
Definition: concat.cpp:375
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
Definition: concat.cpp:287
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
Definition: concat.cpp:367
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
Definition: concat.cpp:270
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
Definition: concat.cpp:387
The casadi namespace.
Definition: archiver.cpp:28
unsigned long long bvec_t