slicot_expm.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 "slicot_expm.hpp"
27 #include "slicot_layer.hpp"
28 #include "slicot_la.hpp"
29 
30 #include "../../core/casadi_misc.hpp"
31 #include "../../core/mx_function.hpp"
32 #include "../../core/sx_function.hpp"
33 
34 #include <cassert>
35 #include <ctime>
36 #include <numeric>
37 
38 namespace casadi {
39 
40  extern "C"
41  int CASADI_EXPM_SLICOT_EXPORT
42  casadi_register_expm_slicot(Expm::Plugin* plugin) {
43  plugin->creator = SlicotExpm::creator;
44  plugin->name = "slicot";
45  plugin->doc = SlicotExpm::meta_doc.c_str();
46  plugin->version = CASADI_VERSION;
47  plugin->options = &SlicotExpm::options_;
48  return 0;
49  }
50 
51  extern "C"
52  void CASADI_EXPM_SLICOT_EXPORT casadi_load_expm_slicot() {
54  }
55 
56  SlicotExpm::SlicotExpm(const std::string& name, const Sparsity& A) : Expm(name, A) {
57 
58  }
59 
61  clear_mem();
62  }
63 
64  bool SlicotExpm::has_loaded_ = false;
65 
66  void SlicotExpm::init(const Dict& opts) {
67 
68  if (!has_loaded_) {
69  has_loaded_ = true;
70  casadi_warning("Loaded plugin with GPL license.");
71  }
72 
73  Expm::init(opts);
74 
75  n_ = A_.size1();
76 
77  alloc_w(n_*n_, true); // A
78  alloc_w(n_*n_, true); // H
79  alloc_w(2*n_*n_, false); // dwork
80  alloc_iw(2*n_, false); // iwork
81  }
82 
83 
84  void SlicotExpm::set_work(void* mem, const double**& arg, double**& res,
85  casadi_int*& iw, double*& w) const {
86  auto m = static_cast<SlicotExpmMemory*>(mem);
87 
88  // Set work in base classes
89  Expm::set_work(mem, arg, res, iw, w);
90 
91  m->A = w; w += n_*n_;
92  m->H = w; w += n_*n_;
93  m->dwork = w;
94  m->iwork = reinterpret_cast<int*>(iw);
95  }
96 
97 
99  int SlicotExpm::init_mem(void* mem) const {
100  return Expm::init_mem(mem);
101  }
102 
103  int SlicotExpm::eval(const double** arg, double** res,
104  casadi_int* iw, double* w, void* mem) const {
105  auto m = static_cast<SlicotExpmMemory*>(mem);
106 
107  setup(mem, arg, res, iw, w);
108 
109  double tol = 1e-8;
110  int ret = slicot_mb05nd(n_, arg[1][0], arg[0], n_, m->A, n_, m->H, n_,
111  tol, m->iwork, m->dwork, 2*n_*n_);
112  casadi_assert(ret==0, "Slicot mb05nd failed with status " + str(ret) + ".");
113  if (res[0]) std::copy(m->A, m->A+n_*n_, res[0]);
114  return 0;
115  }
116 
117 
118 
119 
120 } // namespace casadi
Internal class.
Definition: expm_impl.hpp:35
void init(const Dict &opts) override
Initialize.
Definition: expm.cpp:93
Sparsity A_
Definition: expm_impl.hpp:121
static const Options options_
Options.
Definition: expm_impl.hpp:63
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
virtual void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const
Set the (persistent) work vectors.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
void setup(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (persistent and temporary) work vectors.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
virtual int init_mem(void *mem) const
Initalize memory block.
void clear_mem()
Clear all memory (called from destructor)
static Expm * creator(const std::string &name, const Sparsity &A)
Create a new QP Solver.
Definition: slicot_expm.hpp:83
~SlicotExpm() override
Destructor.
Definition: slicot_expm.cpp:60
int init_mem(void *mem) const override
Initalize memory block.
Definition: slicot_expm.cpp:99
int eval(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
Evaluate numerically.
SlicotExpm()
Constructor.
void init(const Dict &opts) override
Initialize.
Definition: slicot_expm.cpp:66
static const std::string meta_doc
A documentation string.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Definition: slicot_expm.cpp:84
General sparsity class.
Definition: sparsity.hpp:106
casadi_int size1() const
Get the number of rows.
Definition: sparsity.cpp:124
The casadi namespace.
Definition: archiver.cpp:28
int CASADI_EXPM_SLICOT_EXPORT casadi_register_expm_slicot(Expm::Plugin *plugin)
Definition: slicot_expm.cpp:42
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
void CASADI_EXPM_SLICOT_EXPORT casadi_load_expm_slicot()
Definition: slicot_expm.cpp:52
int slicot_mb05nd(int n, double delta, const double *a, int lda, double *ex, int ldex, double *exint, int ldexin, double tol, int *iwork, double *dwork, int ldwork)