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;
325 std::string
dim(
bool with_nz=
false)
const;
358 std::pair<casadi_int, casadi_int>
size()
const;
366 casadi_int
size(casadi_int axis)
const;
648 static MatType
interp1d(
const std::vector<double>& x,
const MatType &v,
649 const std::vector<double>& xq,
const std::string& mode,
bool equidistant);
650 static casadi_int sprank(
const MatType &x) {
return Sparsity::sprank(x.sparsity());}
651 static casadi_int norm_0_mul(
const MatType &x,
const MatType &y) {
652 return Sparsity::norm_0_mul(x.sparsity(), y.sparsity());
654 static MatType tril(
const MatType &x,
bool includeDiagonal=
true) {
655 return project(x, Sparsity::tril(x.sparsity(), includeDiagonal));
657 static MatType triu(
const MatType &x,
bool includeDiagonal=
true) {
658 return project(x, Sparsity::triu(x.sparsity(), includeDiagonal));
660 static MatType
sumsqr(
const MatType &x) {
return dot(x, x);}
661 static MatType
linspace(
const MatType &a,
const MatType &b, casadi_int nsteps);
662 static MatType
cross(
const MatType &a,
const MatType &b, casadi_int
dim=-1);
663 static MatType
skew(
const MatType &a);
664 static MatType
inv_skew(
const MatType &a);
665 static MatType
tril2symm(
const MatType &x);
666 static MatType
triu2symm(
const MatType &x);
667 static MatType
repsum(
const MatType &x, casadi_int n, casadi_int m=1);
668 static MatType
diff(
const MatType &x, casadi_int n=1, casadi_int axis=-1);
670 static bool is_linear(
const MatType &expr,
const MatType &var);
671 static bool is_quadratic(
const MatType &expr,
const MatType &var);
673 MatType& A, MatType& b, MatType& c,
bool check);
674 static void linear_coeff(
const MatType &expr,
const MatType &var,
675 MatType& A, MatType& b,
bool check);
683 const MatType nz(
const K& k)
const {
685 self().get_nz(ret,
false, k);
693 NonZeros<MatType, K> nz(
const K& k) {
694 return NonZeros<MatType, K>(
self(), k);
700 template<
typename RR>
701 const MatType operator()(
const RR& rr)
const {
703 self().get(ret,
false, rr);
710 template<
typename RR,
typename CC>
711 const MatType operator()(
const RR& rr,
const CC& cc)
const {
713 self().get(ret,
false, rr, cc);
720 template<
typename RR>
721 SubIndex<MatType, RR> operator()(
const RR& rr) {
722 return SubIndex<MatType, RR>(
self(), rr);
728 template<
typename RR,
typename CC>
729 SubMatrix<MatType, RR, CC> operator()(
const RR& rr,
const CC& cc) {
730 return SubMatrix<MatType, RR, CC>(
self(), rr, cc);
734 #if !defined(SWIG) || defined(DOXYGEN)
812 inline friend MatType
interp1d(
const std::vector<double>& x,
const MatType&v,
813 const std::vector<double>& xq,
const std::string& mode,
bool equidistant=
false) {
814 return MatType::interp1d(x, v, xq, mode, equidistant);
891 inline friend MatType
mpower(
const MatType& x,
const MatType& n) {
892 return MatType::mpower(x, n);
936 inline friend MatType
soc(
const MatType& x,
const MatType& y) {
937 return MatType::soc(x, y);
1001 inline friend MatType
1002 einstein(
const MatType &A,
const MatType &B,
const MatType &C,
1003 const std::vector<casadi_int>& dim_a,
const std::vector<casadi_int>& dim_b,
1004 const std::vector<casadi_int>& dim_c,
1005 const std::vector<casadi_int>& a,
const std::vector<casadi_int>& b,
1006 const std::vector<casadi_int>& c) {
1007 return MatType::einstein(A, B,
C, dim_a, dim_b, dim_c, a, b, c);
1010 inline friend MatType
1012 const std::vector<casadi_int>& dim_a,
const std::vector<casadi_int>& dim_b,
1013 const std::vector<casadi_int>& dim_c,
1014 const std::vector<casadi_int>& a,
const std::vector<casadi_int>& b,
1015 const std::vector<casadi_int>& c) {
1016 return MatType::einstein(A, B, dim_a, dim_b, dim_c, a, b, c);
1052 inline friend MatType
mrdivide(
const MatType& x,
const MatType& n) {
1053 return MatType::mrdivide(x, n);
1088 inline friend MatType
mldivide(
const MatType& x,
const MatType& n) {
1089 return MatType::mldivide(x, n);
1157 inline friend std::vector<MatType>
symvar(
const MatType& x) {
1158 return MatType::symvar(x);
1207 inline friend MatType
bilin(
const MatType &A,
const MatType &x,
const MatType &y) {
1208 return MatType::bilin(A, x, y);
1210 inline friend MatType
bilin(
const MatType &A,
const MatType &x) {
1211 return MatType::bilin(A, x, x);
1213 static MatType
bilin(
const MatType& A,
const MatType& x,
const MatType& y);
1263 inline friend MatType
rank1(
const MatType &A,
const MatType &alpha,
1264 const MatType &x,
const MatType &y) {
1265 return MatType::rank1(A, alpha, x, y);
1267 static MatType
rank1(
const MatType& A,
const MatType& alpha,
1268 const MatType& x,
const MatType& y);
1312 inline friend MatType
sumsqr(
const MatType &x) {
1313 return MatType::sumsqr(x);
1370 return MatType::logsumexp(x);
1400 inline friend MatType
logsumexp(
const MatType& x,
const MatType& margin) {
1401 MatType alpha = log(x.size1()) / margin;
1402 return MatType::logsumexp(alpha*x)/alpha;
1447 inline friend MatType
linspace(
const MatType &a,
const MatType &b, casadi_int nsteps) {
1448 return MatType::linspace(a, b, nsteps);
1501 inline friend MatType
cross(
const MatType &a,
const MatType &b, casadi_int
dim = -1) {
1502 return MatType::cross(a, b,
dim);
1547 inline friend MatType
skew(
const MatType &a) {
1548 return MatType::skew(a);
1561 return MatType::inv_skew(a);
1607 inline friend MatType
det(
const MatType& A) {
return MatType::det(A);}
1639 inline friend MatType
det(
const MatType& A,
const std::string& lsolver,
1641 return MatType::det(A, lsolver, dict);
1678 inline friend MatType
inv_minor(
const MatType& A) {
return MatType::inv_minor(A);}
1737 inline friend MatType
inv(
const MatType& A) {
1738 return MatType::inv(A);
1776 inline friend MatType
inv(
const MatType& A,
1777 const std::string& lsolver,
1779 return MatType::inv(A, lsolver, options);
1817 inline friend MatType
trace(
const MatType& x) {
return MatType::trace(x);}
1871 inline friend MatType
tril2symm(
const MatType &a) {
return MatType::tril2symm(a);}
1910 inline friend MatType
triu2symm(
const MatType &a) {
return MatType::triu2symm(a);}
1948 inline friend MatType
norm_fro(
const MatType &x) {
return MatType::norm_fro(x);}
1994 inline friend MatType
norm_2(
const MatType &x) {
return MatType::norm_2(x);}
2031 inline friend MatType
norm_1(
const MatType &x) {
return MatType::norm_1(x);}
2068 inline friend MatType
norm_inf(
const MatType &x) {
return MatType::norm_inf(x);}
2128 inline friend MatType
diff(
const MatType &x, casadi_int n=1, casadi_int axis=-1) {
2129 return MatType::diff(x, n, axis);
2190 inline friend MatType
cumsum(
const MatType &x, casadi_int axis=-1) {
2191 return MatType::cumsum(x, axis);
2242 inline friend MatType
dot(
const MatType &x,
const MatType &y) {
2243 return MatType::dot(x, y);
2288 return MatType::nullspace(A);
2335 inline friend MatType
polyval(
const MatType& p,
const MatType& x) {
2336 return MatType::polyval(p, x);
2393 inline friend MatType
diag(
const MatType &A) {
2394 return MatType::diag(A);
2445 inline friend MatType
unite(
const MatType& A,
const MatType& B) {
2446 return MatType::unite(A, B);
2502 return MatType::densify(x);
2510 inline friend MatType
densify(
const MatType& x,
const MatType& val) {
2511 return MatType::densify(x, val);
2575 bool intersect=
false) {
2576 return MatType::project(A, sp, intersect);
2650 inline friend MatType
if_else(
const MatType &cond,
const MatType &if_true,
2651 const MatType &if_false,
bool short_circuit=
false) {
2652 return MatType::if_else(cond, if_true, if_false, short_circuit);
2711 inline friend MatType
conditional(
const MatType& ind,
const std::vector<MatType> &x,
2712 const MatType &x_default,
bool short_circuit=
false) {
2713 return MatType::conditional(ind, x, x_default, short_circuit);
2779 inline friend bool depends_on(
const MatType& f,
const MatType &arg) {
2780 return MatType::depends_on(f, arg);
2846 inline friend bool contains(
const std::vector<MatType>& v,
const MatType &n) {
2850 inline friend bool contains_all(
const std::vector<MatType>& v,
const std::vector<MatType> &n) {
2851 return MatType::contains_all(v, n);
2854 inline friend bool contains_any(
const std::vector<MatType>& v,
const std::vector<MatType> &n) {
2855 return MatType::contains_any(v, n);
2917 friend inline MatType
substitute(
const MatType& ex,
const MatType& v,
2918 const MatType& vdef) {
2919 return MatType::substitute(ex, v, vdef);
2964 friend inline std::vector<MatType>
2965 substitute(
const std::vector<MatType>& ex,
const std::vector<MatType>& v,
2966 const std::vector<MatType>& vdef) {
2967 return MatType::substitute(ex, v, vdef);
3025 std::vector<MatType>& inout_vdef,
3026 std::vector<MatType>& inout_ex,
bool reverse=
false) {
3027 return MatType::substitute_inplace(v, inout_vdef, inout_ex,
reverse);
3072 inline friend MatType
cse(
const MatType& e) {
3073 return MatType::cse({e}).at(0);
3113 inline friend std::vector<MatType>
cse(
const std::vector<MatType>& e) {
3114 return MatType::cse(e);
3197 friend inline MatType
solve(
const MatType& A,
const MatType& b) {
3199 if (A.is_scalar())
return b/A;
3200 return MatType::solve(A, b);
3245 friend inline MatType
solve(
const MatType& A,
const MatType& b,
3246 const std::string& lsolver,
3249 if (A.is_scalar())
return b/A;
3250 return MatType::solve(A, b, lsolver, dict);
3253 #ifdef WITH_DEPRECATED_FEATURES
3293 friend inline MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
3295 return MatType::linearize(f, x, x0, opts);
3364 friend inline MatType
pinv(
const MatType& A) {
3365 return MatType::pinv(A);
3405 friend inline MatType
pinv(
const MatType& A,
const std::string& lsolver,
3407 return MatType::pinv(A, lsolver, dict);
3422 friend inline MatType
expm_const(
const MatType& A,
const MatType& t) {
3423 return MatType::expm_const(A, t);
3434 friend inline MatType
expm(
const MatType& A) {
3435 return MatType::expm(A);
3508 inline friend MatType
jacobian(
const MatType &ex,
const MatType &arg,
3510 return MatType::jacobian(ex, arg, opts);
3570 inline friend MatType
gradient(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
3571 return MatType::gradient(ex, arg, opts);
3606 inline friend MatType
tangent(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
3607 return MatType::tangent(ex, arg, opts);
3677 friend inline MatType
jtimes(
const MatType &ex,
const MatType &arg,
3678 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict()) {
3679 return MatType::jtimes(ex, arg, v, tr, opts);
3734 friend inline std::vector<std::vector<MatType> >
3735 forward(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
3736 const std::vector<std::vector<MatType> > &v,
3738 return MatType::forward(ex, arg, v, opts);
3791 friend inline std::vector<std::vector<MatType> >
3792 reverse(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
3793 const std::vector<std::vector<MatType> > &v,
3795 return MatType::reverse(ex, arg, v, opts);
3851 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg,
3853 return MatType::hessian(ex, arg, opts);
3855 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg, MatType& output_g,
3857 return MatType::hessian(ex, arg, output_g, opts);
3927 inline friend std::vector<bool>
which_depends(
const MatType &expr,
const MatType &var,
3928 casadi_int order,
bool tr) {
3929 return MatType::which_depends(expr, var, order, tr);
3964 return MatType::jacobian_sparsity(f, x);
4010 inline friend bool is_linear(
const MatType &expr,
const MatType &var) {
4011 return MatType::is_linear(expr, var);
4056 return MatType::is_quadratic(expr, var);
4123 MatType& A, MatType& b, MatType& c,
bool check=
true) {
4124 MatType::quadratic_coeff(expr, var, A, b, c, check);
4180 MatType& A, MatType& b,
bool check=
true) {
4181 MatType::linear_coeff(expr, var, A, b, check);
4273 MatType& SWIG_OUTPUT(expr_ret),
4274 std::vector<MatType>& SWIG_OUTPUT(symbols),
4275 std::vector<MatType>& SWIG_OUTPUT(parametric),
4277 MatType::extract_parametric(expr, par, expr_ret, symbols, parametric, opts);
4281 std::vector<MatType>& SWIG_OUTPUT(expr_ret),
4282 std::vector<MatType>& SWIG_OUTPUT(symbols),
4283 std::vector<MatType>& SWIG_OUTPUT(parametric),
4286 MatType expr_cat = veccat(expr);
4287 MatType expr_ret_cat;
4290 MatType::extract_parametric(expr_cat, par, expr_ret_cat, symbols, parametric, opts);
4293 std::vector<casadi_int> edges = {0};
4294 for (
const MatType& e : expr) {
4295 edges.push_back(edges.back() + e.numel());
4298 std::vector<MatType> expr_ret_catv = MatType::vertsplit(expr_ret_cat, edges);
4301 expr_ret.resize(expr_ret_catv.size());
4302 for (casadi_int i=0; i<expr_ret_catv.size(); ++i) {
4303 expr_ret[i] = reshape(expr_ret_catv[i], expr[i].
size1(), expr[i].
size2());
4308 const std::vector<MatType>& par,
4309 std::vector<MatType>& SWIG_OUTPUT(expr_ret),
4310 std::vector<MatType>& SWIG_OUTPUT(symbols),
4311 std::vector<MatType>& SWIG_OUTPUT(parametric),
4317 MatType& SWIG_OUTPUT(expr_ret),
4318 std::vector<MatType>& SWIG_OUTPUT(symbols),
4319 std::vector<MatType>& SWIG_OUTPUT(parametric),
4393 const MatType &sym_lin,
const MatType &sym_const,
4394 MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
4395 MatType::separate_linear(expr, sym_lin, sym_const, expr_const, expr_lin, expr_nonlin);
4399 const std::vector<MatType> &sym_lin,
const std::vector<MatType> &sym_const,
4400 MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
4402 expr_const, expr_lin, expr_nonlin);
4445 inline friend casadi_int
n_nodes(
const MatType& A) {
4446 return MatType::n_nodes(A);
4483 return MatType::simplify(x);
4522 return MatType::transform(x, opts);
4525 const std::vector<std::vector<GenericType> >& passes,
const Dict& opts =
Dict()) {
4526 return MatType::transform(x, passes, opts);
4528 friend inline std::vector<MatType>
transform(
const std::vector<MatType> &x,
4530 return MatType::transform(x, opts);
4532 friend inline std::vector<MatType>
transform(
const std::vector<MatType> &x,
4533 const std::vector<std::vector<GenericType> >& passes,
const Dict& opts =
Dict()) {
4534 return MatType::transform(x, passes, opts);
4579 inline friend std::string
4581 return MatType::print_operator(xb, args);
4666 inline friend void extract(std::vector<MatType>& ex,
4667 std::vector<MatType>& v,
4668 std::vector<MatType>& vdef,
4670 MatType::extract(ex, v, vdef, opts);
4721 inline friend void shared(std::vector<MatType>& ex,
4722 std::vector<MatType>& v,
4723 std::vector<MatType>& vdef,
4724 const std::string& v_prefix=
"v_",
4725 const std::string& v_suffix=
"") {
4726 return MatType::shared(ex, v, vdef, v_prefix, v_suffix);
4771 inline friend MatType
repsum(
const MatType &A, casadi_int n, casadi_int m=1) {
4772 return MatType::repsum(A, n, m);
4821 friend inline MatType
mmin(
const MatType& x) {
4822 return MatType::mmin(x);
4861 friend inline MatType
mmax(
const MatType& x) {
4862 return MatType::mmax(x);
4868 static MatType
jtimes(
const MatType &ex,
const MatType &arg,
4869 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict());
4872 static MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
4874 static MatType
mpower(
const MatType &x,
const MatType &y);
4875 static MatType
soc(
const MatType &x,
const MatType &y);
4948 static MatType
sym(
const std::string& name, casadi_int nrow=1, casadi_int ncol=1) {
4955 static MatType
sym(
const std::string& name,
const std::pair<casadi_int, casadi_int> &rc) {
4956 return sym(name, rc.first, rc.second);
4998 return MatType::_sym(name, sp);
5033 static std::vector<MatType >
sym(
const std::string& name,
const Sparsity& sp, casadi_int p);
5063 static std::vector<MatType >
sym(
const std::string& name, casadi_int nrow,
5064 casadi_int ncol, casadi_int p) {
5074 static std::vector<std::vector<MatType> >
5075 sym(
const std::string& name,
const Sparsity& sp, casadi_int p, casadi_int r);
5106 static std::vector<std::vector<MatType> >
5107 sym(
const std::string& name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r) {
5151 static MatType
zeros(casadi_int nrow=1, casadi_int ncol=1) {
5155 static MatType
zeros(
const std::pair<casadi_int, casadi_int>& rc) {
5156 return zeros(rc.first, rc.second);
5206 static MatType
ones(casadi_int nrow=1, casadi_int ncol=1) {
5210 static MatType
ones(
const std::pair<casadi_int, casadi_int>& rc) {
5211 return ones(rc.first, rc.second);
5217 #define CASADI_THROW_ERROR(FNAME, WHAT) \
5218 throw CasadiException("Error in " + MatType::type_name() \
5219 + "::" FNAME " at " + CASADI_WHERE + ":\n" + std::string(WHAT));
5223 template<
typename MatType>
5225 return self().sparsity();
5228 template<
typename MatType>
5230 return sparsity().nnz();
5233 template<
typename MatType>
5235 return sparsity().nnz_lower();
5238 template<
typename MatType>
5240 return sparsity().nnz_upper();
5243 template<
typename MatType>
5245 return sparsity().nnz_diag();
5248 template<
typename MatType>
5250 return sparsity().numel();
5253 template<
typename MatType>
5255 return sparsity().size1();
5258 template<
typename MatType>
5260 return sparsity().size2();
5263 template<
typename MatType>
5265 return sparsity().size();
5268 template<
typename MatType>
5270 return sparsity().size(axis);
5273 template<
typename MatType>
5275 return sparsity().dim(with_nz);
5278 template<
typename MatType>
5280 return sparsity().is_scalar(scalar_and_dense);
5285 template<
typename MatType>
5287 const Sparsity& sp, casadi_int p) {
5288 std::vector<MatType> ret(p);
5289 std::stringstream ss;
5290 for (casadi_int k=0; k<p; ++k) {
5293 ret[k] = sym(ss.str(), sp);
5298 template<
typename MatType>
5302 std::vector<std::vector<MatType> > ret(r);
5303 for (casadi_int k=0; k<r; ++k) {
5304 std::stringstream ss;
5305 ss << name <<
"_" << k;
5306 ret[k] = sym(ss.str(), sp, p);
5311 template<
typename MatType>
5313 casadi_assert(nsteps>=1,
"linspace: nsteps (" + str(nsteps) +
") must be at least 1");
5314 std::vector<MatType> ret(nsteps);
5316 MatType step = (b-a)/
static_cast<MatType
>(nsteps-1);
5318 for (casadi_int i=1; i<nsteps-1; ++i)
5319 ret[i] = a + i * step;
5322 return vertcat(ret);
5325 template<
typename MatType>
5327 casadi_assert(a.size1()==b.size1() && a.size2()==b.size2(),
5328 "cross(a, b): Inconsistent dimensions. Dimension of a ("
5329 + a.dim() +
" ) must equal that of b (" + b.dim() +
").");
5331 casadi_assert(a.size1()==3 || a.size2()==3,
5332 "cross(a, b): One of the dimensions of a should have length 3, but got "
5334 casadi_assert(dim==-1 || dim==1 || dim==2,
5335 "cross(a, b, dim): Dim must be 1, 2 or -1 (automatic).");
5337 std::vector<MatType> ret(3);
5339 bool t = a.size1()==3;
5341 if (dim==1) t =
true;
5342 if (dim==2) t =
false;
5344 MatType a1 = t ? a(0, Slice()) : a(Slice(), 0);
5345 MatType a2 = t ? a(1, Slice()) : a(Slice(), 1);
5346 MatType a3 = t ? a(2, Slice()) : a(Slice(), 2);
5348 MatType b1 = t ? b(0, Slice()) : b(Slice(), 0);
5349 MatType b2 = t ? b(1, Slice()) : b(Slice(), 1);
5350 MatType b3 = t ? b(2, Slice()) : b(Slice(), 2);
5352 ret[0] = a2*b3-a3*b2;
5353 ret[1] = a3*b1-a1*b3;
5354 ret[2] = a1*b2-a2*b1;
5356 return t ? vertcat(ret) : horzcat(ret);
5360 bool equidistant=
false);
5362 template<
typename MatType>
5364 const std::vector<double>& xq,
const std::string& mode,
bool equidistant) {
5366 bool mode_floor =
false;
5367 bool mode_ceil =
false;
5368 if (mode==
"floor") {
5370 }
else if (mode==
"ceil") {
5372 }
else if (mode==
"linear") {
5375 casadi_error(
"interp1d(x, v, xq, mode): "
5376 "Mode must be 'floor', 'ceil' or 'linear'. Got '" + mode +
"' instead.");
5379 casadi_assert(
is_increasing(x),
"interp1d(x, v, xq): x must be increasing.");
5381 casadi_assert(x.size()==v.size1(),
5382 "interp1d(x, v, xq): dimensions mismatch. v expected to have " + str(x.size()) +
" rows,"
5383 " but got " + str(v.size1()) +
" instead.");
5386 casadi_assert(x.size()>=2,
"interp1d(x, v, xq): x must be at least length 2.");
5389 std::vector<double> val;
5390 std::vector<casadi_int> colind(1, 0);
5391 std::vector<casadi_int> row;
5395 for (casadi_int i=0;i<xq.size();++i) {
5399 if (mode_floor) ind = floor(ind);
5400 if (mode_ceil) ind = ceil(ind);
5404 double frac_part = modf(ind, &int_partd);
5405 casadi_int int_part =
static_cast<casadi_int
>(int_partd);
5410 row.push_back(int_part);
5412 colind.push_back(nnz);
5415 val.push_back(1-frac_part);
5416 val.push_back(frac_part);
5417 row.push_back(int_part);
5418 row.push_back(int_part+1);
5420 colind.push_back(nnz);
5425 Sparsity sp(x.size(), xq.size() , colind, row);
5427 return MatType::mtimes(MatType(sp, val).
T(), v);
5431 template<
typename MatType>
5433 casadi_assert(a.is_vector() && (a.size1()==3 || a.size2()==3),
5434 "skew(a): Expecting 3-vector, got " + a.dim() +
".");
5439 return blockcat(std::vector< std::vector<MatType> >({{0, -z, y}, {z, 0, -x}, {-y, x, 0}}));
5442 template<
typename MatType>
5444 casadi_assert(a.size1()==3 && a.size2()==3,
5445 "inv_skew(a): Expecting 3-by-3 matrix, got " + a.dim() +
".");
5447 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)}));
5451 template<
typename MatType>
5453 casadi_assert(x.is_square(),
5454 "Shape error in tril2symm. Expecting square shape but got " + x.dim());
5455 casadi_assert(x.nnz_upper()-x.nnz_diag()==0,
5456 "Sparsity error in tril2symm. Found above-diagonal entries in argument: " + x.dim());
5457 return x + x.T() - diag(diag(x));
5460 template<
typename MatType>
5462 casadi_assert(n>0 && x.size1() % n==0,
5463 "repsum: x.size1() (" + str(x.size1()) +
") must be a multiple of n (" + str(n) +
")");
5464 casadi_assert(m>0 && x.size2() % m==0,
5465 "repsum: x.size2() (" + str(x.size2()) +
") must be a multiple of m (" + str(m) +
")");
5466 std::vector< std::vector< MatType> > s =
5467 blocksplit(x, x.size1()/n, x.size2()/m);
5469 for (casadi_int i=0;i<s.size();++i) {
5470 for (casadi_int j=0;j<s[i].size();++j) {
5471 sum = sum + s[i][j];
5477 template<
typename MatType>
5479 casadi_assert(x.is_square(),
5480 "Shape error in triu2symm. Expecting square shape but got " + x.dim());
5481 casadi_assert(x.nnz_lower()-x.nnz_diag()==0,
5482 "Sparsity error in triu2symm. Found below-diagonal entries in argument: " + x.dim());
5483 return x + x.T() - diag(diag(x));
5486 template<
typename MatType>
5490 casadi_assert_dev(x.is_vector());
5491 if (!x.is_column())
return bilin(A, x.T(), y);
5492 if (!x.is_dense())
return bilin(A, densify(x), y);
5495 casadi_assert_dev(y.is_vector());
5496 if (!y.is_column())
return bilin(A, x, y.T());
5497 if (!y.is_dense())
return bilin(A, x, densify(y));
5500 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
5501 "Dimension mismatch. Got x.size1() = " + str(x.size1())
5502 +
" and y.size1() = " + str(y.size1()) +
" but A.size() = " + str(A.size()));
5505 return MatType::_bilin(A, x, y);
5508 template<
typename MatType>
5510 const MatType& x,
const MatType& y) {
5512 casadi_assert_dev(x.is_vector());
5513 if (!x.is_column())
return rank1(A, alpha, x.T(), y);
5514 if (!x.is_dense())
return rank1(A, alpha, densify(x), y);
5517 casadi_assert_dev(y.is_vector());
5518 if (!y.is_column())
return rank1(A, alpha, x, y.T());
5519 if (!y.is_dense())
return rank1(A, alpha, x, densify(y));
5522 casadi_assert_dev(
alpha.is_scalar());
5523 if (!
alpha.is_dense())
return A;
5526 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
5527 "Dimension mismatch. Got x.size1() = " + str(x.size1())
5528 +
" and y.size1() = " + str(y.size1())
5529 +
" but A.size() = " + str(A.size()));
5532 return MatType::_rank1(A, alpha, x, y);
5535 template<
typename MatType>
5537 casadi_assert(x.is_dense(),
"Argument must be dense");
5538 casadi_assert(x.is_column(),
"Argument must be column vector");
5539 casadi_assert(!x.is_empty(),
"Argument must be nonempty");
5541 return MatType::_logsumexp(x);
5544 template<
typename MatType>
5546 const MatType &v,
bool tr,
const Dict& opts) {
5550 if (ex.size2()==0 && v.size2()>0) {
5551 casadi_error(
"Ambiguous dimensions.");
5553 casadi_assert(v.size1() == ex.size1() &&
5554 (v.size2()==0 || ex.size2()==0 || v.size2() % ex.size2() == 0),
5555 "'v' has inconsistent dimensions: "
5556 " v " + v.dim(
false) +
", ex " + ex.dim(
false) +
".");
5558 if (arg.size2()==0 && v.size2()>0) {
5559 casadi_error(
"Ambiguous dimensions.");
5561 casadi_assert(v.size1() == arg.size1() &&
5562 (v.size2()==0 || arg.size2()==0 || v.size2() % arg.size2() == 0),
5563 "'v' has inconsistent dimensions: "
5564 " v " + v.dim(
false) +
", arg " + arg.dim(
false) +
".");
5567 casadi_int n_seeds = 1;
5569 if (ex.size2()>0) n_seeds = v.size2() / ex.size2();
5571 if (arg.size2()>0) n_seeds = v.size2() / arg.size2();
5575 if (v.is_empty() || ex.is_empty()) {
5576 return MatType(tr ? arg.size1() : ex.size1(),
5577 tr ? arg.size2()*n_seeds : ex.size2()*n_seeds);
5581 std::vector<MatType> w = horzsplit(v, tr ? ex.size2() : arg.size2());
5584 std::vector<std::vector<MatType> > ww(w.size());
5585 for (casadi_int i=0; i<w.size(); ++i) ww[i] = {w[i]};
5589 ww = reverse({ex}, {arg}, ww, opts);
5591 ww = forward({ex}, {arg}, ww, opts);
5595 for (casadi_int i=0; i<w.size(); ++i) w[i] = ww[i][0];
5597 }
catch (std::exception& e) {
5598 CASADI_THROW_ERROR(
"jtimes", e.what());
5602 template<
typename MatType>
5606 casadi_assert(ex.is_scalar(),
5607 "'gradient' only defined for scalar outputs: Use 'jacobian' instead.");
5608 return project(jtimes(ex, arg, MatType::ones(ex.sparsity()),
true, opts), arg.sparsity());
5609 }
catch (std::exception& e) {
5610 CASADI_THROW_ERROR(
"gradient", e.what());
5614 template<
typename MatType>
5618 casadi_assert(arg.is_scalar(),
5619 "'tangent' only defined for scalar inputs: Use 'jacobian' instead.");
5620 return project(jtimes(ex, arg, MatType::ones(arg.sparsity()),
false, opts), ex.sparsity());
5621 }
catch (std::exception& e) {
5622 CASADI_THROW_ERROR(
"tangent", e.what());
5626 template<
typename MatType>
5628 linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
const Dict& opts) {
5629 MatType x_lin = MatType::sym(
"x_lin", x.sparsity());
5631 if (x0.size() != x.size()) {
5633 if (x0.sparsity().is_scalar()) {
5634 return linearize(f, x, MatType(x.sparsity(), x0));
5636 casadi_error(
"Dimension mismatch in 'linearize'");
5638 return substitute(f + jtimes(f, x, x_lin,
false, opts),
5639 MatType::vertcat({x_lin, x}), MatType::vertcat({x, x0}));
5642 template<
typename MatType>
5645 if (a.is_scalar() &&
b.is_scalar())
return pow(a, b);
5646 casadi_assert(a.is_square() &&
b.is_constant() &&
b.is_scalar(),
5648 double bv =
static_cast<double>(
b);
5649 casadi_int N =
static_cast<casadi_int
>(bv);
5650 casadi_assert(bv-
static_cast<double>(N)==0,
"mpower only defined for integer powers.");
5651 casadi_assert(bv==N,
"Not Implemented");
5652 if (N<0)
return inv(mpower(a, -N));
5653 if (N==0)
return MatType::eye(a.size1());
5656 MatType h = mpower(a, N/2);
5657 return MatType::mtimes(h, h);
5659 return MatType::mtimes(mpower(a, N-1), a);
5663 template<
typename MatType>
5666 casadi_assert(y.is_scalar(),
"y needs to be scalar. Got " + y.dim() +
".");
5667 casadi_assert(x.is_vector(),
"x needs to be a vector. Got " + x.dim() +
".");
5669 MatType x_col = x.is_column() ? x : x.T();
5671 x_col = x_col.nz(Slice());
5673 casadi_int n = x_col.numel();
5674 return blockcat(y*MatType::eye(n), x_col, x_col.T(), y);
5677 template<
typename MatType>
5679 return !any(MatType::which_depends(expr, var, 2,
true));
5682 template<
typename MatType>
5684 return is_linear(gradient(expr, var), var);
5687 template<
typename MatType>
5689 MatType& A, MatType& b, MatType& c,
bool check) {
5690 casadi_assert(expr.is_scalar(),
"'quadratic_coeff' only defined for scalar expressions.");
5691 A = hessian(expr, var);
5692 b = substitute(jacobian(expr, var), var, 0).T();
5694 casadi_assert(!depends_on(A, var),
"'quadratic_coeff' called on non-quadratic expression.");
5695 c = substitute(expr, var, 0);
5698 template<
typename MatType>
5700 MatType& A, MatType& b,
bool check) {
5701 casadi_assert(expr.is_vector(),
"'linear_coeff' only defined for vector expressions.");
5703 casadi_assert(is_linear(expr, var),
"'linear_coeff' called on non-linear expression.");
5704 A = substitute(jacobian(expr, var), var, 0);
5705 b = vec(substitute(expr, var, 0));
5708 template<
typename MatType>
5710 casadi_assert(axis==-1 || axis==0 || axis==1,
"Axis argument invalid");
5711 casadi_assert(n>=1,
"n argument invalid");
5714 for (casadi_int i=0;i<n;++i) {
5716 if (axis==-1 && ret.is_scalar())
return MatType();
5718 casadi_int local_axis = (axis==-1) ? ret.is_row() : axis;
5719 if (local_axis==0) {
5720 if (ret.size1()<=1) {
5721 ret = MatType::zeros(0, ret.size2());
5723 ret = ret(Slice(1, ret.size1()), Slice())-ret(Slice(0, ret.size1()-1), Slice());
5726 if (ret.size2()<=1) {
5727 ret = MatType::zeros(ret.size1(), 0);
5729 ret = ret(Slice(), Slice(1, ret.size2()))-ret(Slice(), Slice(0, ret.size2()-1));
5736 #undef CASADI_THROW_ERROR
casadi_int numel() const
Get the number of elements, size1()*size2()
Sparsity sparsity() const
Get the sparsity pattern.
bool is_dense() const
Check if the matrix is dense, i.e. nnz() equals numel()
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 matrix 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 nonzeros.
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 (same as size1())
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, as a pair (nrow, ncol)
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 list of length p of nrow-by-ncol symbolic primitives.
casadi_int size(casadi_int axis) const
Get the size along a particular dimension.
casadi_int nnz_upper() const
Get the number of structural nonzeros on or above the diagonal.
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 the number of structural nonzeros 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 list of length r of lists of length p of nrow-by-ncol symbolic primitives.
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 is square, i.e. size1() equals size2()
static std::vector< MatType > sym(const std::string &name, const Sparsity &sp, casadi_int p)
Create a list of length p of symbolic primitives with a given sparsity.
casadi_int columns() const
Get the number of columns, Octave-style syntax (same as size2())
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 list of length r of lists of length p of symbolic primitives.
std::pair< casadi_int, casadi_int > size() const
Get the shape as a pair (number of rows, number of columns)
casadi_int nnz_lower() const
Get the number of structural nonzeros on or below the diagonal.
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix is scalar, i.e. 1-by-1.
casadi_int colind(casadi_int cc) const
Index of the first nonzero of column cc.
bool is_vector() const
Check whether the pattern is a row or a 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
Column offsets of the compressed column storage.
bool is_column() const
Check whether the pattern is a column vector, i.e. size2() == 1.
bool is_row() const
Check whether the pattern is a row vector, i.e. size1() == 1.
bool is_tril(bool strictly=false) const
Check whether all nonzeros are on or below the diagonal (row >= col)
casadi_int row(casadi_int el) const
Row index of nonzero el.
bool is_empty(bool both=false) const
Check whether the pattern has a zero dimension.
bool is_dense() const
Check whether every entry is a structural nonzero, i.e. nnz() == numel()
bool is_square() const
Check whether the number of rows equals the number of columns.
bool is_triu(bool strictly=false) const
Check whether all nonzeros are on or above the diagonal (row <= col)
std::vector< casadi_int > get_row() const
Row index of every nonzero, in nonzero (column-major) order.
const long double alpha[8][8]
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.