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>) {
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);
216 static casadi_int
norm_0_mul(
const MatType &x,
const MatType &y) {
219 static MatType
tril(
const MatType &x,
bool includeDiagonal=
true) {
222 static MatType
triu(
const MatType &x,
bool includeDiagonal=
true) {
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);
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);
238 MatType& A, MatType& b, MatType& c,
bool check);
240 MatType& A, MatType& b,
bool check);
248 const MatType
nz(
const K& k)
const {
250 self().get_nz(ret,
false, k);
265 template<
typename RR>
268 self().get(ret,
false, rr);
275 template<
typename RR,
typename CC>
278 self().get(ret,
false, rr, cc);
285 template<
typename RR>
293 template<
typename RR,
typename 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
inv_minor(
const MatType& A) {
return MatType::inv_minor(A);}
498 inline friend MatType
inv(
const MatType& A) {
499 return MatType::inv(A);
505 inline friend MatType
inv(
const MatType& A,
506 const std::string& lsolver,
508 return MatType::inv(A, lsolver, options);
514 inline friend MatType
trace(
const MatType& x) {
return MatType::trace(x);}
519 inline friend MatType
tril2symm(
const MatType &a) {
return MatType::tril2symm(a);}
524 inline friend MatType
triu2symm(
const MatType &a) {
return MatType::triu2symm(a);}
529 inline friend MatType
norm_fro(
const MatType &x) {
return MatType::norm_fro(x);}
534 inline friend MatType
norm_2(
const MatType &x) {
return MatType::norm_2(x);}
539 inline friend MatType
norm_1(
const MatType &x) {
return MatType::norm_1(x);}
544 inline friend MatType
norm_inf(
const MatType &x) {
return MatType::norm_inf(x);}
549 inline friend MatType
diff(
const MatType &x, casadi_int n=1, casadi_int axis=-1) {
550 return MatType::diff(x, n, axis);
556 inline friend MatType
cumsum(
const MatType &x, casadi_int axis=-1) {
557 return MatType::cumsum(x, axis);
565 inline friend MatType
dot(
const MatType &x,
const MatType &y) {
566 return MatType::dot(x, y);
580 return MatType::nullspace(A);
586 inline friend MatType
polyval(
const MatType& p,
const MatType& x) {
587 return MatType::polyval(p, x);
596 inline friend MatType
diag(
const MatType &A) {
597 return MatType::diag(A);
603 inline friend MatType
unite(
const MatType& A,
const MatType& B) {
604 return MatType::unite(A, B);
610 inline friend MatType
densify(
const MatType& x) {
611 return MatType::densify(x);
617 inline friend MatType
densify(
const MatType& x,
const MatType& val) {
618 return MatType::densify(x, val);
627 bool intersect=
false) {
628 return MatType::project(A, sp, intersect);
636 inline friend MatType
if_else(
const MatType &cond,
const MatType &if_true,
637 const MatType &if_false,
bool short_circuit=
false) {
638 return MatType::if_else(cond, if_true, if_false, short_circuit);
647 inline friend MatType
conditional(
const MatType& ind,
const std::vector<MatType> &x,
648 const MatType &x_default,
bool short_circuit=
false) {
649 return MatType::conditional(ind, x, x_default, short_circuit);
665 inline friend bool depends_on(
const MatType& f,
const MatType &arg) {
666 return MatType::depends_on(f, arg);
685 inline friend bool contains(
const std::vector<MatType>& v,
const MatType &n) {
689 inline friend bool contains_all(
const std::vector<MatType>& v,
const std::vector<MatType> &n) {
690 return MatType::contains_all(v, n);
693 inline friend bool contains_any(
const std::vector<MatType>& v,
const std::vector<MatType> &n) {
694 return MatType::contains_any(v, n);
701 friend inline MatType
substitute(
const MatType& ex,
const MatType& v,
702 const MatType& vdef) {
703 return MatType::substitute(ex, v, vdef);
709 friend inline std::vector<MatType>
710 substitute(
const std::vector<MatType>& ex,
const std::vector<MatType>& v,
711 const std::vector<MatType>& vdef) {
712 return MatType::substitute(ex, v, vdef);
723 std::vector<MatType>& inout_vdef,
724 std::vector<MatType>& inout_ex,
bool reverse=
false) {
725 return MatType::substitute_inplace(v, inout_vdef, inout_ex,
reverse);
731 inline friend MatType
cse(
const MatType& e) {
732 return MatType::cse({e}).at(0);
739 inline friend std::vector<MatType>
cse(
const std::vector<MatType>& e) {
740 return MatType::cse(e);
761 friend inline MatType
solve(
const MatType& A,
const MatType& b) {
763 if (A.is_scalar())
return b/A;
764 return MatType::solve(A, b);
770 friend inline MatType
solve(
const MatType& A,
const MatType& b,
771 const std::string& lsolver,
774 if (A.is_scalar())
return b/A;
775 return MatType::solve(A, b, lsolver, dict);
778 #ifdef WITH_DEPRECATED_FEATURES
795 friend inline MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
797 return MatType::linearize(f, x, x0, opts);
813 friend inline MatType
pinv(
const MatType& A) {
814 return MatType::pinv(A);
823 friend inline MatType
pinv(
const MatType& A,
const std::string& lsolver,
825 return MatType::pinv(A, lsolver, dict);
838 friend inline MatType
expm_const(
const MatType& A,
const MatType& t) {
839 return MatType::expm_const(A, t);
846 friend inline MatType
expm(
const MatType& A) {
847 return MatType::expm(A);
855 inline friend MatType
jacobian(
const MatType &ex,
const MatType &arg,
857 return MatType::jacobian(ex, arg, opts);
868 inline friend MatType
gradient(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
869 return MatType::gradient(ex, arg, opts);
875 inline friend MatType
tangent(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
876 return MatType::tangent(ex, arg, opts);
888 friend inline MatType
jtimes(
const MatType &ex,
const MatType &arg,
889 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict()) {
890 return MatType::jtimes(ex, arg, v, tr, opts);
896 friend inline std::vector<std::vector<MatType> >
897 forward(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
898 const std::vector<std::vector<MatType> > &v,
900 return MatType::forward(ex, arg, v, opts);
906 friend inline std::vector<std::vector<MatType> >
907 reverse(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
908 const std::vector<std::vector<MatType> > &v,
910 return MatType::reverse(ex, arg, v, opts);
917 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg,
919 return MatType::hessian(ex, arg, opts);
921 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg, MatType& output_g,
923 return MatType::hessian(ex, arg, output_g, opts);
930 inline friend std::vector<bool>
which_depends(
const MatType &expr,
const MatType &var,
931 casadi_int order,
bool tr) {
932 return MatType::which_depends(expr, var, order, tr);
941 return MatType::jacobian_sparsity(f, x);
951 inline friend bool is_linear(
const MatType &expr,
const MatType &var) {
952 return MatType::is_linear(expr, var);
962 inline friend bool is_quadratic(
const MatType &expr,
const MatType &var) {
963 return MatType::is_quadratic(expr, var);
977 MatType& A, MatType& b, MatType& c,
bool check=
true) {
978 MatType::quadratic_coeff(expr, var, A, b, c, check);
989 inline friend void linear_coeff(
const MatType &expr,
const MatType &var,
990 MatType& A, MatType& b,
bool check=
true) {
991 MatType::linear_coeff(expr, var, A, b, check);
1026 MatType& SWIG_OUTPUT(expr_ret),
1027 std::vector<MatType>& SWIG_OUTPUT(symbols),
1028 std::vector<MatType>& SWIG_OUTPUT(parametric),
1030 MatType::extract_parametric(expr, par, expr_ret, symbols, parametric, opts);
1034 std::vector<MatType>& SWIG_OUTPUT(expr_ret),
1035 std::vector<MatType>& SWIG_OUTPUT(symbols),
1036 std::vector<MatType>& SWIG_OUTPUT(parametric),
1039 MatType expr_cat =
veccat(expr);
1040 MatType expr_ret_cat;
1043 MatType::extract_parametric(expr_cat, par, expr_ret_cat, symbols, parametric, opts);
1046 std::vector<casadi_int> edges = {0};
1047 for (
const MatType& e : expr) {
1048 edges.push_back(edges.back() + e.numel());
1051 std::vector<MatType> expr_ret_catv = MatType::vertsplit(expr_ret_cat, edges);
1054 expr_ret.resize(expr_ret_catv.size());
1055 for (casadi_int i=0; i<expr_ret_catv.size(); ++i) {
1061 const std::vector<MatType>& par,
1062 std::vector<MatType>& SWIG_OUTPUT(expr_ret),
1063 std::vector<MatType>& SWIG_OUTPUT(symbols),
1064 std::vector<MatType>& SWIG_OUTPUT(parametric),
1070 MatType& SWIG_OUTPUT(expr_ret),
1071 std::vector<MatType>& SWIG_OUTPUT(symbols),
1072 std::vector<MatType>& SWIG_OUTPUT(parametric),
1105 const MatType &sym_lin,
const MatType &sym_const,
1106 MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1107 MatType::separate_linear(expr, sym_lin, sym_const, expr_const, expr_lin, expr_nonlin);
1111 const std::vector<MatType> &sym_lin,
const std::vector<MatType> &sym_const,
1112 MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1114 expr_const, expr_lin, expr_nonlin);
1118 inline friend casadi_int
n_nodes(
const MatType& A) {
1119 return MatType::n_nodes(A);
1124 return MatType::simplify(x);
1130 inline friend std::string
1132 return MatType::print_operator(xb, args);
1138 inline friend void extract(std::vector<MatType>& ex,
1139 std::vector<MatType>& v,
1140 std::vector<MatType>& vdef,
1142 MatType::extract(ex, v, vdef, opts);
1148 inline friend void shared(std::vector<MatType>& ex,
1149 std::vector<MatType>& v,
1150 std::vector<MatType>& vdef,
1151 const std::string& v_prefix=
"v_",
1152 const std::string& v_suffix=
"") {
1153 return MatType::shared(ex, v, vdef, v_prefix, v_suffix);
1159 inline friend MatType
repsum(
const MatType &A, casadi_int n, casadi_int m=1) {
1160 return MatType::repsum(A, n, m);
1167 friend inline MatType
mmin(
const MatType& x) {
1168 return MatType::mmin(x);
1176 friend inline MatType
mmax(
const MatType& x) {
1177 return MatType::mmax(x);
1183 static MatType
jtimes(
const MatType &ex,
const MatType &arg,
1184 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict());
1187 static MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
1189 static MatType
mpower(
const MatType &x,
const MatType &y);
1190 static MatType
soc(
const MatType &x,
const MatType &y);
1206 static MatType
sym(
const std::string& name, casadi_int nrow=1, casadi_int ncol=1) {
1213 static MatType
sym(
const std::string& name,
const std::pair<casadi_int, casadi_int> &rc) {
1214 return sym(name, rc.first, rc.second);
1221 return MatType::_sym(name, sp);
1229 static std::vector<MatType >
sym(
const std::string& name,
const Sparsity& sp, casadi_int p);
1234 static std::vector<MatType >
sym(
const std::string& name, casadi_int nrow,
1235 casadi_int ncol, casadi_int p) {
1244 static std::vector<std::vector<MatType> >
1245 sym(
const std::string& name,
const Sparsity& sp, casadi_int p, casadi_int r);
1252 static std::vector<std::vector<MatType> >
1253 sym(
const std::string& name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r) {
1262 static MatType
zeros(casadi_int nrow=1, casadi_int ncol=1) {
1266 static MatType
zeros(
const std::pair<casadi_int, casadi_int>& rc) {
1267 return zeros(rc.first, rc.second);
1275 static MatType
ones(casadi_int nrow=1, casadi_int ncol=1) {
1279 static MatType
ones(
const std::pair<casadi_int, casadi_int>& rc) {
1280 return ones(rc.first, rc.second);
1286 #define CASADI_THROW_ERROR(FNAME, WHAT) \
1287 throw CasadiException("Error in " + MatType::type_name() \
1288 + "::" FNAME " at " + CASADI_WHERE + ":\n" + std::string(WHAT));
1292 template<
typename MatType>
1294 return self().sparsity();
1297 template<
typename MatType>
1299 return sparsity().nnz();
1302 template<
typename MatType>
1304 return sparsity().nnz_lower();
1307 template<
typename MatType>
1309 return sparsity().nnz_upper();
1312 template<
typename MatType>
1314 return sparsity().nnz_diag();
1317 template<
typename MatType>
1319 return sparsity().numel();
1322 template<
typename MatType>
1324 return sparsity().size1();
1327 template<
typename MatType>
1329 return sparsity().size2();
1332 template<
typename MatType>
1334 return sparsity().size();
1337 template<
typename MatType>
1339 return sparsity().size(axis);
1342 template<
typename MatType>
1344 return sparsity().dim(with_nz);
1347 template<
typename MatType>
1349 return sparsity().is_scalar(scalar_and_dense);
1354 template<
typename MatType>
1356 const Sparsity& sp, casadi_int p) {
1357 std::vector<MatType> ret(p);
1358 std::stringstream ss;
1359 for (casadi_int k=0; k<p; ++k) {
1362 ret[k] = sym(ss.str(), sp);
1367 template<
typename MatType>
1371 std::vector<std::vector<MatType> > ret(r);
1372 for (casadi_int k=0; k<r; ++k) {
1373 std::stringstream ss;
1374 ss << name <<
"_" << k;
1375 ret[k] = sym(ss.str(), sp, p);
1380 template<
typename MatType>
1382 std::vector<MatType> ret(nsteps);
1384 MatType step = (b-a)/
static_cast<MatType
>(nsteps-1);
1386 for (casadi_int i=1; i<nsteps-1; ++i)
1387 ret[i] = a + i * step;
1390 return vertcat(ret);
1393 template<
typename MatType>
1395 casadi_assert(a.size1()==b.size1() && a.size2()==b.size2(),
1396 "cross(a, b): Inconsistent dimensions. Dimension of a ("
1397 + a.dim() +
" ) must equal that of b (" + b.dim() +
").");
1399 casadi_assert(a.size1()==3 || a.size2()==3,
1400 "cross(a, b): One of the dimensions of a should have length 3, but got "
1402 casadi_assert(dim==-1 || dim==1 || dim==2,
1403 "cross(a, b, dim): Dim must be 1, 2 or -1 (automatic).");
1405 std::vector<MatType> ret(3);
1407 bool t = a.size1()==3;
1409 if (dim==1) t =
true;
1410 if (dim==2) t =
false;
1412 MatType a1 = t ? a(0,
Slice()) : a(
Slice(), 0);
1413 MatType a2 = t ? a(1,
Slice()) : a(
Slice(), 1);
1414 MatType a3 = t ? a(2,
Slice()) : a(
Slice(), 2);
1416 MatType b1 = t ? b(0,
Slice()) : b(
Slice(), 0);
1417 MatType b2 = t ? b(1,
Slice()) : b(
Slice(), 1);
1418 MatType b3 = t ? b(2,
Slice()) : b(
Slice(), 2);
1420 ret[0] = a2*b3-a3*b2;
1421 ret[1] = a3*b1-a1*b3;
1422 ret[2] = a1*b2-a2*b1;
1424 return t ? vertcat(ret) : horzcat(ret);
1427 double CASADI_EXPORT
index_interp1d(
const std::vector<double>& x,
double xq,
1428 bool equidistant=
false);
1430 template<
typename MatType>
1432 const std::vector<double>& xq,
const std::string& mode,
bool equidistant) {
1434 bool mode_floor =
false;
1435 bool mode_ceil =
false;
1436 if (mode==
"floor") {
1438 }
else if (mode==
"ceil") {
1440 }
else if (mode==
"linear") {
1443 casadi_error(
"interp1d(x, v, xq, mode): "
1444 "Mode must be 'floor', 'ceil' or 'linear'. Got '" + mode +
"' instead.");
1447 casadi_assert(
is_increasing(x),
"interp1d(x, v, xq): x must be increasing.");
1449 casadi_assert(x.size()==v.size1(),
1450 "interp1d(x, v, xq): dimensions mismatch. v expected to have " +
str(x.size()) +
" rows,"
1451 " but got " +
str(v.size1()) +
" instead.");
1454 casadi_assert(x.size()>=2,
"interp1d(x, v, xq): x must be at least length 2.");
1457 std::vector<double> val;
1458 std::vector<casadi_int> colind(1, 0);
1459 std::vector<casadi_int> row;
1463 for (casadi_int i=0;i<xq.size();++i) {
1467 if (mode_floor) ind = floor(ind);
1468 if (mode_ceil) ind = ceil(ind);
1472 double frac_part = modf(ind, &int_partd);
1473 casadi_int int_part =
static_cast<casadi_int
>(int_partd);
1478 row.push_back(int_part);
1480 colind.push_back(nnz);
1483 val.push_back(1-frac_part);
1484 val.push_back(frac_part);
1485 row.push_back(int_part);
1486 row.push_back(int_part+1);
1488 colind.push_back(nnz);
1493 Sparsity sp(x.size(), xq.size() , colind, row);
1495 return MatType::mtimes(MatType(sp, val).
T(), v);
1499 template<
typename MatType>
1501 casadi_assert(a.is_vector() && (a.size1()==3 || a.size2()==3),
1502 "skew(a): Expecting 3-vector, got " + a.dim() +
".");
1507 return blockcat(std::vector< std::vector<MatType> >({{0, -z, y}, {z, 0, -x}, {-y, x, 0}}));
1510 template<
typename MatType>
1512 casadi_assert(a.size1()==3 && a.size2()==3,
1513 "inv_skew(a): Expecting 3-by-3 matrix, got " + a.dim() +
".");
1515 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)}));
1519 template<
typename MatType>
1521 casadi_assert(x.is_square(),
1522 "Shape error in tril2symm. Expecting square shape but got " + x.dim());
1523 casadi_assert(x.nnz_upper()-x.nnz_diag()==0,
1524 "Sparsity error in tril2symm. Found above-diagonal entries in argument: " + x.dim());
1525 return x + x.T() - diag(diag(x));
1528 template<
typename MatType>
1530 casadi_assert_dev(x.size1() % n==0);
1531 casadi_assert_dev(x.size2() % m==0);
1532 std::vector< std::vector< MatType> > s =
1533 blocksplit(x, x.size1()/n, x.size2()/m);
1535 for (casadi_int i=0;i<s.size();++i) {
1536 for (casadi_int j=0;j<s[i].size();++j) {
1543 template<
typename MatType>
1545 casadi_assert(x.is_square(),
1546 "Shape error in triu2symm. Expecting square shape but got " + x.dim());
1547 casadi_assert(x.nnz_lower()-x.nnz_diag()==0,
1548 "Sparsity error in triu2symm. Found below-diagonal entries in argument: " + x.dim());
1549 return x + x.T() - diag(diag(x));
1552 template<
typename MatType>
1556 casadi_assert_dev(x.is_vector());
1557 if (!x.is_column())
return bilin(A, x.T(), y);
1558 if (!x.is_dense())
return bilin(A, densify(x), y);
1561 casadi_assert_dev(y.is_vector());
1562 if (!y.is_column())
return bilin(A, x, y.T());
1563 if (!y.is_dense())
return bilin(A, x, densify(y));
1566 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1567 "Dimension mismatch. Got x.size1() = " +
str(x.size1())
1568 +
" and y.size1() = " +
str(y.size1()) +
" but A.size() = " +
str(A.size()));
1571 return MatType::_bilin(A, x, y);
1574 template<
typename MatType>
1576 const MatType& x,
const MatType& y) {
1578 casadi_assert_dev(x.is_vector());
1579 if (!x.is_column())
return rank1(A, alpha, x.T(), y);
1580 if (!x.is_dense())
return rank1(A, alpha, densify(x), y);
1583 casadi_assert_dev(y.is_vector());
1584 if (!y.is_column())
return rank1(A, alpha, x, y.T());
1585 if (!y.is_dense())
return rank1(A, alpha, x, densify(y));
1588 casadi_assert_dev(alpha.is_scalar());
1589 if (!alpha.is_dense())
return A;
1592 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1593 "Dimension mismatch. Got x.size1() = " +
str(x.size1())
1594 +
" and y.size1() = " +
str(y.size1())
1595 +
" but A.size() = " +
str(A.size()));
1598 return MatType::_rank1(A, alpha, x, y);
1601 template<
typename MatType>
1603 casadi_assert(x.is_dense(),
"Argument must be dense");
1604 casadi_assert(x.is_column(),
"Argument must be column vector");
1606 return MatType::_logsumexp(x);
1609 template<
typename MatType>
1611 const MatType &v,
bool tr,
const Dict& opts) {
1615 if (ex.size2()==0 && v.size2()>0) {
1616 casadi_error(
"Ambiguous dimensions.");
1618 casadi_assert(v.size1() == ex.size1() &&
1619 (v.size2()==0 || ex.size2()==0 || v.size2() % ex.size2() == 0),
1620 "'v' has inconsistent dimensions: "
1621 " v " + v.dim(
false) +
", ex " + ex.dim(
false) +
".");
1623 if (arg.size2()==0 && v.size2()>0) {
1624 casadi_error(
"Ambiguous dimensions.");
1626 casadi_assert(v.size1() == arg.size1() &&
1627 (v.size2()==0 || arg.size2()==0 || v.size2() % arg.size2() == 0),
1628 "'v' has inconsistent dimensions: "
1629 " v " + v.dim(
false) +
", arg " + arg.dim(
false) +
".");
1632 casadi_int n_seeds = 1;
1634 if (ex.size2()>0) n_seeds = v.size2() / ex.size2();
1636 if (arg.size2()>0) n_seeds = v.size2() / arg.size2();
1640 if (v.is_empty() || ex.is_empty()) {
1641 return MatType(tr ? arg.size1() : ex.size1(),
1642 tr ? arg.size2()*n_seeds : ex.size2()*n_seeds);
1646 std::vector<MatType> w = horzsplit(v, tr ? ex.size2() : arg.size2());
1649 std::vector<std::vector<MatType> > ww(w.size());
1650 for (casadi_int i=0; i<w.size(); ++i) ww[i] = {w[i]};
1654 ww =
reverse({ex}, {arg}, ww, opts);
1656 ww = forward({ex}, {arg}, ww, opts);
1660 for (casadi_int i=0; i<w.size(); ++i) w[i] = ww[i][0];
1662 }
catch (std::exception& e) {
1663 CASADI_THROW_ERROR(
"jtimes", e.what());
1667 template<
typename MatType>
1671 casadi_assert(ex.is_scalar(),
1672 "'gradient' only defined for scalar outputs: Use 'jacobian' instead.");
1673 return project(jtimes(ex, arg, MatType::ones(ex.sparsity()),
true, opts), arg.sparsity());
1674 }
catch (std::exception& e) {
1675 CASADI_THROW_ERROR(
"gradient", e.what());
1679 template<
typename MatType>
1683 casadi_assert(arg.is_scalar(),
1684 "'tangent' only defined for scalar inputs: Use 'jacobian' instead.");
1685 return project(jtimes(ex, arg, MatType::ones(arg.sparsity()),
false, opts), ex.sparsity());
1686 }
catch (std::exception& e) {
1687 CASADI_THROW_ERROR(
"tangent", e.what());
1691 template<
typename MatType>
1693 linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
const Dict& opts) {
1694 MatType x_lin = MatType::sym(
"x_lin", x.sparsity());
1696 if (x0.size() != x.size()) {
1698 if (x0.sparsity().is_scalar()) {
1699 return linearize(f, x, MatType(x.sparsity(), x0));
1701 casadi_error(
"Dimension mismatch in 'linearize'");
1703 return substitute(f + jtimes(f, x, x_lin,
false, opts),
1704 MatType::vertcat({x_lin, x}), MatType::vertcat({x, x0}));
1707 template<
typename MatType>
1710 if (a.is_scalar() && b.is_scalar())
return pow(a, b);
1711 casadi_assert(a.is_square() && b.is_constant() && b.is_scalar(),
1713 double bv =
static_cast<double>(b);
1714 casadi_int N =
static_cast<casadi_int
>(bv);
1715 casadi_assert(bv-
static_cast<double>(N)==0,
"mpower only defined for integer powers.");
1716 casadi_assert(bv==N,
"Not Implemented");
1717 if (N<0)
return inv(mpower(a, -N));
1718 if (N==0)
return MatType::eye(a.size1());
1721 MatType h = mpower(a, N/2);
1722 return MatType::mtimes(h, h);
1724 return MatType::mtimes(mpower(a, N-1), a);
1728 template<
typename MatType>
1731 casadi_assert(y.is_scalar(),
"y needs to be scalar. Got " + y.dim() +
".");
1732 casadi_assert(x.is_vector(),
"x needs to be a vector. Got " + x.dim() +
".");
1734 MatType x_col = x.is_column() ? x : x.T();
1736 x_col = x_col.nz(Slice());
1738 casadi_int n = x_col.numel();
1739 return blockcat(y*MatType::eye(n), x_col, x_col.T(), y);
1742 template<
typename MatType>
1744 return !
any(MatType::which_depends(expr, var, 2,
true));
1747 template<
typename MatType>
1749 return is_linear(gradient(expr, var), var);
1752 template<
typename MatType>
1754 MatType& A, MatType& b, MatType& c,
bool check) {
1755 casadi_assert(expr.is_scalar(),
"'quadratic_coeff' only defined for scalar expressions.");
1756 A = hessian(expr, var);
1757 b = substitute(jacobian(expr, var), var, 0).T();
1759 casadi_assert(!depends_on(A, var),
"'quadratic_coeff' called on non-quadratic expression.");
1760 c = substitute(expr, var, 0);
1763 template<
typename MatType>
1765 MatType& A, MatType& b,
bool check) {
1766 casadi_assert(expr.is_vector(),
"'linear_coeff' only defined for vector expressions.");
1768 casadi_assert(is_linear(expr, var),
"'linear_coeff' called on non-linear expression.");
1769 A = substitute(jacobian(expr, var), var, 0);
1770 b = vec(substitute(expr, var, 0));
1773 template<
typename MatType>
1775 casadi_assert(axis==-1 || axis==0 || axis==1,
"Axis argument invalid");
1776 casadi_assert(n>=1,
"n argument invalid");
1779 for (casadi_int i=0;i<n;++i) {
1781 if (axis==-1 && ret.is_scalar())
return MatType();
1783 casadi_int local_axis = (axis==-1) ? ret.is_row() : axis;
1784 if (local_axis==0) {
1785 if (ret.size1()<=1) {
1786 ret = MatType::zeros(0, ret.size2());
1791 if (ret.size2()<=1) {
1792 ret = MatType::zeros(ret.size1(), 0);
1801 #undef CASADI_THROW_ERROR
static MatType interp1d(const std::vector< double > &x, const MatType &v, const std::vector< double > &xq, const std::string &mode, bool equidistant)
Functions called by friend functions defined here.
Sparsity sparsity() const
Get the sparsity pattern.
const MatType operator()(const RR &rr, const CC &cc) const
Get Matrix element or slice.
static casadi_int sprank(const MatType &x)
Functions called by friend functions defined here.
casadi_int numel() const
Get the number of elements.
static casadi_int norm_0_mul(const MatType &x, const MatType &y)
Functions called by friend functions defined here.
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.
static void quadratic_coeff(const MatType &expr, const MatType &var, MatType &A, MatType &b, MatType &c, bool check)
Functions called by friend functions defined here.
bool is_empty(bool both=false) const
Check if the sparsity is empty, i.e. if one of the dimensions is zero.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
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)
static void linear_coeff(const MatType &expr, const MatType &var, MatType &A, MatType &b, bool check)
Functions called by friend functions defined here.
static bool is_quadratic(const MatType &expr, const MatType &var)
Functions called by friend functions defined here.
casadi_int rows() const
Get the number of rows, Octave-style syntax.
SubMatrix< MatType, RR, CC > operator()(const RR &rr, const CC &cc)
Access Matrix elements (two arguments)
static MatType sumsqr(const MatType &x)
Functions called by friend functions defined here.
const MatType nz(const K &k) const
Get vector nonzero or slice of nonzeros.
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 MatType diff(const MatType &x, casadi_int n=1, casadi_int axis=-1)
Functions called by friend functions defined here.
static MatType cross(const MatType &a, const MatType &b, casadi_int dim=-1)
Functions called by friend functions defined here.
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.
const MatType operator()(const RR &rr) const
Get vector element or slice.
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)
static MatType tril(const MatType &x, bool includeDiagonal=true)
Functions called by friend functions defined here.
static MatType linspace(const MatType &a, const MatType &b, casadi_int nsteps)
Functions called by friend functions defined here.
static bool is_linear(const MatType &expr, const MatType &var)
Functions called by friend functions defined here.
NonZeros< MatType, K > nz(const K &k)
Access vector nonzero or slice of nonzeros.
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.
const casadi_int * colind() const
Get the sparsity pattern. See the Sparsity class for details.
SubIndex< MatType, RR > operator()(const RR &rr)
Access Matrix elements (one argument)
casadi_int colind(casadi_int col) const
Get the sparsity pattern. See the Sparsity class for details.
static MatType repsum(const MatType &x, casadi_int n, casadi_int m=1)
Functions called by friend functions defined here.
static MatType triu2symm(const MatType &x)
Functions called by friend functions defined here.
static MatType inv_skew(const MatType &a)
Functions called by friend functions defined here.
const casadi_int * row() const
Get the sparsity pattern. See the Sparsity class for details.
bool is_square() const
Check if the matrix expression is square.
static MatType skew(const MatType &a)
Functions called by friend functions defined here.
static std::vector< MatType > sym(const std::string &name, const Sparsity &sp, casadi_int p)
Create a vector of length p with with matrices.
static MatType triu(const MatType &x, bool includeDiagonal=true)
Functions called by friend functions defined here.
casadi_int columns() const
Get the number of columns, Octave-style syntax.
static MatType tril2symm(const MatType &x)
Functions called by friend functions defined here.
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.
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.
Access to a set of nonzeros.
Class representing a Slice.
Sparsity interface class.
static MatType veccat(const std::vector< MatType > &x)
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 *.
static Sparsity triu(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
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)
static Sparsity tril(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
bool is_tril(bool strictly=false) const
Is lower triangular?
const casadi_int * row() const
Get a reference to row-vector,.
std::vector< casadi_int > get_colind() const
Get the column index for each column.
static casadi_int sprank(const Sparsity &x)
Enlarge matrix.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
static casadi_int norm_0_mul(const Sparsity &x, const Sparsity &A)
Enlarge matrix.
std::vector< casadi_int > get_row() const
Get the row for each non-zero entry.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
bool is_dense() const
Is dense?
bool is_square() const
Is square?
bool is_triu(bool strictly=false) const
Is upper triangular?
double index_interp1d(const std::vector< double > &x, double xq, bool equidistant)
bool is_increasing(const std::vector< T > &v)
Check if the vector is strictly increasing.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
bool any(const std::vector< bool > &v)
Check if any arguments are true.
T sum(const std::vector< T > &values)
sum
std::vector< T > reverse(const std::vector< T > &v)
Reverse a list.