26 #include "blazing_spline_impl.hpp"
27 #include "interpolant_impl.hpp"
28 #include "bspline_impl.hpp"
29 #include "casadi_misc.hpp"
30 #include "serializer.hpp"
39 const std::vector< std::vector<double> >& knots,
65 casadi_assert_dev(
false);
77 casadi_assert_dev(
false);
92 casadi_assert_dev(
false);
104 casadi_assert_dev(
false);
110 const std::vector< std::vector<double> >& knots,
111 casadi_int diff_order) :
FunctionInternal(name), diff_order_(diff_order), knots_(knots) {
115 casadi_assert(knots.size()>=1,
"blazing_spline only defined for 1D/2D/3D");
116 casadi_assert(knots.size()<=3,
"blazing_spline only defined for 1D/2D/3D");
122 for (
const auto& e :
knots_) {
128 for (casadi_int k=0;k<
knots_.size();++k) {
130 for (casadi_int i=0;i<
knots_.size();++i) {
131 ndc *=
knots_[i].size() - 4 - (i==k);
137 for (casadi_int k=0;k<
knots_.size();++k) {
138 for (casadi_int kk=0;kk<
knots_.size();++kk) {
140 for (casadi_int i=0;i<
knots_.size();++i) {
141 ndc *=
knots_[i].size() - 4 - (i==k)-(i==kk);
151 std::vector<casadi_int> offset;
152 std::vector<double> stacked;
166 casadi_int n_dims =
knots_.size();
193 std::vector<std::string> lookup_mode;
194 std::vector<casadi_int> degree(3,
knots_.size());
195 std::vector<casadi_int> mode =
199 std::string fun_name =
"casadi_blazing_" +
str(
knots_.size()) +
"d_boor_eval";
203 g << fun_name +
"(res[0], 0, 0, " +
204 knots_stacked +
", " +
205 knots_offset +
", " +
212 g << fun_name +
"(res[0], res[1], 0, " +
213 knots_stacked +
", " +
214 knots_offset +
", " +
215 "arg[1], arg[2], 0, " +
221 g << fun_name +
"(res[0], res[1], res[2], " +
222 knots_stacked +
", " +
223 knots_offset +
", " +
224 "arg[1], arg[2], arg[3], " +
229 casadi_assert_dev(
false);
238 const std::vector<std::string>& inames,
239 const std::vector<std::string>& onames,
240 const Dict& opts)
const {
245 std::vector<casadi_int> coeffs_dims(N+1);
247 for (casadi_int i=0; i<N; ++i) {
248 coeffs_dims[i+1] =
knots_[i].size()-4;
251 std::vector<casadi_int> degree(N, 3);
252 std::vector< std::vector< std::vector<double> > > knots_d(N);
253 std::vector< std::vector< casadi_int> > degree_d(N);
256 for (
size_t i=0;i<N;++i) {
262 MX dC = vertcat(dCv);
267 Jopts[
"derivative_of"] =
self();
269 std::string fJname =
name_ +
"_der";
279 std::vector<MX> ret = fJ(std::vector<MX>{x,
C, dC});
283 {ret[1],
MX(1,
nc_)},
286 {{
"always_inline",
true}});
292 int size0 =
knots_[0].size();
293 int size1 =
knots_[1].size();
294 int size2 =
knots_[2].size();
295 std::vector<casadi_int> offset;
296 std::vector<double> stacked;
297 std::vector< std::vector<double> > knots_dummy;
298 std::vector< casadi_int> degree_dummy;
301 {1, size0-5, size1-4, size2-4}, dCv[0], knots_dummy, degree_dummy);
304 {1, size0-4, size1-5, size2-4}, dCv[1], knots_dummy, degree_dummy);
307 {1, size0-4, size1-4, size2-5}, dCv[2], knots_dummy, degree_dummy);
310 {1, size0-5, size1-4, size2-4}, dCv[0], knots_dummy, degree_dummy);
313 {1, size0-4, size1-5, size2-4}, dCv[1], knots_dummy, degree_dummy);
316 {1, size0-4, size1-4, size2-5}, dCv[2], knots_dummy, degree_dummy);
317 ddC = vertcat(ddC00, ddC11, ddC22, ddC01, ddC12, ddC20);
319 int size0 =
knots_[0].size();
320 int size1 =
knots_[1].size();
321 std::vector<casadi_int> offset;
322 std::vector<double> stacked;
323 std::vector< std::vector<double> > knots_dummy;
324 std::vector< casadi_int> degree_dummy;
327 {1, size0-5, size1-4}, dCv[0], knots_dummy, degree_dummy);
330 {1, size0-4, size1-5}, dCv[1], knots_dummy, degree_dummy);
333 {1, size0-5, size1-4}, dCv[0], knots_dummy, degree_dummy);
334 ddC = vertcat(ddC00, ddC11, ddC01);
336 int size0 =
knots_[0].size();
337 std::vector<casadi_int> offset;
338 std::vector<double> stacked;
339 std::vector< std::vector<double> > knots_dummy;
340 std::vector< casadi_int> degree_dummy;
343 {1, size0-5}, dCv[0], knots_dummy, degree_dummy);
346 std::vector<MX> ret = fJ(std::vector<MX>{x,
C, dC, ddC});
350 {ret[1],
MX(1,
nc_),
MX(1,
ndc_), ret[2],
MX(N,
nc_),
MX(N,
ndc_)},
353 {{
"always_inline",
true}});
362 s.
version(
"BlazingSplineFunction", 1);
364 s.
pack(
"BlazingSplineFunction::knots",
knots_);
368 s.
version(
"BlazingSplineFunction", 1);
378 class BlazingSplineIncrementalSerializer {
381 BlazingSplineIncrementalSerializer() : serializer(ss) {
384 std::string generate_id(
const std::vector<MX>& a) {
385 ref.insert(ref.end(), a.begin(), a.end());
386 if (a.empty())
return "";
394 serializer.pack(ordered);
397 serializer.pack(ordered);
398 std::string ret = ss.str();
405 std::stringstream ss;
408 SerializingStream serializer;
412 std::vector<MX>& subs_from,
413 std::vector<MX>& subs_to)
const {
421 Function f(
"f", {}, arg, {{
"allow_free",
true}, {
"max_io", 0}});
424 std::unordered_map<std::string, std::vector<MX> > targets0;
425 std::unordered_map<std::string, std::vector<MX> > targets1;
426 std::vector<MX> targets2;
428 BlazingSplineIncrementalSerializer ss;
432 for (
int k=0; k<f.n_instructions(); ++k) {
433 MX e = f.instruction_MX(k);
438 if (fun.
class_name()==
"BlazingSplineFunction") {
439 key = ss.generate_id(e->
dep_);
442 targets0[key].push_back(e);
445 targets1[key].push_back(e);
449 targets2.push_back(e);
456 for (
const auto& e : targets2) {
462 for (
const auto& ee : targets1[key]) {
464 subs_from.push_back(ee);
466 subs_to.push_back(e);
473 for (
const auto& ee : targets0[key]) {
475 subs_from.push_back(ee);
477 subs_to.push_back(e);
482 for (
const auto& ee : targets1) {
483 for (
const auto& e : ee.second) {
488 for (
const auto& ee : targets0[key]) {
490 subs_from.push_back(ee);
492 subs_to.push_back(e);
static M derivative_coeff(casadi_int i, const std::vector< double > &knots, const std::vector< casadi_int > &offset, const std::vector< casadi_int > °ree, const std::vector< casadi_int > &coeffs_dims, const M &coeffs, std::vector< std::vector< double > > &new_knots, std::vector< casadi_int > &new_degree)
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
std::string get_name_out(casadi_int i) override
Names of function input and outputs.
std::vector< casadi_int > knots_offset_
std::vector< double > knots_stacked_
~BlazingSplineFunction() override
Destructor.
Sparsity get_sparsity_in(casadi_int i) override
Sparsities of function inputs and outputs.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
bool get_diff_in(casadi_int i) override
Which inputs are differentiable?
std::vector< std::vector< double > > knots_
bool has_jacobian() const override
Jacobian of all outputs with respect to all inputs.
size_t get_n_out() override
Number of function inputs and outputs.
BlazingSplineFunction(const std::string &name, const std::vector< std::vector< double > > &knots, casadi_int diff_order)
Constructor.
Sparsity get_sparsity_out(casadi_int i) override
Sparsities of function inputs and outputs.
Function get_jacobian(const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Jacobian of all outputs with respect to all inputs.
static const Options options_
Options.
void init(const Dict &opts) override
Initialize.
void codegen_body(CodeGenerator &g) const override
Generate code for the function body.
size_t get_n_in() override
Number of function inputs and outputs.
void init_derived_members()
std::string get_name_in(casadi_int i) override
Names of function input and outputs.
void merge(const std::vector< MX > &arg, std::vector< MX > &subs_from, std::vector< MX > &subs_to) const override
List merge opportunitities.
Helper class for C code generation.
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
void add_include(const std::string &new_include, bool relative_path=false, const std::string &use_ifdef=std::string())
Add an include file optionally using a relative path "..." instead of an absolute path <....
@ AUX_BLAZING_2D_BOOR_EVAL
@ AUX_BLAZING_1D_BOOR_EVAL
@ AUX_BLAZING_3D_BOOR_EVAL
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.
void version(const std::string &name, int v)
Internal class for Function.
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
void init(const Dict &opts) override
Initialize.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
bool incache(const std::string &fname, Function &f, const std::string &suffix="") const
Get function in cache.
static const Options options_
Options.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
void tocache(const Function &f, const std::string &suffix="") const
Save function to cache.
Function derivative_of_
If the function is the derivative of another function.
Dict generate_options(const std::string &target) const override
Reconstruct options dict.
static Function create(FunctionInternal *node)
Create from node.
static std::vector< SX > order(const std::vector< SX > &expr)
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
bool is_null() const
Is a null pointer?
static void stack_grid(const std::vector< std::vector< double > > &grid, std::vector< casadi_int > &offset, std::vector< double > &stacked)
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.
std::vector< MX > dep_
dependencies - functions that have to be evaluated before this one
bool is_call() const
Check if evaluation.
Function which_function() const
Get function - only valid when is_call() is true.
Base class for FunctionInternal and LinsolInternal.
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
std::string class_name() const
Get class name.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Function blazing_spline(const std::string &name, const std::vector< std::vector< double > > &knots, const Dict &opts)
Construct a specialized parametric BSpline.
Dict combine(const Dict &first, const Dict &second, bool recurse)
Combine two dicts. First has priority.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::vector< T > vector_init(const std::vector< T > &v)
Return all but the last element of a vector.
Options metadata for a class.