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) const {
102  // Get the first nonnegative nz
103  casadi_int nz_test = -1;
104  for (auto&& i : nz) {
105  if (i>=0) {
106  nz_test = i;
107  break;
108  }
109  }
110 
111  // Quick return if none
112  if (nz_test<0) return MX::zeros(sp);
113 
114  // Find out to which dependency it might depend
115  casadi_int begin=0, end=0;
116  casadi_int i;
117  for (i=0; i<n_dep(); ++i) {
118  begin = end;
119  end += dep(i).nnz();
120  if (nz_test < end) break;
121  }
122 
123  // Check if any nz refer to a different nonzero
124  for (auto&& j : nz) {
125  if (j>=0 && (j < begin || j >= end)) {
126 
127  // Fallback to the base class
128  return MXNode::get_nzref(sp, nz);
129  }
130  }
131 
132  // All nz refer to the same dependency, update the nonzero indices
133  if (begin==0) {
134  return dep(i)->get_nzref(sp, nz);
135  } else {
136  std::vector<casadi_int> nz_new(nz);
137  for (auto&& j : nz_new) if (j>=0) j -= begin;
138  return dep(i)->get_nzref(sp, nz_new);
139  }
140  }
141 
142 
143  Diagcat::Diagcat(const std::vector<MX>& x) : Concat(x) {
144  casadi_assert_dev(x.size()>1);
145  std::vector<Sparsity> sp(x.size());
146  for (casadi_int i=0; i<x.size(); ++i) sp[i] = x[i].sparsity();
147  set_sparsity(diagcat(sp));
148  }
149 
150  std::string Diagcat::disp(const std::vector<std::string>& arg) const {
151  std::stringstream ss;
152  ss << "diagcat(" << arg.at(0);
153  for (casadi_int i=1; i<n_dep(); ++i) ss << ", " << arg.at(i);
154  ss << ")";
155  return ss.str();
156  }
157 
158  void Diagcat::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
159  res[0] = diagcat(arg);
160  }
161 
162  void Diagcat::ad_forward(const std::vector<std::vector<MX> >& fseed,
163  std::vector<std::vector<MX> >& fsens) const {
164  casadi_int nfwd = fsens.size();
165  for (casadi_int d = 0; d<nfwd; ++d) fsens[d][0] = diagcat(fseed[d]);
166  }
167 
168  std::pair<std::vector<casadi_int>, std::vector<casadi_int> > Diagcat::off() const {
169  std::vector<casadi_int> offset1(n_dep()+1, 0);
170  std::vector<casadi_int> offset2(n_dep()+1, 0);
171  for (casadi_int i=0; i<n_dep(); ++i) {
172  casadi_int ncol = dep(i).sparsity().size2();
173  casadi_int nrow = dep(i).sparsity().size1();
174  offset2[i+1] = offset2[i] + ncol;
175  offset1[i+1] = offset1[i] + nrow;
176  }
177  return std::make_pair(offset1, offset2);
178  }
179 
180  void Diagcat::ad_reverse(const std::vector<std::vector<MX> >& aseed,
181  std::vector<std::vector<MX> >& asens) const {
182  // Get offsets for each row and column
183  auto off = this->off();
184 
185  // Adjoint sensitivities
186  casadi_int nadj = aseed.size();
187  for (casadi_int d=0; d<nadj; ++d) {
188  std::vector<MX> s = diagsplit(aseed[d][0], off.first, off.second);
189  for (casadi_int i=0; i<n_dep(); ++i) {
190  asens[d][i] += s[i];
191  }
192  }
193  }
194 
195  Horzcat::Horzcat(const std::vector<MX>& x) : Concat(x) {
196  casadi_assert_dev(x.size()>1);
197  std::vector<Sparsity> sp(x.size());
198  for (casadi_int i=0; i<x.size(); ++i)
199  sp[i] = x[i].sparsity();
200  set_sparsity(horzcat(sp));
201  }
202 
203  std::string Horzcat::disp(const std::vector<std::string>& arg) const {
204  std::stringstream ss;
205  ss << "horzcat(" << arg.at(0);
206  for (casadi_int i=1; i<n_dep(); ++i) ss << ", " << arg.at(i);
207  ss << ")";
208  return ss.str();
209  }
210 
211  void Horzcat::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
212  res[0] = horzcat(arg);
213  }
214 
215  void Horzcat::ad_forward(const std::vector<std::vector<MX> >& fseed,
216  std::vector<std::vector<MX> >& fsens) const {
217  casadi_int nfwd = fsens.size();
218  for (casadi_int d = 0; d<nfwd; ++d) {
219  fsens[d][0] = horzcat(fseed[d]);
220  }
221  }
222 
223  std::vector<casadi_int> Horzcat::off() const {
224  std::vector<casadi_int> col_offset(n_dep()+1, 0);
225  for (casadi_int i=0; i<n_dep(); ++i) {
226  casadi_int ncol = dep(i).sparsity().size2();
227  col_offset[i+1] = col_offset[i] + ncol;
228  }
229  return col_offset;
230  }
231 
232  void Horzcat::ad_reverse(const std::vector<std::vector<MX> >& aseed,
233  std::vector<std::vector<MX> >& asens) const {
234  // Get offsets for each column
235  std::vector<casadi_int> col_offset = off();
236 
237  // Adjoint sensitivities
238  casadi_int nadj = aseed.size();
239  for (casadi_int d=0; d<nadj; ++d) {
240  std::vector<MX> s = horzsplit(aseed[d][0], col_offset);
241  for (casadi_int i=0; i<n_dep(); ++i) {
242  asens[d][i] += s[i];
243  }
244  }
245  }
246 
247  Vertcat::Vertcat(const std::vector<MX>& x) : Concat(x) {
248  casadi_assert_dev(x.size()>1);
249  std::vector<Sparsity> sp(x.size());
250  for (casadi_int i=0; i<x.size(); ++i) sp[i] = x[i].sparsity();
251  set_sparsity(vertcat(sp));
252  }
253 
254  std::string Vertcat::disp(const std::vector<std::string>& arg) const {
255  std::stringstream ss;
256  ss << "vertcat(" << arg.at(0);
257  for (casadi_int i=1; i<n_dep(); ++i) ss << ", " << arg.at(i);
258  ss << ")";
259  return ss.str();
260  }
261 
262  void Vertcat::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
263  res[0] = vertcat(arg);
264  }
265 
266  void Vertcat::ad_forward(const std::vector<std::vector<MX> >& fseed,
267  std::vector<std::vector<MX> >& fsens) const {
268  casadi_int nfwd = fsens.size();
269  for (casadi_int d = 0; d<nfwd; ++d) {
270  fsens[d][0] = vertcat(fseed[d]);
271  }
272  }
273 
274  std::vector<casadi_int> Vertcat::off() const {
275  std::vector<casadi_int> row_offset(n_dep()+1, 0);
276  for (casadi_int i=0; i<n_dep(); ++i) {
277  casadi_int nrow = dep(i).sparsity().size1();
278  row_offset[i+1] = row_offset[i] + nrow;
279  }
280  return row_offset;
281  }
282 
283  void Vertcat::ad_reverse(const std::vector<std::vector<MX> >& aseed,
284  std::vector<std::vector<MX> >& asens) const {
285  // Get offsets for each row
286  std::vector<casadi_int> row_offset = off();
287 
288  // Adjoint sensitivities
289  casadi_int nadj = aseed.size();
290  for (casadi_int d=0; d<nadj; ++d) {
291  std::vector<MX> s = vertsplit(aseed[d][0], row_offset);
292  for (casadi_int i=0; i<n_dep(); ++i) {
293  asens[d][i] += s[i];
294  }
295  }
296  }
297 
298  bool Concat::is_valid_input() const {
299  for (casadi_int i=0; i<n_dep(); ++i) {
300  if (!dep(i)->is_valid_input()) return false;
301  }
302  return true;
303  }
304 
305  casadi_int Concat::n_primitives() const {
306  casadi_int nprim = 0;
307  for (casadi_int i=0; i<n_dep(); ++i) {
308  nprim += dep(i)->n_primitives();
309  }
310  return nprim;
311  }
312 
313  template<typename T>
314  void Horzcat::split_primitives_gen(const T& x, typename std::vector<T>::iterator& it) const {
315  std::vector<T> s = horzsplit(x, off());
316  for (casadi_int i=0; i<s.size(); ++i) {
317  dep(i)->split_primitives(s[i], it);
318  }
319  }
320 
321  void Horzcat::split_primitives(const MX& x, std::vector<MX>::iterator& it) const {
322  split_primitives_gen<MX>(x, it);
323  }
324 
325  void Horzcat::split_primitives(const SX& x, std::vector<SX>::iterator& it) const {
326  split_primitives_gen<SX>(x, it);
327  }
328 
329  void Horzcat::split_primitives(const DM& x, std::vector<DM>::iterator& it) const {
330  split_primitives_gen<DM>(x, it);
331  }
332 
333  template<typename T>
334  T Horzcat::join_primitives_gen(typename std::vector<T>::const_iterator& it) const {
335  std::vector<T> s(n_dep());
336  for (casadi_int i=0; i<s.size(); ++i) {
337  s[i] = dep(i)->join_primitives(it);
338  }
339  return horzcat(s);
340  }
341 
342  MX Horzcat::join_primitives(std::vector<MX>::const_iterator& it) const {
343  return join_primitives_gen<MX>(it);
344  }
345 
346  SX Horzcat::join_primitives(std::vector<SX>::const_iterator& it) const {
347  return join_primitives_gen<SX>(it);
348  }
349 
350  DM Horzcat::join_primitives(std::vector<DM>::const_iterator& it) const {
351  return join_primitives_gen<DM>(it);
352  }
353 
354  template<typename T>
355  void Vertcat::split_primitives_gen(const T& x, typename std::vector<T>::iterator& it) const {
356  std::vector<T> s = vertsplit(x, off());
357  for (casadi_int i=0; i<s.size(); ++i) {
358  dep(i)->split_primitives(s[i], it);
359  }
360  }
361 
362  template<typename T>
363  T Vertcat::join_primitives_gen(typename std::vector<T>::const_iterator& it) const {
364  std::vector<T> s(n_dep());
365  for (casadi_int i=0; i<s.size(); ++i) {
366  s[i] = dep(i)->join_primitives(it);
367  }
368  return vertcat(s);
369  }
370 
371  void Vertcat::split_primitives(const MX& x, std::vector<MX>::iterator& it) const {
372  split_primitives_gen<MX>(x, it);
373  }
374 
375  void Vertcat::split_primitives(const SX& x, std::vector<SX>::iterator& it) const {
376  split_primitives_gen<SX>(x, it);
377  }
378 
379  void Vertcat::split_primitives(const DM& x, std::vector<DM>::iterator& it) const {
380  split_primitives_gen<DM>(x, it);
381  }
382 
383  MX Vertcat::join_primitives(std::vector<MX>::const_iterator& it) const {
384  return join_primitives_gen<MX>(it);
385  }
386 
387  SX Vertcat::join_primitives(std::vector<SX>::const_iterator& it) const {
388  return join_primitives_gen<SX>(it);
389  }
390 
391  DM Vertcat::join_primitives(std::vector<DM>::const_iterator& it) const {
392  return join_primitives_gen<DM>(it);
393  }
394 
395  template<typename T>
396  void Diagcat::split_primitives_gen(const T& x, typename std::vector<T>::iterator& it) const {
397  std::pair<std::vector<casadi_int>, std::vector<casadi_int> > off = this->off();
398  std::vector<T> s = diagsplit(x, off.first, off.second);
399  for (casadi_int i=0; i<s.size(); ++i) {
400  dep(i)->split_primitives(s[i], it);
401  }
402  }
403 
404  template<typename T>
405  T Diagcat::join_primitives_gen(typename std::vector<T>::const_iterator& it) const {
406  std::vector<T> s(n_dep());
407  for (casadi_int i=0; i<s.size(); ++i) {
408  s[i] = dep(i)->join_primitives(it);
409  }
410  return diagcat(s);
411  }
412 
413  void Diagcat::split_primitives(const MX& x, std::vector<MX>::iterator& it) const {
414  split_primitives_gen<MX>(x, it);
415  }
416 
417  void Diagcat::split_primitives(const SX& x, std::vector<SX>::iterator& it) const {
418  split_primitives_gen<SX>(x, it);
419  }
420 
421  void Diagcat::split_primitives(const DM& x, std::vector<DM>::iterator& it) const {
422  split_primitives_gen<DM>(x, it);
423  }
424 
425  MX Diagcat::join_primitives(std::vector<MX>::const_iterator& it) const {
426  return join_primitives_gen<MX>(it);
427  }
428 
429  SX Diagcat::join_primitives(std::vector<SX>::const_iterator& it) const {
430  return join_primitives_gen<SX>(it);
431  }
432 
433  DM Diagcat::join_primitives(std::vector<DM>::const_iterator& it) const {
434  return join_primitives_gen<DM>(it);
435  }
436 
437  bool Concat::has_duplicates() const {
438  bool has_duplicates = false;
439  for (casadi_int i=0; i<n_dep(); ++i) {
441  }
442  return has_duplicates;
443  }
444 
445  void Concat::reset_input() const {
446  for (casadi_int i=0; i<n_dep(); ++i) {
447  dep(i)->reset_input();
448  }
449  }
450 
451  void Concat::primitives(std::vector<MX>::iterator& it) const {
452  for (casadi_int i=0; i<n_dep(); ++i) {
453  dep(i)->primitives(it);
454  }
455  }
456 
457 } // 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:437
MX get_nzref(const Sparsity &sp, const std::vector< casadi_int > &nz) const override
Get the nonzeros of matrix.
Definition: concat.cpp:101
void reset_input() const override
Reset the marker for an input expression.
Definition: concat.cpp:445
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:305
void primitives(std::vector< MX >::iterator &it) const override
Get symbolic primitives.
Definition: concat.cpp:451
bool is_valid_input() const override
Check if valid function input.
Definition: concat.cpp:298
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:162
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
Definition: concat.cpp:158
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
Definition: concat.cpp:396
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:180
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
Definition: concat.cpp:425
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
Definition: concat.cpp:405
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: concat.cpp:150
Diagcat(const std::vector< MX > &x)
Constructor.
Definition: concat.cpp:143
std::pair< std::vector< casadi_int >, std::vector< casadi_int > > off() const
Get offsets for split.
Definition: concat.cpp:168
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
Definition: concat.cpp:413
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:203
std::vector< casadi_int > off() const
Get offsets for split.
Definition: concat.cpp:223
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
Definition: concat.cpp:342
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
Definition: concat.cpp:321
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:215
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:232
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
Definition: concat.cpp:334
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
Definition: concat.cpp:314
Horzcat(const std::vector< MX > &x)
Constructor.
Definition: concat.cpp:195
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
Definition: concat.cpp:211
virtual void reset_input() const
Reset the marker for an input expression.
Definition: mx_node.cpp:150
virtual casadi_int n_primitives() const
Get the number of symbolic primitives.
Definition: mx_node.cpp:142
virtual bool has_duplicates() const
Detect duplicate symbolic expressions.
Definition: mx_node.cpp:146
virtual bool is_valid_input() const
Check if valid function input.
Definition: mx_node.hpp:231
virtual MX join_primitives(std::vector< MX >::const_iterator &it) const
Join an expression along symbolic primitives.
Definition: mx_node.cpp:181
const Sparsity & sparsity() const
Get the sparsity.
Definition: mx_node.hpp:372
casadi_int nnz(casadi_int i=0) const
Definition: mx_node.hpp:389
const MX & dep(casadi_int ind=0) const
dependencies - functions that have to be evaluated before this one
Definition: mx_node.hpp:354
casadi_int n_dep() const
Number of dependencies.
Definition: mx_node.cpp:206
virtual void primitives(std::vector< MX >::iterator &it) const
Get symbolic primitives.
Definition: mx_node.cpp:154
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
Definition: mx_node.cpp:222
virtual MX get_nzref(const Sparsity &sp, const std::vector< casadi_int > &nz) const
Get the nonzeros of matrix.
Definition: mx_node.cpp:657
void set_dep(const MX &dep)
Set unary dependency.
Definition: mx_node.cpp:226
virtual void split_primitives(const MX &x, std::vector< MX >::iterator &it) const
Split up an expression along symbolic primitives.
Definition: mx_node.cpp:158
MX - Matrix expression.
Definition: mx.hpp:92
const Sparsity & sparsity() const
Get the sparsity pattern.
Definition: mx.cpp:592
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
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
Definition: concat.cpp:262
Vertcat(const std::vector< MX > &x)
Constructor.
Definition: concat.cpp:247
std::vector< casadi_int > off() const
Get offsets for split.
Definition: concat.cpp:274
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: concat.cpp:254
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
Definition: concat.cpp:355
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
Definition: concat.cpp:371
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:283
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
Definition: concat.cpp:363
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:266
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
Definition: concat.cpp:383
The casadi namespace.
Definition: archiver.cpp:28
unsigned long long bvec_t