27 #include "casadi_misc.hpp"
38 int Concat::eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
39 return eval_gen<double>(arg, res, iw, w);
43 return eval_gen<SXElem>(arg, res, iw, w);
49 for (casadi_int i=0; i<
n_dep(); ++i) {
50 casadi_int n =
dep(i).
nnz();
51 std::copy(arg[i], arg[i]+n, r);
59 for (casadi_int i=0; i<
n_dep(); ++i) {
60 casadi_int n_i =
dep(i).
nnz();
61 const bvec_t *arg_i_ptr = arg[i];
62 std::copy(arg_i_ptr, arg_i_ptr+n_i, res_ptr);
70 for (casadi_int i=0; i<
n_dep(); ++i) {
71 casadi_int n_i =
dep(i).
nnz();
72 bvec_t *arg_i_ptr = arg[i];
73 for (casadi_int k=0; k<n_i; ++k) {
74 *arg_i_ptr++ |= *res_ptr;
82 const std::vector<casadi_int>& arg,
83 const std::vector<casadi_int>& res,
84 const std::vector<bool>& arg_is_ref,
85 std::vector<bool>& res_is_ref)
const {
86 g.
local(
"rr",
"casadi_real",
"*");
87 g <<
"rr=" << g.
work(res[0],
nnz(),
false) <<
";\n";
88 for (casadi_int i=0; i<arg.size(); ++i) {
89 casadi_int nz =
dep(i).
nnz();
91 g <<
"*rr++ = " << g.
workel(arg[i]) <<
";\n";
93 g.
local(
"i",
"casadi_int");
94 g.
local(
"cs",
"const casadi_real",
"*");
95 g <<
"for (i=0, " <<
"cs=" << g.
work(arg[i], nz, arg_is_ref[i]) <<
"; "
96 <<
"i<" << nz <<
"; ++i) *rr++ = *cs++;\n";
104 casadi_int nz_test = -1;
105 for (
auto&& i : nz) {
116 casadi_int begin=0, end=0;
118 for (i=0; i<
n_dep(); ++i) {
121 if (nz_test < end)
break;
125 for (
auto&& j : nz) {
126 if (j>=0 && (j < begin || j >= end)) {
137 std::vector<casadi_int> nz_new(nz);
138 for (
auto&& j : nz_new)
if (j>=0) j -= begin;
145 casadi_assert_dev(x.size()>1);
146 std::vector<Sparsity> sp(x.size());
147 for (casadi_int i=0; i<x.size(); ++i) sp[i] = x[i].
sparsity();
152 std::stringstream ss;
153 ss <<
"diagcat(" << arg.at(0);
154 for (casadi_int i=1; i<
n_dep(); ++i) ss <<
", " << arg.at(i);
160 const std::vector<bool>& unique)
const {
161 res[0] = diagcat(arg);
165 std::vector<std::vector<MX> >& fsens)
const {
166 casadi_int nfwd = fsens.size();
167 for (casadi_int d = 0; d<nfwd; ++d) fsens[d][0] = diagcat(fseed[d]);
170 std::pair<std::vector<casadi_int>, std::vector<casadi_int> >
Diagcat::off()
const {
171 std::vector<casadi_int> offset1(
n_dep()+1, 0);
172 std::vector<casadi_int> offset2(
n_dep()+1, 0);
173 for (casadi_int i=0; i<
n_dep(); ++i) {
176 offset2[i+1] = offset2[i] + ncol;
177 offset1[i+1] = offset1[i] + nrow;
179 return std::make_pair(offset1, offset2);
183 std::vector<std::vector<MX> >& asens)
const {
188 casadi_int nadj = aseed.size();
189 for (casadi_int d=0; d<nadj; ++d) {
190 std::vector<MX> s = diagsplit(aseed[d][0],
off.first,
off.second);
191 for (casadi_int i=0; i<
n_dep(); ++i) {
198 casadi_assert_dev(x.size()>1);
199 std::vector<Sparsity> sp(x.size());
200 for (casadi_int i=0; i<x.size(); ++i)
206 std::stringstream ss;
207 ss <<
"horzcat(" << arg.at(0);
208 for (casadi_int i=1; i<
n_dep(); ++i) ss <<
", " << arg.at(i);
214 const std::vector<bool>& unique)
const {
215 res[0] = horzcat(arg);
219 std::vector<std::vector<MX> >& fsens)
const {
220 casadi_int nfwd = fsens.size();
221 for (casadi_int d = 0; d<nfwd; ++d) {
222 fsens[d][0] = horzcat(fseed[d]);
227 std::vector<casadi_int> col_offset(
n_dep()+1, 0);
228 for (casadi_int i=0; i<
n_dep(); ++i) {
230 col_offset[i+1] = col_offset[i] + ncol;
236 std::vector<std::vector<MX> >& asens)
const {
238 std::vector<casadi_int> col_offset =
off();
241 casadi_int nadj = aseed.size();
242 for (casadi_int d=0; d<nadj; ++d) {
243 std::vector<MX> s = horzsplit(aseed[d][0], col_offset);
244 for (casadi_int i=0; i<
n_dep(); ++i) {
251 casadi_assert_dev(x.size()>1);
252 std::vector<Sparsity> sp(x.size());
253 for (casadi_int i=0; i<x.size(); ++i) sp[i] = x[i].
sparsity();
258 std::stringstream ss;
259 ss <<
"vertcat(" << arg.at(0);
260 for (casadi_int i=1; i<
n_dep(); ++i) ss <<
", " << arg.at(i);
266 const std::vector<bool>& unique)
const {
267 res[0] = vertcat(arg);
271 std::vector<std::vector<MX> >& fsens)
const {
272 casadi_int nfwd = fsens.size();
273 for (casadi_int d = 0; d<nfwd; ++d) {
274 fsens[d][0] = vertcat(fseed[d]);
279 std::vector<casadi_int> row_offset(
n_dep()+1, 0);
280 for (casadi_int i=0; i<
n_dep(); ++i) {
282 row_offset[i+1] = row_offset[i] + nrow;
288 std::vector<std::vector<MX> >& asens)
const {
290 std::vector<casadi_int> row_offset =
off();
293 casadi_int nadj = aseed.size();
294 for (casadi_int d=0; d<nadj; ++d) {
295 std::vector<MX> s = vertsplit(aseed[d][0], row_offset);
296 for (casadi_int i=0; i<
n_dep(); ++i) {
303 for (casadi_int i=0; i<
n_dep(); ++i) {
310 casadi_int nprim = 0;
311 for (casadi_int i=0; i<
n_dep(); ++i) {
319 std::vector<T> s = horzsplit(x,
off());
320 for (casadi_int i=0; i<s.size(); ++i) {
326 split_primitives_gen<MX>(x, it);
330 split_primitives_gen<SX>(x, it);
334 split_primitives_gen<DM>(x, it);
339 std::vector<T> s(
n_dep());
340 for (casadi_int i=0; i<s.size(); ++i) {
347 return join_primitives_gen<MX>(it);
351 return join_primitives_gen<SX>(it);
355 return join_primitives_gen<DM>(it);
360 std::vector<T> s = vertsplit(x,
off());
361 for (casadi_int i=0; i<s.size(); ++i) {
368 std::vector<T> s(
n_dep());
369 for (casadi_int i=0; i<s.size(); ++i) {
376 split_primitives_gen<MX>(x, it);
380 split_primitives_gen<SX>(x, it);
384 split_primitives_gen<DM>(x, it);
388 return join_primitives_gen<MX>(it);
392 return join_primitives_gen<SX>(it);
396 return join_primitives_gen<DM>(it);
401 std::pair<std::vector<casadi_int>, std::vector<casadi_int> >
off = this->
off();
402 std::vector<T> s = diagsplit(x,
off.first,
off.second);
403 for (casadi_int i=0; i<s.size(); ++i) {
410 std::vector<T> s(
n_dep());
411 for (casadi_int i=0; i<s.size(); ++i) {
418 split_primitives_gen<MX>(x, it);
422 split_primitives_gen<SX>(x, it);
426 split_primitives_gen<DM>(x, it);
430 return join_primitives_gen<MX>(it);
434 return join_primitives_gen<SX>(it);
438 return join_primitives_gen<DM>(it);
443 for (casadi_int i=0; i<
n_dep(); ++i) {
450 for (casadi_int i=0; i<
n_dep(); ++i) {
456 for (casadi_int i=0; i<
n_dep(); ++i) {
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
std::string workel(casadi_int n) const
Concatenation: Join multiple expressions stacking the nonzeros.
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
~Concat() override=0
Destructor.
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
bool has_duplicates() const override
Detect duplicate symbolic expressions.
void reset_input() const override
Reset the marker for an input expression.
MX get_nzref(const Sparsity &sp, const std::vector< casadi_int > &nz, bool unique=false) const override
Get the nonzeros of matrix.
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
casadi_int n_primitives() const override
Get the number of symbolic primitives.
void primitives(std::vector< MX >::iterator &it) const override
Get symbolic primitives.
bool is_valid_input() const override
Check if valid function input.
int eval_gen(const T *const *arg, T *const *res, casadi_int *iw, T *w) const
Evaluate the function (template)
Concat(const std::vector< MX > &x)
Constructor.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Diagcat(const std::vector< MX > &x)
Constructor.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
std::pair< std::vector< casadi_int >, std::vector< casadi_int > > off() const
Get offsets for split.
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
static MX zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
std::vector< casadi_int > off() const
Get offsets for split.
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
Horzcat(const std::vector< MX > &x)
Constructor.
virtual MX get_nzref(const Sparsity &sp, const std::vector< casadi_int > &nz, bool unique=false) const
Get the nonzeros of matrix.
virtual void reset_input() const
Reset the marker for an input expression.
virtual casadi_int n_primitives() const
Get the number of symbolic primitives.
virtual bool has_duplicates() const
Detect duplicate symbolic expressions.
virtual bool is_valid_input() const
Check if valid function input.
virtual MX join_primitives(std::vector< MX >::const_iterator &it) const
Join an expression along symbolic primitives.
const Sparsity & sparsity() const
Get the sparsity.
casadi_int nnz(casadi_int i=0) const
const MX & dep(casadi_int ind=0) const
dependencies - functions that have to be evaluated before this one
casadi_int n_dep() const
Number of dependencies.
virtual void primitives(std::vector< MX >::iterator &it) const
Get symbolic primitives.
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
void set_dep(const MX &dep)
Set unary dependency.
virtual void split_primitives(const MX &x, std::vector< MX >::iterator &it) const
Split up an expression along symbolic primitives.
const Sparsity & sparsity() const
Get the sparsity pattern.
Sparse matrix class. SX and DM are specializations.
The basic scalar symbolic class of CasADi.
casadi_int size1() const
Get the number of rows.
casadi_int size2() const
Get the number of columns.
Vertcat(const std::vector< MX > &x)
Constructor.
std::vector< casadi_int > off() const
Get offsets for split.
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
void split_primitives_gen(const T &x, typename std::vector< T >::iterator &it) const
Split up an expression along primitives (template)
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
void split_primitives(const MX &x, std::vector< MX >::iterator &it) const override
Split up an expression along symbolic primitives.
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
T join_primitives_gen(typename std::vector< T >::const_iterator &it) const
Join an expression along symbolic primitives (template)
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
MX join_primitives(std::vector< MX >::const_iterator &it) const override
Join an expression along symbolic primitives.
unsigned long long bvec_t