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
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);
657 inline friend bool depends_on(
const MatType& f,
const MatType &arg) {
658 return MatType::depends_on(f, arg);
664 friend inline MatType
substitute(
const MatType& ex,
const MatType& v,
665 const MatType& vdef) {
666 return MatType::substitute(ex, v, vdef);
672 friend inline std::vector<MatType>
673 substitute(
const std::vector<MatType>& ex,
const std::vector<MatType>& v,
674 const std::vector<MatType>& vdef) {
675 return MatType::substitute(ex, v, vdef);
686 std::vector<MatType>& inout_vdef,
687 std::vector<MatType>& inout_ex,
bool reverse=
false) {
688 return MatType::substitute_inplace(v, inout_vdef, inout_ex,
reverse);
694 inline friend MatType
cse(
const MatType& e) {
695 return MatType::cse({e}).at(0);
702 inline friend std::vector<MatType>
cse(
const std::vector<MatType>& e) {
703 return MatType::cse(e);
724 friend inline MatType
solve(
const MatType& A,
const MatType& b) {
725 return MatType::solve(A, b);
731 friend inline MatType
solve(
const MatType& A,
const MatType& b,
732 const std::string& lsolver,
734 return MatType::solve(A, b, lsolver, dict);
740 friend inline MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
742 return MatType::linearize(f, x, x0, opts);
757 friend inline MatType
pinv(
const MatType& A) {
758 return MatType::pinv(A);
767 friend inline MatType
pinv(
const MatType& A,
const std::string& lsolver,
769 return MatType::pinv(A, lsolver, dict);
782 friend inline MatType
expm_const(
const MatType& A,
const MatType& t) {
783 return MatType::expm_const(A, t);
790 friend inline MatType
expm(
const MatType& A) {
791 return MatType::expm(A);
799 inline friend MatType
jacobian(
const MatType &ex,
const MatType &arg,
801 return MatType::jacobian(ex, arg, opts);
812 inline friend MatType
gradient(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
813 return MatType::gradient(ex, arg, opts);
819 inline friend MatType
tangent(
const MatType &ex,
const MatType &arg,
const Dict& opts=
Dict()) {
820 return MatType::tangent(ex, arg, opts);
832 friend inline MatType
jtimes(
const MatType &ex,
const MatType &arg,
833 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict()) {
834 return MatType::jtimes(ex, arg, v, tr, opts);
840 friend inline std::vector<std::vector<MatType> >
841 forward(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
842 const std::vector<std::vector<MatType> > &v,
844 return MatType::forward(ex, arg, v, opts);
850 friend inline std::vector<std::vector<MatType> >
851 reverse(
const std::vector<MatType> &ex,
const std::vector<MatType> &arg,
852 const std::vector<std::vector<MatType> > &v,
854 return MatType::reverse(ex, arg, v, opts);
861 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg,
863 return MatType::hessian(ex, arg, opts);
865 inline friend MatType
hessian(
const MatType &ex,
const MatType &arg, MatType& output_g,
867 return MatType::hessian(ex, arg, output_g, opts);
874 inline friend std::vector<bool>
which_depends(
const MatType &expr,
const MatType &var,
875 casadi_int order,
bool tr) {
876 return MatType::which_depends(expr, var, order, tr);
885 return MatType::jacobian_sparsity(f, x);
895 inline friend bool is_linear(
const MatType &expr,
const MatType &var) {
896 return MatType::is_linear(expr, var);
906 inline friend bool is_quadratic(
const MatType &expr,
const MatType &var) {
907 return MatType::is_quadratic(expr, var);
921 MatType& A, MatType& b, MatType& c,
bool check=
true) {
922 MatType::quadratic_coeff(expr, var, A, b, c, check);
933 inline friend void linear_coeff(
const MatType &expr,
const MatType &var,
934 MatType& A, MatType& b,
bool check=
true) {
935 MatType::linear_coeff(expr, var, A, b, check);
939 inline friend casadi_int
n_nodes(
const MatType& A) {
940 return MatType::n_nodes(A);
945 return MatType::simplify(x);
951 inline friend std::string
953 return MatType::print_operator(xb, args);
959 inline friend void extract(std::vector<MatType>& ex,
960 std::vector<MatType>& v,
961 std::vector<MatType>& vdef,
963 MatType::extract(ex, v, vdef, opts);
969 inline friend void shared(std::vector<MatType>& ex,
970 std::vector<MatType>& v,
971 std::vector<MatType>& vdef,
972 const std::string& v_prefix=
"v_",
973 const std::string& v_suffix=
"") {
974 return MatType::shared(ex, v, vdef, v_prefix, v_suffix);
980 inline friend MatType
repsum(
const MatType &A, casadi_int n, casadi_int m=1) {
981 return MatType::repsum(A, n, m);
988 friend inline MatType
mmin(
const MatType& x) {
989 return MatType::mmin(x);
997 friend inline MatType
mmax(
const MatType& x) {
998 return MatType::mmax(x);
1004 static MatType
jtimes(
const MatType &ex,
const MatType &arg,
1005 const MatType &v,
bool tr=
false,
const Dict& opts=
Dict());
1008 static MatType
linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
1010 static MatType
mpower(
const MatType &x,
const MatType &y);
1011 static MatType
soc(
const MatType &x,
const MatType &y);
1027 static MatType
sym(
const std::string& name, casadi_int nrow=1, casadi_int ncol=1) {
1034 static MatType
sym(
const std::string& name,
const std::pair<casadi_int, casadi_int> &rc) {
1035 return sym(name, rc.first, rc.second);
1042 return MatType::_sym(name, sp);
1050 static std::vector<MatType >
sym(
const std::string& name,
const Sparsity& sp, casadi_int p);
1055 static std::vector<MatType >
sym(
const std::string& name, casadi_int nrow,
1056 casadi_int ncol, casadi_int p) {
1065 static std::vector<std::vector<MatType> >
1066 sym(
const std::string& name,
const Sparsity& sp, casadi_int p, casadi_int r);
1073 static std::vector<std::vector<MatType> >
1074 sym(
const std::string& name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r) {
1083 static MatType
zeros(casadi_int nrow=1, casadi_int ncol=1) {
1087 static MatType
zeros(
const std::pair<casadi_int, casadi_int>& rc) {
1088 return zeros(rc.first, rc.second);
1096 static MatType
ones(casadi_int nrow=1, casadi_int ncol=1) {
1100 static MatType
ones(
const std::pair<casadi_int, casadi_int>& rc) {
1101 return ones(rc.first, rc.second);
1107 #define CASADI_THROW_ERROR(FNAME, WHAT) \
1108 throw CasadiException("Error in " + MatType::type_name() \
1109 + "::" FNAME " at " + CASADI_WHERE + ":\n" + std::string(WHAT));
1113 template<
typename MatType>
1115 return self().sparsity();
1118 template<
typename MatType>
1120 return sparsity().nnz();
1123 template<
typename MatType>
1125 return sparsity().nnz_lower();
1128 template<
typename MatType>
1130 return sparsity().nnz_upper();
1133 template<
typename MatType>
1135 return sparsity().nnz_diag();
1138 template<
typename MatType>
1140 return sparsity().numel();
1143 template<
typename MatType>
1145 return sparsity().size1();
1148 template<
typename MatType>
1150 return sparsity().size2();
1153 template<
typename MatType>
1155 return sparsity().size();
1158 template<
typename MatType>
1160 return sparsity().size(axis);
1163 template<
typename MatType>
1165 return sparsity().dim(with_nz);
1168 template<
typename MatType>
1170 return sparsity().is_scalar(scalar_and_dense);
1175 template<
typename MatType>
1177 const Sparsity& sp, casadi_int p) {
1178 std::vector<MatType> ret(p);
1179 std::stringstream ss;
1180 for (casadi_int k=0; k<p; ++k) {
1183 ret[k] = sym(ss.str(), sp);
1188 template<
typename MatType>
1192 std::vector<std::vector<MatType> > ret(r);
1193 for (casadi_int k=0; k<r; ++k) {
1194 std::stringstream ss;
1195 ss << name <<
"_" << k;
1196 ret[k] = sym(ss.str(), sp, p);
1201 template<
typename MatType>
1203 std::vector<MatType> ret(nsteps);
1205 MatType step = (b-a)/
static_cast<MatType
>(nsteps-1);
1207 for (casadi_int i=1; i<nsteps-1; ++i)
1208 ret[i] = a + i * step;
1211 return vertcat(ret);
1214 template<
typename MatType>
1216 casadi_assert(a.size1()==b.size1() && a.size2()==b.size2(),
1217 "cross(a, b): Inconsistent dimensions. Dimension of a ("
1218 + a.dim() +
" ) must equal that of b (" + b.dim() +
").");
1220 casadi_assert(a.size1()==3 || a.size2()==3,
1221 "cross(a, b): One of the dimensions of a should have length 3, but got "
1223 casadi_assert(dim==-1 || dim==1 || dim==2,
1224 "cross(a, b, dim): Dim must be 1, 2 or -1 (automatic).");
1226 std::vector<MatType> ret(3);
1228 bool t = a.size1()==3;
1230 if (dim==1) t =
true;
1231 if (dim==2) t =
false;
1233 MatType a1 = t ? a(0, Slice()) : a(Slice(), 0);
1234 MatType a2 = t ? a(1, Slice()) : a(Slice(), 1);
1235 MatType a3 = t ? a(2, Slice()) : a(Slice(), 2);
1237 MatType b1 = t ? b(0, Slice()) : b(Slice(), 0);
1238 MatType b2 = t ? b(1, Slice()) : b(Slice(), 1);
1239 MatType b3 = t ? b(2, Slice()) : b(Slice(), 2);
1241 ret[0] = a2*b3-a3*b2;
1242 ret[1] = a3*b1-a1*b3;
1243 ret[2] = a1*b2-a2*b1;
1245 return t ? vertcat(ret) : horzcat(ret);
1249 bool equidistant=
false);
1251 template<
typename MatType>
1253 const std::vector<double>& xq,
const std::string& mode,
bool equidistant) {
1255 bool mode_floor = mode ==
"floor";
1256 bool mode_ceil = mode ==
"ceil";
1260 casadi_assert(x.size()==v.size1(),
1261 "interp1d(x, v, xq): dimensions mismatch. v expected to have " + str(x.size()) +
" rows,"
1262 " but got " + str(v.size1()) +
" instead.");
1265 casadi_assert(x.size()>=2,
"interp1d(x, v, xq): x must be at least length 2.");
1268 std::vector<double> val;
1269 std::vector<casadi_int> colind(1, 0);
1270 std::vector<casadi_int> row;
1274 for (casadi_int i=0;i<xq.size();++i) {
1278 if (mode_floor) ind = floor(ind);
1279 if (mode_ceil) ind = ceil(ind);
1283 double frac_part = modf(ind, &int_partd);
1284 casadi_int int_part =
static_cast<casadi_int
>(int_partd);
1289 row.push_back(int_part);
1291 colind.push_back(nnz);
1294 val.push_back(1-frac_part);
1295 val.push_back(frac_part);
1296 row.push_back(int_part);
1297 row.push_back(int_part+1);
1299 colind.push_back(nnz);
1304 Sparsity sp(x.size(), xq.size() , colind, row);
1306 return MatType::mtimes(MatType(sp, val).T(), v);
1310 template<
typename MatType>
1312 casadi_assert(a.is_vector() && (a.size1()==3 || a.size2()==3),
1313 "skew(a): Expecting 3-vector, got " + a.dim() +
".");
1318 return blockcat(std::vector< std::vector<MatType> >({{0, -z, y}, {z, 0, -x}, {-y, x, 0}}));
1321 template<
typename MatType>
1323 casadi_assert(a.size1()==3 && a.size2()==3,
1324 "inv_skew(a): Expecting 3-by-3 matrix, got " + a.dim() +
".");
1326 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)}));
1330 template<
typename MatType>
1332 casadi_assert(x.is_square(),
1333 "Shape error in tril2symm. Expecting square shape but got " + x.dim());
1334 casadi_assert(x.nnz_upper()-x.nnz_diag()==0,
1335 "Sparsity error in tril2symm. Found above-diagonal entries in argument: " + x.dim());
1336 return x + x.T() - diag(diag(x));
1339 template<
typename MatType>
1341 casadi_assert_dev(x.size1() % n==0);
1342 casadi_assert_dev(x.size2() % m==0);
1343 std::vector< std::vector< MatType> > s =
1344 blocksplit(x, x.size1()/n, x.size2()/m);
1346 for (casadi_int i=0;i<s.size();++i) {
1347 for (casadi_int j=0;j<s[i].size();++j) {
1348 sum = sum + s[i][j];
1354 template<
typename MatType>
1356 casadi_assert(x.is_square(),
1357 "Shape error in triu2symm. Expecting square shape but got " + x.dim());
1358 casadi_assert(x.nnz_lower()-x.nnz_diag()==0,
1359 "Sparsity error in triu2symm. Found below-diagonal entries in argument: " + x.dim());
1360 return x + x.T() - diag(diag(x));
1363 template<
typename MatType>
1367 casadi_assert_dev(x.is_vector());
1368 if (!x.is_column())
return bilin(A, x.T(), y);
1369 if (!x.is_dense())
return bilin(A, densify(x), y);
1372 casadi_assert_dev(y.is_vector());
1373 if (!y.is_column())
return bilin(A, x, y.T());
1374 if (!y.is_dense())
return bilin(A, x, densify(y));
1377 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1378 "Dimension mismatch. Got x.size1() = " + str(x.size1())
1379 +
" and y.size1() = " + str(y.size1()) +
" but A.size() = " + str(A.size()));
1382 return MatType::_bilin(A, x, y);
1385 template<
typename MatType>
1387 const MatType& x,
const MatType& y) {
1389 casadi_assert_dev(x.is_vector());
1390 if (!x.is_column())
return rank1(A, alpha, x.T(), y);
1391 if (!x.is_dense())
return rank1(A, alpha, densify(x), y);
1394 casadi_assert_dev(y.is_vector());
1395 if (!y.is_column())
return rank1(A, alpha, x, y.T());
1396 if (!y.is_dense())
return rank1(A, alpha, x, densify(y));
1399 casadi_assert_dev(alpha.is_scalar());
1400 if (!alpha.is_dense())
return A;
1403 casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1404 "Dimension mismatch. Got x.size1() = " + str(x.size1())
1405 +
" and y.size1() = " + str(y.size1())
1406 +
" but A.size() = " + str(A.size()));
1409 return MatType::_rank1(A, alpha, x, y);
1412 template<
typename MatType>
1414 casadi_assert(x.is_dense(),
"Argument must be dense");
1415 casadi_assert(x.is_column(),
"Argument must be column vector");
1417 return MatType::_logsumexp(x);
1420 template<
typename MatType>
1422 const MatType &v,
bool tr,
const Dict& opts) {
1426 casadi_assert(v.size1() == ex.size1() && v.size2() % ex.size2() == 0,
1427 "'v' has inconsistent dimensions: "
1428 " v " + v.dim(
false) +
", ex " + ex.dim(
false) +
".");
1430 casadi_assert(v.size1() == arg.size1() && v.size2() % arg.size2() == 0,
1431 "'v' has inconsistent dimensions: "
1432 " v " + v.dim(
false) +
", arg " + arg.dim(
false) +
".");
1436 if (v.is_empty())
return MatType(tr ? arg.size1() : ex.size1(), 0);
1439 std::vector<MatType> w = horzsplit(v, tr ? ex.size2() : arg.size2());
1442 std::vector<std::vector<MatType> > ww(w.size());
1443 for (casadi_int i=0; i<w.size(); ++i) ww[i] = {w[i]};
1447 ww = reverse({ex}, {arg}, ww, opts);
1449 ww = forward({ex}, {arg}, ww, opts);
1453 for (casadi_int i=0; i<w.size(); ++i) w[i] = ww[i][0];
1455 }
catch (std::exception& e) {
1456 CASADI_THROW_ERROR(
"jtimes", e.what());
1460 template<
typename MatType>
1464 casadi_assert(ex.is_scalar(),
1465 "'gradient' only defined for scalar outputs: Use 'jacobian' instead.");
1466 return project(jtimes(ex, arg, MatType::ones(ex.sparsity()),
true, opts), arg.sparsity());
1467 }
catch (std::exception& e) {
1468 CASADI_THROW_ERROR(
"gradient", e.what());
1472 template<
typename MatType>
1476 casadi_assert(arg.is_scalar(),
1477 "'tangent' only defined for scalar inputs: Use 'jacobian' instead.");
1478 return project(jtimes(ex, arg, MatType::ones(arg.sparsity()),
false, opts), ex.sparsity());
1479 }
catch (std::exception& e) {
1480 CASADI_THROW_ERROR(
"tangent", e.what());
1484 template<
typename MatType>
1486 linearize(
const MatType& f,
const MatType& x,
const MatType& x0,
const Dict& opts) {
1487 MatType x_lin = MatType::sym(
"x_lin", x.sparsity());
1489 if (x0.size() != x.size()) {
1491 if (x0.sparsity().is_scalar()) {
1492 return linearize(f, x, MatType(x.sparsity(), x0));
1494 casadi_error(
"Dimension mismatch in 'linearize'");
1496 return substitute(f + jtimes(f, x, x_lin,
false, opts),
1497 MatType::vertcat({x_lin, x}), MatType::vertcat({x, x0}));
1500 template<
typename MatType>
1503 if (a.is_scalar() && b.is_scalar())
return pow(a, b);
1504 casadi_assert(a.is_square() && b.is_constant() && b.is_scalar(),
1506 double bv =
static_cast<double>(b);
1507 casadi_int N =
static_cast<casadi_int
>(bv);
1508 casadi_assert(bv-
static_cast<double>(N)==0,
"mpower only defined for integer powers.");
1509 casadi_assert(bv==N,
"Not Implemented");
1510 if (N<0)
return inv(mpower(a, -N));
1511 if (N==0)
return MatType::eye(a.size1());
1514 MatType h = mpower(a, N/2);
1515 return MatType::mtimes(h, h);
1517 return MatType::mtimes(mpower(a, N-1), a);
1521 template<
typename MatType>
1524 casadi_assert(y.is_scalar(),
"y needs to be scalar. Got " + y.dim() +
".");
1525 casadi_assert(x.is_vector(),
"x needs to be a vector. Got " + x.dim() +
".");
1527 MatType x_col = x.is_column() ? x : x.T();
1529 x_col = x_col.nz(Slice());
1531 casadi_int n = x_col.numel();
1532 return blockcat(y*MatType::eye(n), x_col, x_col.T(), y);
1535 template<
typename MatType>
1537 return !any(MatType::which_depends(expr, var, 2,
true));
1540 template<
typename MatType>
1542 return is_linear(gradient(expr, var), var);
1545 template<
typename MatType>
1547 MatType& A, MatType& b, MatType& c,
bool check) {
1548 casadi_assert(expr.is_scalar(),
"'quadratic_coeff' only defined for scalar expressions.");
1549 A = hessian(expr, var);
1550 b = substitute(jacobian(expr, var), var, 0).T();
1552 casadi_assert(!depends_on(A, var),
"'quadratic_coeff' called on non-quadratic expression.");
1553 c = substitute(expr, var, 0);
1556 template<
typename MatType>
1558 MatType& A, MatType& b,
bool check) {
1559 casadi_assert(expr.is_vector(),
"'linear_coeff' only defined for vector expressions.");
1561 casadi_assert(is_linear(expr, var),
"'linear_coeff' called on non-linear expression.");
1562 A = substitute(jacobian(expr, var), var, 0);
1563 b = vec(substitute(expr, var, 0));
1566 template<
typename MatType>
1568 casadi_assert(axis==-1 || axis==0 || axis==1,
"Axis argument invalid");
1569 casadi_assert(n>=1,
"n argument invalid");
1572 for (casadi_int i=0;i<n;++i) {
1574 if (axis==-1 && ret.is_scalar())
return MatType();
1576 casadi_int local_axis = (axis==-1) ? ret.is_row() : axis;
1577 if (local_axis==0) {
1578 if (ret.size1()<=1) {
1579 ret = MatType::zeros(0, ret.size2());
1581 ret = ret(Slice(1, ret.size1()), Slice())-ret(Slice(0, ret.size1()-1), Slice());
1584 if (ret.size2()<=1) {
1585 ret = MatType::zeros(ret.size1(), 0);
1587 ret = ret(Slice(), Slice(1, ret.size2()))-ret(Slice(), Slice(0, ret.size2()-1));
1594 #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.