callback_internal.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 #include "callback_internal.hpp"
26 
27 namespace casadi {
28 
29  #define TRY_CALL(FCN, OBJ, ...) \
30  try { \
31  casadi_assert((OBJ)!=0, "Callback object has been deleted"); \
32  return (OBJ)->FCN(__VA_ARGS__);\
33  } catch (std::exception& ex) { \
34  casadi_error("Error calling \"" CASADI_STR(FCN) "\" for object " \
35  + name_ + ":\n" + std::string(ex.what())); \
36  }
37 
39  CallbackInternal(const std::string& name, Callback *self)
40  : FunctionInternal(name), self_(self), has_eval_buffer_(false) {
41  }
42 
44  clear_mem();
45  }
46 
48  TRY_CALL(get_n_in, self_);
49  }
50 
52  TRY_CALL(get_n_out, self_);
53  }
54 
56  TRY_CALL(get_sparsity_in, self_, i);
57  }
58 
60  TRY_CALL(get_sparsity_out, self_, i);
61  }
62 
63  std::string CallbackInternal::get_name_in(casadi_int i) {
64  TRY_CALL(get_name_in, self_, i);
65  }
66 
67  std::string CallbackInternal::get_name_out(casadi_int i) {
68  TRY_CALL(get_name_out, self_, i);
69  }
70 
72  TRY_CALL(has_eval_buffer, self_);
73  }
74 
75  bool CallbackInternal::has_jac_sparsity(casadi_int oind, casadi_int iind) const {
76  TRY_CALL(has_jac_sparsity, self_, oind, iind);
77  }
78 
79  Sparsity CallbackInternal::get_jac_sparsity(casadi_int oind, casadi_int iind,
80  bool symmetric) const {
81  TRY_CALL(get_jac_sparsity, self_, oind, iind, symmetric);
82  }
83 
84  void CallbackInternal::init(const Dict& opts) {
85  // Initialize the base classes
87 
88  // Initialize this
89  casadi_assert(self_!=nullptr, "Callback object has been deleted");
90  self_->init();
91  }
92 
94  // Finalize this
95  casadi_assert(self_!=nullptr, "Callback object has been deleted");
96  self_->finalize();
97 
98  // Finalize the base classes
100 
102 
103  if (has_eval_buffer_) {
104  sizes_arg_.resize(n_in_);
105  for (casadi_int i=0;i<n_in_;++i) {
106  sizes_arg_[i] = nnz_in(i);
107  }
108  sizes_res_.resize(n_out_);
109  for (casadi_int i=0;i<n_out_;++i) {
110  sizes_res_[i] = nnz_out(i);
111  }
112  }
113  }
114 
115  std::vector<DM> CallbackInternal::eval_dm(const std::vector<DM>& arg) const {
116  TRY_CALL(eval, self_, arg);
117  }
118 
120  int CallbackInternal::eval(const double** arg, double** res,
121  casadi_int* iw, double* w, void* mem) const {
122  setup(mem, arg, res, iw, w);
123  if (has_eval_dm()) {
124  return FunctionInternal::eval(arg, res, iw, w, mem);
125  } else {
126  TRY_CALL(eval_buffer, self_, arg, sizes_arg_, res, sizes_res_);
127  }
128  }
129 
131  TRY_CALL(uses_output, self_);
132  }
133 
135  TRY_CALL(has_jacobian, self_);
136  }
137 
139  get_jacobian(const std::string& name,
140  const std::vector<std::string>& inames,
141  const std::vector<std::string>& onames,
142  const Dict& opts) const {
143  TRY_CALL(get_jacobian, self_, name, inames, onames, opts);
144  }
145 
147  get_forward(casadi_int nfwd, const std::string& name,
148  const std::vector<std::string>& inames,
149  const std::vector<std::string>& onames, const Dict& opts) const {
150  TRY_CALL(get_forward, self_, nfwd, name, inames, onames, opts);
151  }
152 
153  bool CallbackInternal::has_forward(casadi_int nfwd) const {
154  TRY_CALL(has_forward, self_, nfwd);
155  }
156 
158  get_reverse(casadi_int nadj, const std::string& name,
159  const std::vector<std::string>& inames,
160  const std::vector<std::string>& onames, const Dict& opts) const {
161  TRY_CALL(get_reverse, self_, nadj, name, inames, onames, opts);
162  }
163 
164  bool CallbackInternal::has_reverse(casadi_int nadj) const {
165  TRY_CALL(has_reverse, self_, nadj);
166  }
167 } // namespace casadi
std::vector< DM > eval_dm(const std::vector< DM > &arg) const override
Evaluate with DM matrices.
void finalize() override
Finalize the object creation.
bool has_jacobian() const override
Return Jacobian of all input elements with respect to all output elements.
void init(const Dict &opts) override
Initialize.
std::string get_name_out(casadi_int i) override
Names of function input and outputs.
std::string get_name_in(casadi_int i) override
Names of function input and outputs.
size_t get_n_out() override
Number of function inputs and outputs.
Callback * self_
Pointer to the public class.
bool has_forward(casadi_int nfwd) const override
Return function that calculates forward derivatives.
std::vector< casadi_int > sizes_arg_
bool has_jac_sparsity(casadi_int oind, casadi_int iind) const override
Return sparsity of Jacobian of an output respect to an input.
Function get_jacobian(const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Return Jacobian of all input elements with respect to all output elements.
~CallbackInternal() override
Destructor.
size_t get_n_in() override
Number of function inputs and outputs.
std::vector< casadi_int > sizes_res_
bool has_eval_dm() const override
Evaluate with DM matrices.
bool uses_output() const override
Do the derivative functions need nondifferentiated outputs?
Function get_reverse(casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Return function that calculates adjoint derivatives.
Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Return function that calculates forward derivatives.
Sparsity get_sparsity_out(casadi_int i) override
Sparsities of function inputs and outputs.
virtual int eval(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
Evaluate numerically.
bool has_reverse(casadi_int nadj) const override
Return function that calculates adjoint derivatives.
Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind, bool symmetric) const override
Return sparsity of Jacobian of an output respect to an input.
Sparsity get_sparsity_in(casadi_int i) override
Sparsities of function inputs and outputs.
CallbackInternal(const std::string &name, Callback *self)
Constructor.
Callback function functionality.
Internal class for Function.
void init(const Dict &opts) override
Initialize.
void finalize() override
Finalize the object creation.
virtual int eval(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const
Evaluate numerically.
size_t n_in_
Number of inputs and outputs.
casadi_int nnz_in() const
Number of input/output nonzeros.
casadi_int nnz_out() const
Number of input/output nonzeros.
void setup(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (persistent and temporary) work vectors.
Function object.
Definition: function.hpp:60
void clear_mem()
Clear all memory (called from destructor)
General sparsity class.
Definition: sparsity.hpp:106
The casadi namespace.
Definition: archiver.cpp:28
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.