26 #ifndef CASADI_BSPLINE_IMPL_HPP
27 #define CASADI_BSPLINE_IMPL_HPP
29 #include "bspline.hpp"
30 #include "interpolant_impl.hpp"
31 #include "casadi_low.hpp"
36 M BSplineCommon::derivative_coeff(casadi_int i,
37 const std::vector<double>& knots,
38 const std::vector<casadi_int>& offset,
39 const std::vector<casadi_int>& degree,
40 const std::vector<casadi_int>& coeffs_dims,
const M& coeffs,
41 std::vector< std::vector<double> >& new_knots,
42 std::vector<casadi_int>& new_degree) {
43 casadi_int n_dims = degree.size();
45 casadi_int n_knots = offset[i+1]-offset[i];
46 casadi_int n = n_knots-degree[i]-1;
47 DM K = std::vector<double>(get_ptr(knots)+offset[i], get_ptr(knots)+offset[i+1]);
48 DM delta_knots = K(range(1+degree[i], n_knots-1))
49 - K(range(1, n_knots-degree[i]-1));
51 Sparsity sp_band = vertsplit(
Sparsity::band(n, -1), {0, n-1, n})[0];
52 DM delta_knots_inv = 1/delta_knots;
53 DM T =
DM(sp_diag, -delta_knots_inv) +
DM(sp_band, delta_knots_inv);
56 std::vector<casadi_int> coeffs_dims_new = coeffs_dims;
57 coeffs_dims_new[i+1] =
T.size1();
62 std::vector<casadi_int> order = range(n_dims+1);
63 std::swap(order.back(), order[i+1]);
64 std::vector<casadi_int> mapping = tensor_permute_mapping(coeffs_dims, order);
65 M coeff_matrix = coeffs.nz(mapping);
68 coeff_matrix = reshape(coeff_matrix, -1,
T.size2());
71 coeff_matrix = mtimes(coeff_matrix,
T.T());
74 mapping = tensor_permute_mapping(permute(coeffs_dims_new, order), order);
75 coeff_matrix = coeff_matrix.nz(mapping);
79 for (casadi_int k=0;k<degree.size();++k) {
82 std::vector<double>(get_ptr(knots)+offset[k]+1, get_ptr(knots)+offset[k+1]-1));
83 new_degree.push_back(degree[k]-1);
86 std::vector<double>(get_ptr(knots)+offset[k], get_ptr(knots)+offset[k+1]));
87 new_degree.push_back(degree[k]);
96 MX BSplineCommon::jac(
const MX& x,
const T& coeffs)
const {
97 casadi_int n_dims = degree_.size();
98 std::vector<MX> parts;
101 std::vector<std::string> lookup_mode;
102 for (
auto e : lookup_mode_) lookup_mode.push_back(Low::lookup_mode_from_enum(e));
103 opts[
"lookup_mode"] = lookup_mode;
106 for (casadi_int k=0;k<n_dims;++k) {
107 std::vector< std::vector<double> > knots;
108 std::vector< casadi_int> degree;
109 T dC = derivative_coeff(k, knots_, offset_, degree_, coeffs_dims_, coeffs, knots, degree);
110 MX d =
MX::bspline(x, dC, knots, degree, m_, opts);
114 return horzcat(parts);
static Sparsity band(casadi_int n, casadi_int p)
Create a single band in a square sparsity pattern.
static Sparsity diag(casadi_int nrow)
Create diagonal sparsity pattern *.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.