Hi,
I have a problem for using ipopt solver to solve my nlp problem. The decision variable is a 28 * 1 vector. Since my cost function is a user define function, my code is like:
first is jacobian:
============
class callbackJacobian : public casadi::Callback {
public:
// Constructor.
callbackJacobian(const std::string& name, const casadi::Dict &opts = casadi::Dict()) {
construct(name, opts);
}
// Destructor.
~callbackJacobian() override { }
// Initialize callback.
void init() override {
std::cout << "initializing callback jacobian" << std::endl;
}
// Number of inputs.
casadi_int get_n_in() override { return 2; }
// Number of outputs.
casadi_int get_n_out() override { return 1; }
// Set sparsity of input.
casadi::Sparsity get_sparsity_in(casadi_int i) override {
return casadi::Sparsity::dense(28, 1);
}
// Set sparsity of output.
casadi::Sparsity get_sparsity_out(casadi_int i) override {
return casadi::Sparsity::dense(28, 1);
}
// Evaluate numerically.
std::vector<casadi::DM> eval(const std::vector<casadi::DM>& arg) const override {
std::cout << "evaluating jacobian callback" << std::endl;
// for simple just give arbitrary value to the jacobian value
casadi::DM out(28, 1);
for (int i = 0; i <
arg.at(0).size1(); i++) {
out(i, 0) = 5;
}
return { out };
}
};
================
then the cost function:
class MyCallback : public casadi::Callback {
private:
std::shared_ptr<casadiOptim::obstacleMap> cmap_;
public:
MyCallback(const std::string& name, std::shared_ptr<casadiOptim::obstacleMap> map, const casadi::Dict& opts = casadi::Dict()):
cmap_(std::move(map)){
construct(name, opts);
}
~MyCallback() override {}
casadi_int get_n_in() override {return 1; }
casadi_int get_n_out () override {return 1; }
casadi::Sparsity get_sparsity_in(casadi_int i) override {
return casadi::Sparsity::dense(28, 1);
}
casadi::Sparsity get_sparsity_out(casadi_int i) override {
return casadi::Sparsity::dense(1, 1);
}
void init() override {
std::cout << "initializing_object! " << std::endl;
}
std::vector<casadi::DM> eval(const std::vector<casadi::DM>& arg) const override {
// for simple just let function value be 0.
casadi::DM f = 0;
return {f};
}
bool has_jacobian() const override {return true; }
casadi::Function get_jacobian(const std::string&name, const std::vector<std::string>& inames, const std::vector<std::string> &onames,
const casadi::Dict &opts) const override {
callbackJacobian cbJacobian(name);
casadi::Function jacobianFunction = cbJacobian;
return jacobianFunction;
}
};
And when I run, I get the error:
terminate called after throwing an instance of 'casadi::CasadiException'
what(): .../casadi/core/function_internal.cpp:145: Error calling IpoptInterface::init for 'F':
Error in Function::factory for 'nlp' [MXFunction] at .../casadi/core/function.cpp:1634:
Failed to create nlp_grad:[x, p, lam:f, lam:g]->[f, g, grad:gamma:x, grad:gamma:p] with {"gamma": [f, g]}:
.../casadi/core/factory.hpp:367: Gradient generation failed:
Error in MX::gradient at .../casadi/core/generic_matrix.hpp:1203:
Error in MX::jtimes at .../casadi/core/generic_matrix.hpp:1191:
Error in MX::reverse at .../casadi/core/mx.cpp:1741:
Error in MXFunction::ad_reverse at .../casadi/core/mx_function.cpp:1042:
Error in MX::ad_reverse for node of type N6casadi4CallE at .../casadi/core/mx.cpp:2044:
Error in Call::ad_reverse for 'f' [CallbackInternal] at .../casadi/core/casadi_call.cpp:147:
.../casadi/core/mx.cpp:1126: Assertion "offset.back()==x.size1()" failed:
Notify the CasADi developers.
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
And if I change the jacobian function dimension like:
// Set sparsity of output.
casadi::Sparsity get_sparsity_out(casadi_int i) override {
return casadi::Sparsity::dense(1, 28);
}
// Evaluate numerically.
std::vector<casadi::DM> eval(const std::vector<casadi::DM>& arg) const override {
std::cout << "evaluating jacobian callback" << std::endl;
casadi::DM out(1, 28);
for (int i = 0; i <
arg.at(0).size2(); i++) {
out(0, i) = 5;
}
return { out };
}
I can get the followin error:
terminate called after throwing an instance of 'casadi::CasadiException'
what(): .../casadi/core/function_internal.cpp:145: Error calling IpoptInterface::init for 'F':
Error in Function::factory for 'nlp' [MXFunction] at .../casadi/core/function.cpp:1634:
Failed to create nlp_hess_l:[x, p, lam:f, lam:g]->[hess:gamma:x:x] with {"gamma": [f, g]}:
.../casadi/core/factory.hpp:387: Hessian generation failed:
Error in MX::hessian at .../casadi/core/mx.cpp:1679:
Error in MX::jacobian at .../casadi/core/mx.cpp:1663:
Error in XFunction::jac for 'helper_jacobian_MX' [MXFunction] at .../casadi/core/x_function.hpp:719:
Error in MXFunction::ad_forward at .../casadi/core/mx_function.cpp:831:
Error in MX::ad_forward for node of type N6casadi4CallE at .../casadi/core/mx.cpp:2035:
Error in Call::ad_forward for 'jac_f' [CallbackInternal] at .../casadi/core/casadi_call.cpp:123:
.../casadi/core/function_internal.cpp:2639: Assertion "has_derivative()" failed:
Derivatives cannot be calculated for jac_f
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
So, my question is how to define a jacobian function for a user defined function. Can someone give me some examples to learn?
Thanks.