bspline.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 "bspline_impl.hpp"
27 
28 namespace casadi {
29 
31  char t;
32  s.unpack("BSpline::type", t);
33  switch (t) {
34  case 'n':
35  return new BSpline(s);
36  case 'p':
37  return new BSplineParametric(s);
38  default:
39  casadi_error("Unknown BSpline type");
40  }
41  }
42 
44  BSplineCommon::BSplineCommon(const std::vector<double>& knots,
45  const std::vector<casadi_int>& offset,
46  const std::vector<casadi_int>& degree,
47  casadi_int m,
48  const std::vector<casadi_int>& lookup_mode) :
49  knots_(knots), offset_(offset), degree_(degree),
50  m_(m), lookup_mode_(lookup_mode) {
52  }
53 
54  size_t BSplineCommon::sz_iw() const {
55  return n_iw(degree_);
56  }
57 
58  size_t BSplineCommon::sz_w() const {
59  return n_w(degree_);
60  }
61 
62  size_t BSplineCommon::n_iw(const std::vector<casadi_int>& degree) {
63  casadi_int n_dims = degree.size();
64  casadi_int sz = 0;
65  sz += n_dims+1; // boor_offset
66  sz += n_dims; // starts
67  sz += n_dims; // index
68  sz += n_dims+1; // coeff_offset
69  return sz;
70  }
71 
72  size_t BSplineCommon::n_w(const std::vector<casadi_int>& degree) {
73  casadi_int n_dims = degree.size();
74  casadi_int sz = 0;
75  for (casadi_int k=0;k<n_dims-1;++k) {
76  sz += degree[k]+1; // boor
77  }
78  sz += 2*degree[n_dims-1]+1;
79  sz += n_dims+1;
80  return sz;
81  }
82 
83  casadi_int BSplineCommon::get_coeff_size(casadi_int m, const std::vector<casadi_int>& offset,
84  const std::vector<casadi_int>& degree) {
85  casadi_int ret = m;
86  for (casadi_int i=0;i<degree.size();++i) ret*= offset[i+1]-offset[i]-degree[i]-1;
87  return ret;
88  }
89 
90  void BSplineCommon::prepare(casadi_int m, const std::vector<casadi_int>& offset,
91  const std::vector<casadi_int>& degree, casadi_int &coeffs_size,
92  std::vector<casadi_int>& coeffs_dims, std::vector<casadi_int>& strides) {
93 
94  casadi_int n_dims = degree.size();
95  coeffs_size = get_coeff_size(m, offset, degree);
96  coeffs_dims.resize(n_dims+1);
97  coeffs_dims[0] = m;
98  for (casadi_int i=0;i<n_dims;++i) coeffs_dims[i+1] = offset[i+1]-offset[i]-degree[i]-1;
99 
100  // Prepare strides
101  strides.resize(n_dims);
102  strides[0] = m;
103  for (casadi_int i=0;i<n_dims-1;++i) {
104  strides[i+1] = strides[i]*coeffs_dims[i+1];
105  }
106  }
107 
110  s.pack("BSpline::type", 'n');
111  }
112 
115  s.pack("BSpline::type", 'p');
116  }
117 
120  s.pack("BSplineCommon::knots", knots_);
121  s.pack("BSplineCommon::offset", offset_);
122  s.pack("BSplineCommon::degree", degree_);
123  s.pack("BSplineCommon::m", m_);
124  s.pack("BSplineCommon::lookup_mode", lookup_mode_);
125  s.pack("BSplineCommon::strides", strides_);
126  s.pack("BSplineCommon::coeffs_dims", coeffs_dims_);
127  s.pack("BSplineCommon::coeffs_size", coeffs_size_);
128  s.pack("BSplineCommon::jac_cache_", jac_cache_);
129  }
130 
132  s.unpack("BSplineCommon::knots", knots_);
133  s.unpack("BSplineCommon::offset", offset_);
134  s.unpack("BSplineCommon::degree", degree_);
135  s.unpack("BSplineCommon::m", m_);
136  s.unpack("BSplineCommon::lookup_mode", lookup_mode_);
137  s.unpack("BSplineCommon::strides", strides_);
138  s.unpack("BSplineCommon::coeffs_dims", coeffs_dims_);
139  s.unpack("BSplineCommon::coeffs_size", coeffs_size_);
140  s.unpack("BSplineCommon::jac_cache_", jac_cache_);
141  }
142 
145  s.pack("BSpline::coeffs", coeffs_);
146  }
147 
149  s.unpack("BSpline::coeffs", coeffs_);
150  }
151 
152  BSpline::BSpline(const MX& x, const std::vector<double>& knots,
153  const std::vector<casadi_int>& offset,
154  const std::vector<double>& coeffs,
155  const std::vector<casadi_int>& degree,
156  casadi_int m,
157  const std::vector<casadi_int>& lookup_mode) :
158  BSplineCommon(knots, offset, degree, m, lookup_mode), coeffs_(coeffs) {
159  casadi_assert_dev(x.numel()==degree.size());
160  set_dep(x);
162  }
163 
165  const MX& coeffs,
166  const std::vector<double>& knots,
167  const std::vector<casadi_int>& offset,
168  const std::vector<casadi_int>& degree,
169  casadi_int m,
170  const std::vector<casadi_int>& lookup_mode) :
171  BSplineCommon(knots, offset, degree, m, lookup_mode) {
172  casadi_assert_dev(x.size1()==degree.size());
173  set_dep(x, coeffs);
175  }
176 
177  void get_boor(const MX& x, const MX& knots, casadi_int degree, casadi_int lookup_mode,
178  MX& start, MX& boor) {
179  MX knots_clipped = knots(range(degree, knots.size1()-degree));
180 
181  Dict low_opts;
182  low_opts["lookup_mode"] = Low::lookup_mode_from_enum(lookup_mode);
183  MX L = low(knots_clipped, x, low_opts);
184  start = fmin(L, knots.size1()-2*degree-2);
185 
186  DM boor_init = DM::zeros(x.size2(), 2*degree+1);
187  boor_init(Slice(), degree) = 1;
188  std::vector<MX> boor_full = horzsplit(MX(boor_init));
189  casadi_int n_knots = 2*degree+2;
190 
191  MX kn;
192  MX(knots).get_nz(kn, false, start, MX(range(n_knots)));
193 
194  std::vector<MX> knv = horzsplit(kn);
195 
196  MX xt = x.T();
197 
198  for (casadi_int d=1;d<degree+1;++d) {
199  for (casadi_int i=0;i<n_knots-d-1;++i) {
200  MX bottom = knv[i+d]-knv[i];
201  MX b = if_else_zero(bottom, (xt-knv[i])*boor_full[i]/(bottom+1e-100));
202  bottom = knv[i+d+1]-knv[i + 1];
203  b += if_else_zero(bottom, (knv[i+d+1]-xt)*boor_full[i+1]/(bottom+1e-100));
204  boor_full[i] = b;
205  }
206  }
207 
208  boor = horzcat(std::vector<MX>(boor_full.begin(), boor_full.begin()+degree+1));
209  }
210 
211  MX do_inline(const MX& x,
212  const std::vector< std::vector<double> >& knots,
213  const MX& coeffs,
214  casadi_int m,
215  const std::vector<casadi_int>& degree,
216  const std::vector<casadi_int>& lookup_mode) {
217 
218  casadi_int batch_x = x.size2();
219 
220  // Number of grid points
221  casadi_int N = knots.size();
222  std::vector<MX> xs = vertsplit(x);
223 
224  // Compute De Boor vector in each direction
225  std::vector<MX> starts(N);
226  std::vector< std::vector<MX> > boors(N);
227  for (casadi_int i=0;i<N;++i) {
228  MX boor;
229  get_boor(xs[i], knots[i], degree[i], lookup_mode[i], starts[i], boor);
230  boors[i] = horzsplit(boor.T());
231  }
232 
233  // Compute strides
234  std::vector<casadi_int> strides = {m};
235  for (casadi_int i=0;i<N-1;++i) {
236  strides.push_back(strides.back()*(knots[i].size()-degree[i]-1));
237  }
238 
239  // Start index of subtensor: row vector
240  MX start = mtimes(DM(strides).T(), vertcat(starts));
241 
242  // Elements of subtensor
243  DM core = DM(range(m));
244  for (casadi_int i=0;i<N;++i) {
245  casadi_int n = degree[i]+1;
246  core = vec(repmat(core, 1, n)+repmat(strides[i]*DM(range(n)).T(), core.size1(), 1));
247  }
248 
249  std::vector<MX> res;
250 
251  for (casadi_int k=0;k<batch_x;++k) {
252 
253  // Flattened subtensor of coefficients
254  MX c = reshape(coeffs(start(k)+core), m, -1);
255 
256  // Compute outer product of De Boor vectors
257  MX boor = 1;
258  for (casadi_int i=0;i<N;++i) {
259  boor = vec(mtimes(boor, boors[i][k].T()));
260  }
261 
262  res.push_back(mtimes(c, boor));
263  }
264 
265  return horzcat(res);
266  }
267 
268  MX BSpline::create(const MX& x, const std::vector< std::vector<double> >& knots,
269  const std::vector<double>& coeffs,
270  const std::vector<casadi_int>& degree,
271  casadi_int m,
272  const Dict& opts) {
273 
274  casadi_assert(x.is_vector(), "x argument must be a vector, got " + x.dim() + " instead.");
275  casadi_assert(x.numel()==knots.size(), "x argument length (" + str(x.numel()) + ") must match "
276  "number knot list length (" + str(knots.size()) + ").");
277  casadi_assert(degree.size()==knots.size(), "Degree list length (" + str(degree.size()) + ") "
278  "must match knot list length (" + str(knots.size()) + ").");
279 
280  bool do_inline_flag = false;
281  std::vector<std::string> lookup_mode;
282 
283  for (auto&& op : opts) {
284  if (op.first=="inline") {
285  do_inline_flag = op.second;
286  } else if (op.first=="lookup_mode") {
287  lookup_mode = op.second;
288  }
289  }
290 
291  std::vector<casadi_int> offset;
292  std::vector<double> stacked;
293  Interpolant::stack_grid(knots, offset, stacked);
294 
295  std::vector<casadi_int> mode =
296  Interpolant::interpret_lookup_mode(lookup_mode, stacked, offset, degree, degree);
297 
298  if (do_inline_flag) {
299  return do_inline(x, knots, coeffs, m, degree, mode);
300  } else {
301  return x->get_bspline(stacked, offset, coeffs, degree, m, mode);
302  }
303  }
304 
306  const MX& coeffs,
307  const std::vector< std::vector<double> >& knots,
308  const std::vector<casadi_int>& degree,
309  casadi_int m,
310  const Dict& opts) {
311 
312  casadi_assert(x.is_vector(), "x argument must be a vector, got " + x.dim() + " instead.");
313  casadi_assert(x.numel()==knots.size(), "x argument length (" + str(x.numel()) + ") must match "
314  "knot list length (" + str(knots.size()) + ").");
315  casadi_assert(degree.size()==knots.size(), "Degree list length (" + str(degree.size()) + ") "
316  "must match knot list length (" + str(knots.size()) + ").");
317  bool do_inline_flag = false;
318  std::vector<std::string> lookup_mode;
319 
320  for (auto&& op : opts) {
321  if (op.first=="inline") {
322  do_inline_flag = op.second;
323  } else if (op.first=="lookup_mode") {
324  lookup_mode = op.second;
325  }
326  }
327 
328  std::vector<casadi_int> offset;
329  std::vector<double> stacked;
330  Interpolant::stack_grid(knots, offset, stacked);
331  std::vector<casadi_int> mode =
332  Interpolant::interpret_lookup_mode(lookup_mode, stacked, offset, degree, degree);
333 
334  if (do_inline_flag) {
335  return do_inline(x, knots, coeffs, m, degree, mode);
336  } else {
337  return x->get_bspline(coeffs, stacked, offset, degree, m, mode);
338  }
339  }
340 
341  std::string BSpline::disp(const std::vector<std::string>& arg) const {
342  return "BSpline(" + arg.at(0) + ")";
343  }
344 
345  std::string BSplineParametric::disp(const std::vector<std::string>& arg) const {
346  return "BSplineParametric(" + arg.at(0) + ", " + arg.at(1) + ")";
347  }
348 
349  void BSpline::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
350  res[0] = arg[0]->get_bspline(knots_, offset_, coeffs_, degree_, m_, lookup_mode_);
351  }
352 
353  void BSplineParametric::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
354  res[0] = arg[0]->get_bspline(arg[1], knots_, offset_, degree_, m_, lookup_mode_);
355  }
356 
358 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
359  // Safe access to jac_cache_
360  std::lock_guard<std::mutex> lock(jac_cache_mtx_);
361 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
362  if (jac_cache_.is_empty()) {
363  jac_cache_ = jac(dep(0), DM(coeffs_));
364  }
365  return jac_cache_;
366  }
367 
369 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
370  std::lock_guard<std::mutex> lock(jac_cache_mtx_);
371 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
372  if (jac_cache_.is_empty()) {
373  jac_cache_ = jac(dep(0), dep(1));
374  }
375  return jac_cache_;
376  }
377 
378  void BSplineCommon::ad_forward(const std::vector<std::vector<MX> >& fseed,
379  std::vector<std::vector<MX> >& fsens) const {
380  MX J = jac_cached();
381 
382  for (casadi_int d=0; d<fsens.size(); ++d) {
383  fsens[d][0] = mtimes(J, fseed[d][0]);
384  }
385  }
386 
387  void BSplineCommon::ad_reverse(const std::vector<std::vector<MX> >& aseed,
388  std::vector<std::vector<MX> >& asens) const {
389  MX JT = jac_cached().T();
390  for (casadi_int d=0; d<aseed.size(); ++d) {
391  asens[d][0] += mtimes(JT, aseed[d][0]);
392  }
393  }
394 
395  int BSpline::eval(const double** arg, double** res, casadi_int* iw, double* w) const {
396  if (!res[0]) return 0;
397 
398  casadi_clear(res[0], m_);
401  iw, w);
402  return 0;
403  }
404 
405  int BSplineParametric::eval(const double** arg, double** res, casadi_int* iw, double* w) const {
406  if (!res[0]) return 0;
407 
408  casadi_clear(res[0], m_);
410  get_ptr(degree_), get_ptr(strides_), arg[1], m_, arg[0], get_ptr(lookup_mode_),
411  iw, w);
412  return 0;
413  }
414 
416  const std::vector<casadi_int>& arg,
417  const std::vector<casadi_int>& res,
418  const std::vector<bool>& arg_is_ref,
419  std::vector<bool>& res_is_ref) const {
420  casadi_int n_dims = offset_.size()-1;
421 
424  g << g.clear(g.work(res[0], m_, false), m_) << "\n";
425 
426  // Input and output buffers
427  g << "CASADI_PREFIX(nd_boor_eval)(" << g.work(res[0], m_, false) << "," << n_dims << ","
428  << g.constant(knots_) << "," << g.constant(offset_) << "," << g.constant(degree_)
429  << "," << g.constant(strides_) << "," << generate(g, arg, arg_is_ref) << "," << m_ << ","
430  << g.work(arg[0], n_dims, arg_is_ref[0]) << "," << g.constant(lookup_mode_) << ", iw, w);\n";
431  }
432 
434  const std::vector<casadi_int>& arg,
435  const std::vector<bool>& arg_is_ref) const {
436  return g.constant(coeffs_);
437  }
438 
440  const std::vector<casadi_int>& arg,
441  const std::vector<bool>& arg_is_ref) const {
442  return g.work(arg[1], dep(1).nnz(), arg_is_ref[1]);
443  }
444 
445  DM BSpline::dual(const std::vector<double>& x,
446  const std::vector< std::vector<double> >& knots,
447  const std::vector<casadi_int>& degree,
448  const Dict& opts) {
449 
450  std::vector<casadi_int> offset;
451  std::vector<double> stacked;
452  Interpolant::stack_grid(knots, offset, stacked);
453 
454  std::vector<std::string> lookup_mode;
455  auto it = opts.find("lookup_mode");
456  if (it!=opts.end()) lookup_mode = it->second;
457  std::vector<casadi_int> lookup_mode_int =
458  Interpolant::interpret_lookup_mode(lookup_mode, stacked, offset, degree, degree);
459 
460  casadi_int n_dims = degree.size();
461  casadi_int N = x.size()/n_dims;
462  casadi_assert_dev(N*n_dims==x.size());
463 
464  casadi_int coeffs_size;
465  std::vector<casadi_int> coeffs_dims, strides;
466  prepare(1, offset, degree, coeffs_size, coeffs_dims, strides);
467 
468  // Size of coefficients
469  std::vector<double> contribution(coeffs_size);
470  std::vector<casadi_int> nz(coeffs_size);
471 
472  std::vector<double> data;
473  std::vector<casadi_int> row, col;
474 
475  std::vector<double> w(n_w(degree));
476  std::vector<casadi_int> iw(n_iw(degree));
477 
478  for (casadi_int i=0;i<N;++i) {
479  std::fill(contribution.begin(), contribution.end(), 0.0);
480  casadi_int nnz = casadi_nd_boor_dual_eval(get_ptr(contribution), get_ptr(nz),
481  degree.size(), get_ptr(stacked), get_ptr(offset),
482  get_ptr(degree), get_ptr(strides), get_ptr(x)+i*n_dims, get_ptr(lookup_mode_int),
483  get_ptr(iw), get_ptr(w));
484  data.insert(data.end(), contribution.begin(), contribution.begin()+nnz);
485  col.insert(col.end(), nz.begin(), nz.begin()+nnz);
486  row.insert(row.end(), nnz, i);
487  }
488 
489  return DM(Sparsity::triplet(coeffs_size, N, col, row), data).T();
490  }
491 
492 } // namespace casadi
BSpline Node.
Definition: bspline.hpp:42
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: bspline.cpp:118
std::vector< casadi_int > lookup_mode_
Definition: bspline.hpp:76
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
Definition: bspline.cpp:378
std::vector< double > knots_
Definition: bspline.hpp:72
MX jac_cache_
Jacobian.
Definition: bspline.hpp:89
static casadi_int get_coeff_size(casadi_int m, const std::vector< casadi_int > &offset, const std::vector< casadi_int > &degree)
Definition: bspline.cpp:83
static size_t n_w(const std::vector< casadi_int > &degree)
Get required length of w field.
Definition: bspline.cpp:72
BSplineCommon(const std::vector< double > &knots, const std::vector< casadi_int > &offset, const std::vector< casadi_int > &degree, casadi_int m, const std::vector< casadi_int > &lookup_mode)
Constructor.
Definition: bspline.cpp:44
std::vector< casadi_int > degree_
Definition: bspline.hpp:74
size_t sz_w() const override
Get required length of w field.
Definition: bspline.cpp:58
std::vector< casadi_int > offset_
Definition: bspline.hpp:73
casadi_int coeffs_size_
Definition: bspline.hpp:81
std::vector< casadi_int > coeffs_dims_
Definition: bspline.hpp:80
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: bspline.cpp:415
static void prepare(casadi_int m, const std::vector< casadi_int > &offset, const std::vector< casadi_int > &degree, casadi_int &coeffs_size, std::vector< casadi_int > &coeffs_dims, std::vector< casadi_int > &strides)
Definition: bspline.cpp:90
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
Definition: bspline.cpp:387
std::vector< casadi_int > strides_
Definition: bspline.hpp:79
size_t sz_iw() const override
Get required length of iw field.
Definition: bspline.cpp:54
static size_t n_iw(const std::vector< casadi_int > &degree)
Get required length of iw field.
Definition: bspline.cpp:62
virtual MX jac_cached() const =0
casadi_int op() const override
Get the operation.
Definition: bspline.hpp:121
static MXNode * deserialize(DeserializingStream &s)
Deserialize without type information.
Definition: bspline.cpp:30
MX jac(const MX &x, const T &coeffs) const
void serialize_type(SerializingStream &s) const override
Serialize type information.
Definition: bspline.cpp:113
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: bspline.cpp:345
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
Definition: bspline.cpp:353
BSplineParametric(const MX &x, const MX &coeffs, const std::vector< double > &knots, const std::vector< casadi_int > &offset, const std::vector< casadi_int > &degree, casadi_int m, const std::vector< casadi_int > &lookup_mode)
Constructor.
Definition: bspline.cpp:164
std::string generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< bool > &arg_is_ref) const override
Generate code for the operation.
Definition: bspline.cpp:439
MX jac_cached() const override
Definition: bspline.cpp:368
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
Definition: bspline.cpp:405
static MX create(const MX &x, const MX &coeffs, const std::vector< std::vector< double > > &knots, const std::vector< casadi_int > &degree, casadi_int m, const Dict &opts)
Definition: bspline.cpp:305
std::string generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< bool > &arg_is_ref) const override
Generate code for the operation.
Definition: bspline.cpp:433
static MX create(const MX &x, const std::vector< std::vector< double > > &knots, const std::vector< double > &coeffs, const std::vector< casadi_int > &degree, casadi_int m, const Dict &opts)
Definition: bspline.cpp:268
std::vector< double > coeffs_
Definition: bspline.hpp:222
MX jac_cached() const override
Definition: bspline.cpp:357
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
Definition: bspline.cpp:395
static DM dual(const std::vector< double > &x, const std::vector< std::vector< double > > &knots, const std::vector< casadi_int > &degree, const Dict &opts)
Definition: bspline.cpp:445
BSpline(const MX &x, const std::vector< double > &knots, const std::vector< casadi_int > &offset, const std::vector< double > &coeffs, const std::vector< casadi_int > &degree, casadi_int m, const std::vector< casadi_int > &lookup_mode)
Constructor.
Definition: bspline.cpp:152
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: bspline.cpp:341
void serialize_type(SerializingStream &s) const override
Serialize type information.
Definition: bspline.cpp:108
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: bspline.cpp:143
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
Definition: bspline.cpp:349
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
std::string clear(const std::string &res, std::size_t n)
Create a fill operation.
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
casadi_int numel() const
Get the number of elements.
bool is_empty(bool both=false) const
Check if the sparsity is empty, i.e. if one of the dimensions is zero.
bool is_vector() const
Check if the matrix is a row or column vector.
casadi_int size2() const
Get the second dimension (i.e. number of columns)
casadi_int size1() const
Get the first dimension (i.e. number of rows)
std::string dim(bool with_nz=false) const
Get string representation of dimensions.
static MatType zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
static void stack_grid(const std::vector< std::vector< double > > &grid, std::vector< casadi_int > &offset, std::vector< double > &stacked)
Definition: interpolant.cpp:46
static std::vector< casadi_int > interpret_lookup_mode(const std::vector< std::string > &modes, const std::vector< double > &grid, const std::vector< casadi_int > &offset, const std::vector< casadi_int > &margin_left=std::vector< casadi_int >(), const std::vector< casadi_int > &margin_right=std::vector< casadi_int >())
Convert from (optional) lookup modes labels to enum.
static std::string lookup_mode_from_enum(casadi_int lookup_mode)
Definition: casadi_low.cpp:48
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 casadi_int offset() const
Definition: mx_node.cpp:218
MX get_bspline(const std::vector< double > &knots, const std::vector< casadi_int > &offset, const std::vector< double > &coeffs, const std::vector< casadi_int > &degree, casadi_int m, const std::vector< casadi_int > &lookup_mode) const
BSpline.
Definition: mx_node.cpp:1013
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
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.
Definition: mx_node.cpp:523
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
Definition: mx_node.cpp:222
void set_dep(const MX &dep)
Set unary dependency.
Definition: mx_node.cpp:226
MX - Matrix expression.
Definition: mx.hpp:92
MX T() const
Transpose the matrix.
Definition: mx.cpp:1029
void get_nz(MX &m, bool ind1, const Slice &kk) const
Definition: mx.cpp:390
Matrix< Scalar > T() const
Transpose the matrix.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
Class representing a Slice.
Definition: slice.hpp:48
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Definition: sparsity.cpp:1012
static Sparsity triplet(casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, std::vector< casadi_int > &mapping, bool invert_mapping)
Create a sparsity pattern given the nonzeros in sparse triplet form *.
Definition: sparsity.cpp:1127
The casadi namespace.
Definition: archiver.cpp:28
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
double if_else_zero(double x, double y)
Conditional assignment.
Definition: calculus.hpp:289
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
Matrix< double > DM
Definition: dm_fwd.hpp:33
void get_boor(const MX &x, const MX &knots, casadi_int degree, casadi_int lookup_mode, MX &start, MX &boor)
Definition: bspline.cpp:177
void casadi_clear(T1 *x, casadi_int n)
CLEAR: x <- 0.
MX do_inline(const MX &x, const std::vector< std::vector< double > > &knots, const MX &coeffs, casadi_int m, const std::vector< casadi_int > &degree, const std::vector< casadi_int > &lookup_mode)
Definition: bspline.cpp:211
void casadi_nd_boor_eval(T1 *ret, casadi_int n_dims, const T1 *knots, const casadi_int *offset, const casadi_int *degree, const casadi_int *strides, const T1 *c, casadi_int m, const T1 *x, const casadi_int *lookup_mode, casadi_int *iw, T1 *w)