26 #ifndef CASADI_GENERIC_MATRIX_HPP
27 #define CASADI_GENERIC_MATRIX_HPP
30 #include "submatrix.hpp"
31 #include "nonzeros.hpp"
32 #include "sparsity.hpp"
33 #include "calculus.hpp"
34 #include "sparsity_interface.hpp"
35 #include "generic_type.hpp"
74 template<
typename MatType>
77 public SWIG_IF_ELSE(SparsityInterfaceCommon, SparsityInterface<MatType>) {
78 using SparsityInterface<MatType>::self;
84 casadi_int
nnz()
const;
131 std::string
dim(
bool with_nz=
false)
const;
136 std::pair<casadi_int, casadi_int>
size()
const;
141 casadi_int
size(casadi_int axis)
const;
213 static MatType
interp1d(
const std::vector<double>& x,
const MatType &v,
214 const std::vector<double>& xq,
const std::string& mode,
bool equidistant);
215 static casadi_int sprank(
const MatType &x) {
return Sparsity::sprank(x.sparsity());}
216 static casadi_int norm_0_mul(
const MatType &x,
const MatType &y) {
217 return Sparsity::norm_0_mul(x.sparsity(), y.sparsity());
219 static MatType tril(
const MatType &x,
bool includeDiagonal=
true) {
220 return project(x, Sparsity::tril(x.sparsity(), includeDiagonal));
222 static MatType triu(
const MatType &x,
bool includeDiagonal=
true) {
223 return project(x, Sparsity::triu(x.sparsity(), includeDiagonal));
225 static MatType
sumsqr(
const MatType &x) {
return dot(x, x);}
226 static MatType
linspace(
const MatType &a,
const MatType &b, casadi_int nsteps);
227 static MatType
cross(
const MatType &a,
const MatType &b, casadi_int
dim=-1);
228 static MatType
skew(
const MatType &a);
229 static MatType
inv_skew(
const MatType &a);
230 static MatType
tril2symm(
const MatType &x);
231 static MatType
triu2symm(
const MatType &x);
232 static MatType
repsum(
const MatType &x, casadi_int n, casadi_int m=1);
233 static MatType
diff(
const MatType &x, casadi_int n=1, casadi_int axis=-1);
235 static bool is_linear(
const MatType &expr,
const MatType &var);
236 static bool is_quadratic(
const MatType &expr,
const MatType &var);
238 MatType& A, MatType& b, MatType& c,
bool check);
239 static void linear_coeff(
const MatType &expr,
const MatType &var,
240 MatType& A, MatType& b,
bool check);
248 const MatType nz(
const K& k)
const {
250 self().get_nz(ret,
false, k);
258 NonZeros<MatType, K> nz(
const K& k) {
259 return NonZeros<MatType, K>(
self(), k);
265 template<
typename RR>
266 const MatType operator()(
const RR& rr)
const {
268 self().get(ret,
false, rr);
275 template<
typename RR,
typename CC>
276 const MatType operator()(
const RR& rr,
const CC& cc)
const {
278 self().get(ret,
false, rr, cc);
285 template<
typename RR>
286 SubIndex<MatType, RR> operator()(
const RR& rr) {
287 return SubIndex<MatType, RR>(
self(), rr);
293 template<
typename RR,
typename CC>
294 SubMatrix<MatType, RR, CC> operator()(
const RR& rr,
const CC& cc) {
295 return SubMatrix<MatType, RR, CC>(
self(), rr, cc);
299 #if !defined(SWIG) || defined(DOXYGEN)
311 inline friend MatType
interp1d(
const std::vector<double>& x,
const MatType&v,
312 const std::vector<double>& xq,
const std::string& mode,
bool equidistant=
false) {
313 return MatType::interp1d(x, v, xq, mode, equidistant);
319 inline friend MatType
mpower(
const MatType& x,
const MatType& n) {
320 return MatType::mpower(x, n);
334 inline friend MatType
soc(
const MatType& x,
const MatType& y) {
335 return MatType::soc(x, y);
354 inline friend MatType
355 einstein(
const MatType &A,
const MatType &B,
const MatType &C,
356 const std::vector<casadi_int>& dim_a,
const std::vector<casadi_int>& dim_b,
357 const std::vector<casadi_int>& dim_c,
358 const std::vector<casadi_int>& a,
const std::vector<casadi_int>& b,
359 const std::vector<casadi_int>& c) {
360 return MatType::einstein(A, B,
C, dim_a, dim_b, dim_c, a, b, c);
363 inline friend MatType
365 const std::vector<casadi_int>& dim_a,
const std::vector<casadi_int>& dim_b,
366 const std::vector<casadi_int>& dim_c,
367 const std::vector<casadi_int>& a,
const std::vector<casadi_int>& b,
368 const std::vector<casadi_int>& c) {
369 return MatType::einstein(A, B, dim_a, dim_b, dim_c, a, b, c);
376 inline friend MatType
mrdivide(
const MatType& x,
const MatType& n) {
377 return MatType::mrdivide(x, n);
383 inline friend MatType
mldivide(
const MatType& x,
const MatType& n) {
384 return MatType::mldivide(x, n);
393 inline friend std::vector<MatType>
symvar(
const MatType& x) {
394 return MatType::symvar(x);
403 inline friend MatType
bilin(
const MatType &A,
const MatType &x,
const MatType &y) {
404 return MatType::bilin(A, x, y);
406 inline friend MatType
bilin(
const MatType &A,
const MatType &x) {
407 return MatType::bilin(A, x, x);
409 static MatType
bilin(
const MatType& A,
const MatType& x,
const MatType& y);
418 inline friend MatType
rank1(
const MatType &A,
const MatType &alpha,
419 const MatType &x,
const MatType &y) {
420 return MatType::rank1(A, alpha, x, y);
422 static MatType
rank1(
const MatType& A,
const MatType& alpha,
423 const MatType& x,
const MatType& y);
429 inline friend MatType
sumsqr(
const MatType &x) {
430 return MatType::sumsqr(x);
444 return MatType::logsumexp(x);
451 inline friend MatType
logsumexp(
const MatType& x,
const MatType& margin) {
452 MatType alpha = log(x.size1()) / margin;
453 return MatType::logsumexp(alpha*x)/alpha;
460 inline friend MatType
linspace(
const MatType &a,
const MatType &b, casadi_int nsteps) {
461 return MatType::linspace(a, b, nsteps);
467 inline friend MatType
cross(
const MatType &a,
const MatType &b, casadi_int
dim = -1) {
468 return MatType::cross(a, b,
dim);
474 inline friend MatType
skew(
const MatType &a) {
475 return MatType::skew(a);
482 return MatType::inv_skew(a);
488 inline friend MatType
det(
const MatType& A) {
return MatType::det(A);}
493 inline friend MatType
det(
const MatType& A,
const std::string& lsolver,
495 return MatType::det(A, lsolver, dict);
501 inline friend MatType
inv_minor(
const MatType& A) {
return MatType::inv_minor(A);}
506 inline friend MatType
inv(
const MatType& A) {
507 return MatType::inv(A);
513 inline friend MatType
inv(
const MatType& A,
514 const std::string& lsolver,
516 return MatType::inv(A, lsolver, options);
522 inline friend MatType
trace(
const MatType& x) {
return MatType::trace(x);}
527 inline friend MatType
tril2symm(
const MatType &a) {
return MatType::tril2symm(a);}
532 inline friend MatType
triu2symm(
const MatType &a) {
return MatType::triu2symm(a);}
537 inline friend MatType
norm_fro(
const MatType &x) {
return MatType::norm_fro(x);}
542 inline friend MatType
norm_2(
const MatType &x) {
return MatType::norm_2(x);}
547 inline friend MatType
norm_1(
const MatType &x) {
return MatType::norm_1(x);}
552 inline friend MatType
norm_inf(
const MatType &x) {
return MatType::norm_inf(x);}
557 inline friend MatType
diff(
const MatType &x, casadi_int n=1, casadi_int axis=-1) {
558 return MatType::diff(x, n, axis);
564 inline friend MatType
cumsum(
const MatType &x, casadi_int axis=-1) {
565 return MatType::cumsum(x, axis);
573 inline friend MatType
dot(
const MatType &x,
const MatType &y) {
574 return MatType::dot(x, y);
588 return MatType::nullspace(A);
594 inline friend MatType
polyval(
const MatType& p,
const MatType& x) {
595 return MatType::polyval(p, x);
604 inline friend MatType
diag(
const MatType &A) {
605 return MatType::diag(A);
611 inline friend MatType
unite(
const MatType& A,
const MatType& B) {
612 return MatType::unite(A, B);
618 inline friend MatType
densify(
const MatType& x) {
619 return MatType::densify(x);
625 inline friend MatType
densify(
const MatType& x,
const MatType& val) {
626 return MatType::densify(x, val);
635 bool intersect=
false) {
636 return MatType::project(A, sp, intersect);
644 inline friend MatType
if_else(
const MatType &cond,
const MatType &if_true,
645 const MatType &if_false,
bool short_circuit=
false) {
646 return MatType::if_else(cond, if_true, if_false, short_circuit);
655 inline friend MatType
conditional(
const MatType& ind,
const std::vector<MatType> &x,
656 const MatType &x_default,
bool short_circuit=
false) {
657 return MatType::conditional(ind, x, x_default, short_circuit);
673 inline friend bool depends_on(
const MatType& f,
const MatType &arg) {
674 return MatType::depends_on(f, arg);
693 inline friend bool contains(
const std::vector<MatType>& v,
const MatType &n) {
697 inline friend bool contains_all(
const std::vector<MatType>& v,
const std::vector<MatType> &n) {
698 return MatType::contains_all(v, n);
701 inline friend bool contains_any(
const std::vector<MatType>& v,
const std::vector<MatType> &n) {
702 return MatType::contains_any(v, n);
709 friend inline MatType
substitute(
const MatType& ex,
const MatType& v,
710 const MatType& vdef) {
711 return MatType::substitute(ex, v, vdef);
717 friend inline std::vector<MatType>
718 substitute(
const std::vector<MatType>& ex,
const std::vector<MatType>& v,
719 const std::vector<MatType>& vdef) {
720 return MatType::substitute(ex, v, vdef);
731 std::vector<MatType>& inout_vdef,
732 std::vector<MatType>& inout_ex,
bool reverse=
false) {
733 return MatType::substitute_inplace(v, inout_vdef, inout_ex,
reverse);
739 inline friend MatType
cse(
const MatType& e) {
740 return MatType::cse({e}).at(0);
747 inline friend std::vector<MatType>
cse(
const std::vector<MatType>& e) {
748 return MatType::cse(e);
769 friend inline MatType
solve(
const MatType& A,
const MatType& b) {
771 if (A.is_scalar())
return b/A;
772 return MatType::solve(A, b);
778 friend inline MatType
solve(
const MatType& A,
const MatType& b,
779 const std::string& lsolver,
782 if (A.is_scalar())
return b/A;
783 return MatType::solve(A, b, lsolver, dict);
786 #ifdef WITH_DEPRECATED_FEATURES
803 friend inline MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
805 return MatType::linearize(f, x, x0, opts);
821 friend inline MatType
pinv(
const MatType& A) {
822 return MatType::pinv(A);
831 friend inline MatType
pinv(
const MatType& A,
const std::string& lsolver,
833 return MatType::pinv(A, lsolver, dict);
846 friend inline MatType
expm_const(
const MatType& A,
const MatType& t) {
847 return MatType::expm_const(A, t);
854 friend inline MatType
expm(
const MatType& A) {
855 return MatType::expm(A);
863 inline friend MatType
jacobian(
const MatType &ex,
const MatType &arg,
865 return MatType::jacobian(ex, arg, opts);
876 inline friend MatType
gradient(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
877 return MatType::gradient(ex, arg, opts);
883 inline friend MatType
tangent(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
884 return MatType::tangent(ex, arg, opts);
896 friend inline MatType
jtimes(
const MatType &ex,
const MatType &arg,
897 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict()) {
898 return MatType::jtimes(ex, arg, v, tr, opts);
904 friend inline std::vector<std::vector<MatType> >
905 forward(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
906 const std::vector<std::vector<MatType> > &v,
908 return MatType::forward(ex, arg, v, opts);
914 friend inline std::vector<std::vector<MatType> >
915 reverse(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
916 const std::vector<std::vector<MatType> > &v,
918 return MatType::reverse(ex, arg, v, opts);
925 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg,
927 return MatType::hessian(ex, arg, opts);
929 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg, MatType& output_g,
931 return MatType::hessian(ex, arg, output_g, opts);
938 inline friend std::vector<bool>
which_depends(
const MatType &expr,
const MatType &var,
939 casadi_int order,
bool tr) {
940 return MatType::which_depends(expr, var, order, tr);
949 return MatType::jacobian_sparsity(f, x);
959 inline friend bool is_linear(
const MatType &expr,
const MatType &var) {
960 return MatType::is_linear(expr, var);
970 inline friend bool is_quadratic(
const MatType &expr,
const MatType &var) {
971 return MatType::is_quadratic(expr, var);
985 MatType& A, MatType& b, MatType& c,
bool check=
true) {
986 MatType::quadratic_coeff(expr, var, A, b, c, check);
997 inline friend void linear_coeff(
const MatType &expr,
const MatType &var,
998 MatType& A, MatType& b,
bool check=
true) {
999 MatType::linear_coeff(expr, var, A, b, check);
1034 MatType& SWIG_OUTPUT(expr_ret),
1035 std::vector<MatType>& SWIG_OUTPUT(symbols),
1036 std::vector<MatType>& SWIG_OUTPUT(parametric),
1038 MatType::extract_parametric(expr, par, expr_ret, symbols, parametric, opts);
1042 std::vector<MatType>& SWIG_OUTPUT(expr_ret),
1043 std::vector<MatType>& SWIG_OUTPUT(symbols),
1044 std::vector<MatType>& SWIG_OUTPUT(parametric),
1047 MatType expr_cat = veccat(expr);
1048 MatType expr_ret_cat;
1051 MatType::extract_parametric(expr_cat, par, expr_ret_cat, symbols, parametric, opts);
1054 std::vector<casadi_int> edges = {0};
1055 for (
const MatType& e : expr) {
1056 edges.push_back(edges.back() + e.numel());
1059 std::vector<MatType> expr_ret_catv = MatType::vertsplit(expr_ret_cat, edges);
1062 expr_ret.resize(expr_ret_catv.size());
1063 for (casadi_int i=0; i<expr_ret_catv.size(); ++i) {
1064 expr_ret[i] = reshape(expr_ret_catv[i], expr[i].
size1(), expr[i].
size2());
1069 const std::vector<MatType>& par,
1070 std::vector<MatType>& SWIG_OUTPUT(expr_ret),
1071 std::vector<MatType>& SWIG_OUTPUT(symbols),
1072 std::vector<MatType>& SWIG_OUTPUT(parametric),
1078 MatType& SWIG_OUTPUT(expr_ret),
1079 std::vector<MatType>& SWIG_OUTPUT(symbols),
1080 std::vector<MatType>& SWIG_OUTPUT(parametric),
1113 const MatType &sym_lin,
const MatType &sym_const,
1114 MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1115 MatType::separate_linear(expr, sym_lin, sym_const, expr_const, expr_lin, expr_nonlin);
1119 const std::vector<MatType> &sym_lin,
const std::vector<MatType> &sym_const,
1120 MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1122 expr_const, expr_lin, expr_nonlin);
1126 inline friend casadi_int
n_nodes(
const MatType& A) {
1127 return MatType::n_nodes(A);
1132 return MatType::simplify(x);
1138 return MatType::transform(x, opts);
1141 const std::vector<std::vector<GenericType> >& passes,
const Dict& opts =
Dict()) {
1142 return MatType::transform(x, passes, opts);
1144 friend inline std::vector<MatType>
transform(
const std::vector<MatType> &x,
1146 return MatType::transform(x, opts);
1148 friend inline std::vector<MatType>
transform(
const std::vector<MatType> &x,
1149 const std::vector<std::vector<GenericType> >& passes,
const Dict& opts =
Dict()) {
1150 return MatType::transform(x, passes, opts);
1157 inline friend std::string
1159 return MatType::print_operator(xb, args);
1165 inline friend void extract(std::vector<MatType>& ex,
1166 std::vector<MatType>& v,
1167 std::vector<MatType>& vdef,
1169 MatType::extract(ex, v, vdef, opts);
1175 inline friend void shared(std::vector<MatType>& ex,
1176 std::vector<MatType>& v,
1177 std::vector<MatType>& vdef,
1178 const std::string& v_prefix=
"v_",
1179 const std::string& v_suffix=
"") {
1180 return MatType::shared(ex, v, vdef, v_prefix, v_suffix);
1186 inline friend MatType
repsum(
const MatType &A, casadi_int n, casadi_int m=1) {
1187 return MatType::repsum(A, n, m);
1194 friend inline MatType
mmin(
const MatType& x) {
1195 return MatType::mmin(x);
1203 friend inline MatType
mmax(
const MatType& x) {
1204 return MatType::mmax(x);
1210 static MatType
jtimes(
const MatType &ex,
const MatType &arg,
1211 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict());
1214 static MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
1216 static MatType
mpower(
const MatType &x,
const MatType &y);
1217 static MatType
soc(
const MatType &x,
const MatType &y);
1233 static MatType
sym(
const std::string& name, casadi_int nrow=1, casadi_int ncol=1) {
1240 static MatType
sym(
const std::string& name,
const std::pair<casadi_int, casadi_int> &rc) {
1241 return sym(name, rc.first, rc.second);
1248 return MatType::_sym(name, sp);
1256 static std::vector<MatType >
sym(
const std::string& name,
const Sparsity& sp, casadi_int p);
1261 static std::vector<MatType >
sym(
const std::string& name, casadi_int nrow,
1262 casadi_int ncol, casadi_int p) {
1271 static std::vector<std::vector<MatType> >
1272 sym(
const std::string& name,
const Sparsity& sp, casadi_int p, casadi_int r);
1279 static std::vector<std::vector<MatType> >
1280 sym(
const std::string& name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r) {
1289 static MatType
zeros(casadi_int nrow=1, casadi_int ncol=1) {
1293 static MatType
zeros(
const std::pair<casadi_int, casadi_int>& rc) {
1294 return zeros(rc.first, rc.second);
1302 static MatType
ones(casadi_int nrow=1, casadi_int ncol=1) {
1306 static MatType
ones(
const std::pair<casadi_int, casadi_int>& rc) {
1307 return ones(rc.first, rc.second);
1313 #define CASADI_THROW_ERROR(FNAME, WHAT) \
1314 throw CasadiException("Error in " + MatType::type_name() \
1315 + "::" FNAME " at " + CASADI_WHERE + ":\n" + std::string(WHAT));
1319 template<
typename MatType>
1321 return self().sparsity();
1324 template<
typename MatType>
1326 return sparsity().nnz();
1329 template<
typename MatType>
1331 return sparsity().nnz_lower();
1334 template<
typename MatType>
1336 return sparsity().nnz_upper();
1339 template<
typename MatType>
1341 return sparsity().nnz_diag();
1344 template<
typename MatType>
1346 return sparsity().numel();
1349 template<
typename MatType>
1351 return sparsity().size1();
1354 template<
typename MatType>
1356 return sparsity().size2();
1359 template<
typename MatType>
1361 return sparsity().size();
1364 template<
typename MatType>
1366 return sparsity().size(axis);
1369 template<
typename MatType>
1371 return sparsity().dim(with_nz);
1374 template<
typename MatType>
1376 return sparsity().is_scalar(scalar_and_dense);
1381 template<
typename MatType>
1383 const Sparsity& sp, casadi_int p) {
1384 std::vector<MatType> ret(p);
1385 std::stringstream ss;
1386 for (casadi_int k=0; k<p; ++k) {
1389 ret[k] = sym(ss.str(), sp);
1394 template<
typename MatType>
1398 std::vector<std::vector<MatType> > ret(r);
1399 for (casadi_int k=0; k<r; ++k) {
1400 std::stringstream ss;
1401 ss << name <<
"_" << k;
1402 ret[k] = sym(ss.str(), sp, p);
1407 template<
typename MatType>
1409 std::vector<MatType> ret(nsteps);
1411 MatType step = (b-a)/
static_cast<MatType
>(nsteps-1);
1413 for (casadi_int i=1; i<nsteps-1; ++i)
1414 ret[i] = a + i * step;
1417 return vertcat(ret);
1420 template<
typename MatType>
1422 casadi_assert(a.size1()==b.size1() && a.size2()==b.size2(),
1423 "cross(a, b): Inconsistent dimensions. Dimension of a ("
1424 + a.dim() +
" ) must equal that of b (" + b.dim() +
").");
1426 casadi_assert(a.size1()==3 || a.size2()==3,
1427 "cross(a, b): One of the dimensions of a should have length 3, but got "
1429 casadi_assert(dim==-1 || dim==1 || dim==2,
1430 "cross(a, b, dim): Dim must be 1, 2 or -1 (automatic).");
1432 std::vector<MatType> ret(3);
1434 bool t = a.size1()==3;
1436 if (dim==1) t =
true;
1437 if (dim==2) t =
false;
1439 MatType a1 = t ? a(0, Slice()) : a(Slice(), 0);
1440 MatType a2 = t ? a(1, Slice()) : a(Slice(), 1);
1441 MatType a3 = t ? a(2, Slice()) : a(Slice(), 2);
1443 MatType b1 = t ? b(0, Slice()) : b(Slice(), 0);
1444 MatType b2 = t ? b(1, Slice()) : b(Slice(), 1);
1445 MatType b3 = t ? b(2, Slice()) : b(Slice(), 2);
1447 ret[0] = a2*b3-a3*b2;
1448 ret[1] = a3*b1-a1*b3;
1449 ret[2] = a1*b2-a2*b1;
1451 return t ? vertcat(ret) : horzcat(ret);
1455 bool equidistant=
false);
1457 template<
typename MatType>
1459 const std::vector<double>& xq,
const std::string& mode,
bool equidistant) {
1461 bool mode_floor =
false;
1462 bool mode_ceil =
false;
1463 if (mode==
"floor") {
1465 }
else if (mode==
"ceil") {
1467 }
else if (mode==
"linear") {
1470 casadi_error(
"interp1d(x, v, xq, mode): "
1471 "Mode must be 'floor', 'ceil' or 'linear'. Got '" + mode +
"' instead.");
1474 casadi_assert(
is_increasing(x),
"interp1d(x, v, xq): x must be increasing.");
1476 casadi_assert(x.size()==v.size1(),
1477 "interp1d(x, v, xq): dimensions mismatch. v expected to have " + str(x.size()) +
" rows,"
1478 " but got " + str(v.size1()) +
" instead.");
1481 casadi_assert(x.size()>=2,
"interp1d(x, v, xq): x must be at least length 2.");
1484 std::vector<double> val;
1485 std::vector<casadi_int> colind(1, 0);
1486 std::vector<casadi_int> row;
1490 for (casadi_int i=0;i<xq.size();++i) {
1494 if (mode_floor) ind = floor(ind);
1495 if (mode_ceil) ind = ceil(ind);
1499 double frac_part = modf(ind, &int_partd);
1500 casadi_int int_part =
static_cast<casadi_int
>(int_partd);
1505 row.push_back(int_part);
1507 colind.push_back(nnz);
1510 val.push_back(1-frac_part);
1511 val.push_back(frac_part);
1512 row.push_back(int_part);
1513 row.push_back(int_part+1);
1515 colind.push_back(nnz);
1520 Sparsity sp(x.size(), xq.size() , colind, row);
1522 return MatType::mtimes(MatType(sp, val).
T(), v);
1526 template<
typename MatType>
1528 casadi_assert(a.is_vector() && (a.size1()==3 || a.size2()==3),
1529 "skew(a): Expecting 3-vector, got " + a.dim() +
".");
1534 return blockcat(std::vector< std::vector<MatType> >({{0, -z, y}, {z, 0, -x}, {-y, x, 0}}));
1537 template<
typename MatType>
1539 casadi_assert(a.size1()==3 && a.size2()==3,
1540 "inv_skew(a): Expecting 3-by-3 matrix, got " + a.dim() +
".");
1542 return 0.5*vertcat(std::vector<MatType>({a(2, 1)-a(1, 2), a(0, 2)-a(2, 0), a(1, 0)-a(0, 1)}));
1546 template<
typename MatType>
1548 casadi_assert(x.is_square(),
1549 "Shape error in tril2symm. Expecting square shape but got " + x.dim());
1550 casadi_assert(x.nnz_upper()-x.nnz_diag()==0,
1551 "Sparsity error in tril2symm. Found above-diagonal entries in argument: " + x.dim());
1552 return x + x.T() - diag(diag(x));
1555 template<
typename MatType>
1557 casadi_assert_dev(x.size1() % n==0);
1558 casadi_assert_dev(x.size2() % m==0);
1559 std::vector< std::vector< MatType> > s =
1560 blocksplit(x, x.size1()/n, x.size2()/m);
1562 for (casadi_int i=0;i<s.size();++i) {
1563 for (casadi_int j=0;j<s[i].size();++j) {
1564 sum = sum + s[i][j];
1570 template<
typename MatType>
1572 casadi_assert(x.is_square(),
1573 "Shape error in triu2symm. Expecting square shape but got " + x.dim());
1574 casadi_assert(x.nnz_lower()-x.nnz_diag()==0,
1575 "Sparsity error in triu2symm. Found below-diagonal entries in argument: " + x.dim());
1576 return x + x.T() - diag(diag(x));
1579 template<
typename MatType>
1583 casadi_assert_dev(x.is_vector());
1584 if (!x.is_column())
return bilin(A, x.T(), y);
1585 if (!x.is_dense())
return bilin(A, densify(x), y);
1588 casadi_assert_dev(y.is_vector());
1589 if (!y.is_column())
return bilin(A, x, y.T());
1590 if (!y.is_dense())
return bilin(A, x, densify(y));
1593 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1594 "Dimension mismatch. Got x.size1() = " + str(x.size1())
1595 +
" and y.size1() = " + str(y.size1()) +
" but A.size() = " + str(A.size()));
1598 return MatType::_bilin(A, x, y);
1601 template<
typename MatType>
1603 const MatType& x,
const MatType& y) {
1605 casadi_assert_dev(x.is_vector());
1606 if (!x.is_column())
return rank1(A, alpha, x.T(), y);
1607 if (!x.is_dense())
return rank1(A, alpha, densify(x), y);
1610 casadi_assert_dev(y.is_vector());
1611 if (!y.is_column())
return rank1(A, alpha, x, y.T());
1612 if (!y.is_dense())
return rank1(A, alpha, x, densify(y));
1615 casadi_assert_dev(alpha.is_scalar());
1616 if (!alpha.is_dense())
return A;
1619 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1620 "Dimension mismatch. Got x.size1() = " + str(x.size1())
1621 +
" and y.size1() = " + str(y.size1())
1622 +
" but A.size() = " + str(A.size()));
1625 return MatType::_rank1(A, alpha, x, y);
1628 template<
typename MatType>
1630 casadi_assert(x.is_dense(),
"Argument must be dense");
1631 casadi_assert(x.is_column(),
"Argument must be column vector");
1633 return MatType::_logsumexp(x);
1636 template<
typename MatType>
1638 const MatType &v,
bool tr,
const Dict& opts) {
1642 if (ex.size2()==0 && v.size2()>0) {
1643 casadi_error(
"Ambiguous dimensions.");
1645 casadi_assert(v.size1() == ex.size1() &&
1646 (v.size2()==0 || ex.size2()==0 || v.size2() % ex.size2() == 0),
1647 "'v' has inconsistent dimensions: "
1648 " v " + v.dim(
false) +
", ex " + ex.dim(
false) +
".");
1650 if (arg.size2()==0 && v.size2()>0) {
1651 casadi_error(
"Ambiguous dimensions.");
1653 casadi_assert(v.size1() == arg.size1() &&
1654 (v.size2()==0 || arg.size2()==0 || v.size2() % arg.size2() == 0),
1655 "'v' has inconsistent dimensions: "
1656 " v " + v.dim(
false) +
", arg " + arg.dim(
false) +
".");
1659 casadi_int n_seeds = 1;
1661 if (ex.size2()>0) n_seeds = v.size2() / ex.size2();
1663 if (arg.size2()>0) n_seeds = v.size2() / arg.size2();
1667 if (v.is_empty() || ex.is_empty()) {
1668 return MatType(tr ? arg.size1() : ex.size1(),
1669 tr ? arg.size2()*n_seeds : ex.size2()*n_seeds);
1673 std::vector<MatType> w = horzsplit(v, tr ? ex.size2() : arg.size2());
1676 std::vector<std::vector<MatType> > ww(w.size());
1677 for (casadi_int i=0; i<w.size(); ++i) ww[i] = {w[i]};
1681 ww = reverse({ex}, {arg}, ww, opts);
1683 ww = forward({ex}, {arg}, ww, opts);
1687 for (casadi_int i=0; i<w.size(); ++i) w[i] = ww[i][0];
1689 }
catch (std::exception& e) {
1690 CASADI_THROW_ERROR(
"jtimes", e.what());
1694 template<
typename MatType>
1698 casadi_assert(ex.is_scalar(),
1699 "'gradient' only defined for scalar outputs: Use 'jacobian' instead.");
1700 return project(jtimes(ex, arg, MatType::ones(ex.sparsity()),
true, opts), arg.sparsity());
1701 }
catch (std::exception& e) {
1702 CASADI_THROW_ERROR(
"gradient", e.what());
1706 template<
typename MatType>
1710 casadi_assert(arg.is_scalar(),
1711 "'tangent' only defined for scalar inputs: Use 'jacobian' instead.");
1712 return project(jtimes(ex, arg, MatType::ones(arg.sparsity()),
false, opts), ex.sparsity());
1713 }
catch (std::exception& e) {
1714 CASADI_THROW_ERROR(
"tangent", e.what());
1718 template<
typename MatType>
1720 linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
const Dict& opts) {
1721 MatType x_lin = MatType::sym(
"x_lin", x.sparsity());
1723 if (x0.size() != x.size()) {
1725 if (x0.sparsity().is_scalar()) {
1726 return linearize(f, x, MatType(x.sparsity(), x0));
1728 casadi_error(
"Dimension mismatch in 'linearize'");
1730 return substitute(f + jtimes(f, x, x_lin,
false, opts),
1731 MatType::vertcat({x_lin, x}), MatType::vertcat({x, x0}));
1734 template<
typename MatType>
1737 if (a.is_scalar() && b.is_scalar())
return pow(a, b);
1738 casadi_assert(a.is_square() && b.is_constant() && b.is_scalar(),
1740 double bv =
static_cast<double>(b);
1741 casadi_int N =
static_cast<casadi_int
>(bv);
1742 casadi_assert(bv-
static_cast<double>(N)==0,
"mpower only defined for integer powers.");
1743 casadi_assert(bv==N,
"Not Implemented");
1744 if (N<0)
return inv(mpower(a, -N));
1745 if (N==0)
return MatType::eye(a.size1());
1748 MatType h = mpower(a, N/2);
1749 return MatType::mtimes(h, h);
1751 return MatType::mtimes(mpower(a, N-1), a);
1755 template<
typename MatType>
1758 casadi_assert(y.is_scalar(),
"y needs to be scalar. Got " + y.dim() +
".");
1759 casadi_assert(x.is_vector(),
"x needs to be a vector. Got " + x.dim() +
".");
1761 MatType x_col = x.is_column() ? x : x.T();
1763 x_col = x_col.nz(Slice());
1765 casadi_int n = x_col.numel();
1766 return blockcat(y*MatType::eye(n), x_col, x_col.T(), y);
1769 template<
typename MatType>
1771 return !any(MatType::which_depends(expr, var, 2,
true));
1774 template<
typename MatType>
1776 return is_linear(gradient(expr, var), var);
1779 template<
typename MatType>
1781 MatType& A, MatType& b, MatType& c,
bool check) {
1782 casadi_assert(expr.is_scalar(),
"'quadratic_coeff' only defined for scalar expressions.");
1783 A = hessian(expr, var);
1784 b = substitute(jacobian(expr, var), var, 0).T();
1786 casadi_assert(!depends_on(A, var),
"'quadratic_coeff' called on non-quadratic expression.");
1787 c = substitute(expr, var, 0);
1790 template<
typename MatType>
1792 MatType& A, MatType& b,
bool check) {
1793 casadi_assert(expr.is_vector(),
"'linear_coeff' only defined for vector expressions.");
1795 casadi_assert(is_linear(expr, var),
"'linear_coeff' called on non-linear expression.");
1796 A = substitute(jacobian(expr, var), var, 0);
1797 b = vec(substitute(expr, var, 0));
1800 template<
typename MatType>
1802 casadi_assert(axis==-1 || axis==0 || axis==1,
"Axis argument invalid");
1803 casadi_assert(n>=1,
"n argument invalid");
1806 for (casadi_int i=0;i<n;++i) {
1808 if (axis==-1 && ret.is_scalar())
return MatType();
1810 casadi_int local_axis = (axis==-1) ? ret.is_row() : axis;
1811 if (local_axis==0) {
1812 if (ret.size1()<=1) {
1813 ret = MatType::zeros(0, ret.size2());
1815 ret = ret(Slice(1, ret.size1()), Slice())-ret(Slice(0, ret.size1()-1), Slice());
1818 if (ret.size2()<=1) {
1819 ret = MatType::zeros(ret.size1(), 0);
1821 ret = ret(Slice(), Slice(1, ret.size2()))-ret(Slice(), Slice(0, ret.size2()-1));
1828 #undef CASADI_THROW_ERROR
casadi_int numel() const
Get the number of elements.
Sparsity sparsity() const
Get the sparsity pattern.
bool is_dense() const
Check if the matrix expression is dense.
bool is_column() const
Check if the matrix is a column vector (i.e. size2()==1)
static MatType zeros(const Sparsity &sp)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
bool is_empty(bool both=false) const
Check if the sparsity is empty, i.e. if one of the dimensions is zero.
casadi_int row(casadi_int el) const
Get the sparsity pattern. See the Sparsity class for details.
std::vector< casadi_int > get_colind() const
Get the sparsity pattern. See the Sparsity class for details.
bool is_vector() const
Check if the matrix is a row or column vector.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
casadi_int size2() const
Get the second dimension (i.e. number of columns)
casadi_int rows() const
Get the number of rows, Octave-style syntax.
bool is_tril() const
Check if the matrix is lower triangular.
static MatType zeros(const std::pair< casadi_int, casadi_int > &rc)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
static MatType sym(const std::string &name, const std::pair< casadi_int, casadi_int > &rc)
Construct a symbolic primitive with given dimensions.
static MatType sym(const std::string &name, const Sparsity &sp)
Create symbolic primitive with a given sparsity pattern.
static std::vector< MatType > sym(const std::string &name, casadi_int nrow, casadi_int ncol, casadi_int p)
Create a vector of length p with nrow-by-ncol symbolic primitives.
casadi_int size(casadi_int axis) const
Get the size along a particular dimensions.
casadi_int nnz_upper() const
Get the number of non-zeros in the upper triangular half.
bool is_row() const
Check if the matrix is a row vector (i.e. size1()==1)
bool is_triu() const
Check if the matrix is upper triangular.
casadi_int size1() const
Get the first dimension (i.e. number of rows)
std::string dim(bool with_nz=false) const
Get string representation of dimensions.
casadi_int nnz_diag() const
Get get the number of non-zeros on the diagonal.
static MatType ones(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries one.
static MatType ones(const Sparsity &sp)
Create a dense matrix or a matrix with specified sparsity with all entries one.
static MatType sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
static std::vector< std::vector< MatType > > sym(const std::string &name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r)
Create a vector of length r of vectors of length p.
static MatType ones(const std::pair< casadi_int, casadi_int > &rc)
Create a dense matrix or a matrix with specified sparsity with all entries one.
casadi_int colind(casadi_int col) const
Get the sparsity pattern. See the Sparsity class for details.
bool is_square() const
Check if the matrix expression is square.
static std::vector< MatType > sym(const std::string &name, const Sparsity &sp, casadi_int p)
Create a vector of length p with with matrices.
casadi_int columns() const
Get the number of columns, Octave-style syntax.
static MatType zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
std::vector< casadi_int > get_row() const
Get the sparsity pattern. See the Sparsity class for details.
static std::vector< std::vector< MatType > > sym(const std::string &name, const Sparsity &sp, casadi_int p, casadi_int r)
Create a vector of length r of vectors of length p with.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
casadi_int nnz_lower() const
Get the number of non-zeros in the lower triangular half.
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix expression is scalar.
casadi_int colind(casadi_int cc) const
Get a reference to the colindex of column cc (see class description)
bool is_vector() const
Check if the pattern is a row or column vector.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
std::vector< casadi_int > get_colind() const
Get the column index for each column.
bool is_column() const
Check if the pattern is a column vector (i.e. size2()==1)
bool is_row() const
Check if the pattern is a row vector (i.e. size1()==1)
bool is_tril(bool strictly=false) const
Is lower triangular?
casadi_int row(casadi_int el) const
Get the row of a non-zero element.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
bool is_dense() const
Is dense?
bool is_square() const
Is square?
bool is_triu(bool strictly=false) const
Is upper triangular?
std::vector< casadi_int > get_row() const
Get the row for each non-zero entry.
bool is_increasing(const std::vector< T > &v)
Check if the vector is strictly increasing.
double CASADI_EXPORT index_interp1d(const std::vector< double > &x, double xq, bool equidistant=false)
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.