generic_matrix.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_GENERIC_MATRIX_HPP
27 #define CASADI_GENERIC_MATRIX_HPP
28 
29 #include "slice.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"
36 
37 namespace casadi {
43  struct CASADI_EXPORT GenericMatrixCommon {};
44 
74  template<typename MatType>
76  : public GenericMatrixCommon,
77  public SWIG_IF_ELSE(SparsityInterfaceCommon, SparsityInterface<MatType>) {
78  using SparsityInterface<MatType>::self;
79  public:
80 
84  casadi_int nnz() const;
85 
89  casadi_int nnz_lower() const;
90 
94  casadi_int nnz_upper() const;
95 
99  casadi_int nnz_diag() const;
100 
104  casadi_int numel() const;
105 
109  casadi_int size1() const;
110 
114  casadi_int rows() const {return size1();}
115 
119  casadi_int size2() const;
120 
124  casadi_int columns() const {return size2();}
125 
131  std::string dim(bool with_nz=false) const;
132 
136  std::pair<casadi_int, casadi_int> size() const;
137 
141  casadi_int size(casadi_int axis) const;
142 
148  bool is_empty(bool both=false) const { return sparsity().is_empty(both);}
149 
153  bool is_dense() const { return sparsity().is_dense();}
154 
158  bool is_scalar(bool scalar_and_dense=false) const;
159 
163  bool is_square() const { return sparsity().is_square();}
164 
168  bool is_vector() const { return sparsity().is_vector();}
169 
173  bool is_row() const { return sparsity().is_row();}
174 
178  bool is_column() const { return sparsity().is_column();}
179 
183  bool is_triu() const { return sparsity().is_triu();}
184 
188  bool is_tril() const { return sparsity().is_tril();}
189 
191 
194  std::vector<casadi_int> get_row() const { return sparsity().get_row(); }
195  std::vector<casadi_int> get_colind() const { return sparsity().get_colind(); }
196 #ifndef SWIG
197  const casadi_int* row() const { return sparsity().row(); }
198  const casadi_int* colind() const { return sparsity().colind(); }
199 #endif
200  casadi_int row(casadi_int el) const { return sparsity().row(el); }
201  casadi_int colind(casadi_int col) const { return sparsity().colind(col); }
203 
207  SWIG_CONSTREF(Sparsity) sparsity() const;
208 
209 #ifndef SWIG
211 
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());
218  }
219  static MatType tril(const MatType &x, bool includeDiagonal=true) {
220  return project(x, Sparsity::tril(x.sparsity(), includeDiagonal));
221  }
222  static MatType triu(const MatType &x, bool includeDiagonal=true) {
223  return project(x, Sparsity::triu(x.sparsity(), includeDiagonal));
224  }
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);
234 
235  static bool is_linear(const MatType &expr, const MatType &var);
236  static bool is_quadratic(const MatType &expr, const MatType &var);
237  static void quadratic_coeff(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);
243 
247  template<typename K>
248  const MatType nz(const K& k) const {
249  MatType ret;
250  self().get_nz(ret, false, k);
251  return ret;
252  }
253 
257  template<typename K>
258  NonZeros<MatType, K> nz(const K& k) {
259  return NonZeros<MatType, K>(self(), k);
260  }
261 
265  template<typename RR>
266  const MatType operator()(const RR& rr) const {
267  MatType ret;
268  self().get(ret, false, rr);
269  return ret;
270  }
271 
275  template<typename RR, typename CC>
276  const MatType operator()(const RR& rr, const CC& cc) const {
277  MatType ret;
278  self().get(ret, false, rr, cc);
279  return ret;
280  }
281 
285  template<typename RR>
286  SubIndex<MatType, RR> operator()(const RR& rr) {
287  return SubIndex<MatType, RR>(self(), rr);
288  }
289 
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);
296  }
297 #endif // SWIG
298 
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);
314  }
315 
319  inline friend MatType mpower(const MatType& x, const MatType& n) {
320  return MatType::mpower(x, n);
321  }
322 
334  inline friend MatType soc(const MatType& x, const MatType& y) {
335  return MatType::soc(x, y);
336  }
337 
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);
361  }
362 
363  inline friend MatType
364  einstein(const MatType &A, const MatType &B,
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);
370  }
372 
376  inline friend MatType mrdivide(const MatType& x, const MatType& n) {
377  return MatType::mrdivide(x, n);
378  }
379 
383  inline friend MatType mldivide(const MatType& x, const MatType& n) {
384  return MatType::mldivide(x, n);
385  }
386 
393  inline friend std::vector<MatType> symvar(const MatType& x) {
394  return MatType::symvar(x);
395  }
396 
398 
403  inline friend MatType bilin(const MatType &A, const MatType &x, const MatType &y) {
404  return MatType::bilin(A, x, y);
405  }
406  inline friend MatType bilin(const MatType &A, const MatType &x) {
407  return MatType::bilin(A, x, x);
408  }
409  static MatType bilin(const MatType& A, const MatType& x, const MatType& y);
411 
413 
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);
421  }
422  static MatType rank1(const MatType& A, const MatType& alpha,
423  const MatType& x, const MatType& y);
425 
429  inline friend MatType sumsqr(const MatType &x) {
430  return MatType::sumsqr(x);
431  }
432 
443  inline friend MatType logsumexp(const MatType& x) {
444  return MatType::logsumexp(x);
445  }
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;
454  }
455  static MatType logsumexp(const MatType& x);
456 
460  inline friend MatType linspace(const MatType &a, const MatType &b, casadi_int nsteps) {
461  return MatType::linspace(a, b, nsteps);
462  }
463 
467  inline friend MatType cross(const MatType &a, const MatType &b, casadi_int dim = -1) {
468  return MatType::cross(a, b, dim);
469  }
470 
474  inline friend MatType skew(const MatType &a) {
475  return MatType::skew(a);
476  }
477 
481  inline friend MatType inv_skew(const MatType &a) {
482  return MatType::inv_skew(a);
483  }
484 
488  inline friend MatType det(const MatType& A) { return MatType::det(A);}
489 
493  inline friend MatType det(const MatType& A, const std::string& lsolver,
494  const Dict& dict=Dict()) {
495  return MatType::det(A, lsolver, dict);
496  }
497 
501  inline friend MatType inv_minor(const MatType& A) { return MatType::inv_minor(A);}
502 
506  inline friend MatType inv(const MatType& A) {
507  return MatType::inv(A);
508  }
509 
513  inline friend MatType inv(const MatType& A,
514  const std::string& lsolver,
515  const Dict& options=Dict()) {
516  return MatType::inv(A, lsolver, options);
517  }
518 
522  inline friend MatType trace(const MatType& x) { return MatType::trace(x);}
523 
527  inline friend MatType tril2symm(const MatType &a) { return MatType::tril2symm(a);}
528 
532  inline friend MatType triu2symm(const MatType &a) { return MatType::triu2symm(a);}
533 
537  inline friend MatType norm_fro(const MatType &x) { return MatType::norm_fro(x);}
538 
542  inline friend MatType norm_2(const MatType &x) { return MatType::norm_2(x);}
543 
547  inline friend MatType norm_1(const MatType &x) { return MatType::norm_1(x);}
548 
552  inline friend MatType norm_inf(const MatType &x) { return MatType::norm_inf(x);}
553 
557  inline friend MatType diff(const MatType &x, casadi_int n=1, casadi_int axis=-1) {
558  return MatType::diff(x, n, axis);
559  }
560 
564  inline friend MatType cumsum(const MatType &x, casadi_int axis=-1) {
565  return MatType::cumsum(x, axis);
566  }
567 
573  inline friend MatType dot(const MatType &x, const MatType &y) {
574  return MatType::dot(x, y);
575  }
576 
587  inline friend MatType nullspace(const MatType& A) {
588  return MatType::nullspace(A);
589  }
590 
594  inline friend MatType polyval(const MatType& p, const MatType& x) {
595  return MatType::polyval(p, x);
596  }
597 
604  inline friend MatType diag(const MatType &A) {
605  return MatType::diag(A);
606  }
607 
611  inline friend MatType unite(const MatType& A, const MatType& B) {
612  return MatType::unite(A, B);
613  }
614 
618  inline friend MatType densify(const MatType& x) {
619  return MatType::densify(x);
620  }
621 
625  inline friend MatType densify(const MatType& x, const MatType& val) {
626  return MatType::densify(x, val);
627  }
628 
634  inline friend MatType project(const MatType& A, const Sparsity& sp,
635  bool intersect=false) {
636  return MatType::project(A, sp, intersect);
637  }
638 
644  inline friend MatType if_else(const MatType &cond, const MatType &if_true,
645  const MatType &if_false, bool short_circuit=false) {
646  return MatType::if_else(cond, if_true, if_false, short_circuit);
647  }
648 
655  inline friend MatType conditional(const MatType& ind, const std::vector<MatType> &x,
656  const MatType &x_default, bool short_circuit=false) {
657  return MatType::conditional(ind, x, x_default, short_circuit);
658  }
659 
673  inline friend bool depends_on(const MatType& f, const MatType &arg) {
674  return MatType::depends_on(f, arg);
675  }
676 
693  inline friend bool contains(const std::vector<MatType>& v, const MatType &n) {
694  return contains_all(v, std::vector<MatType>{n});
695  }
696 
697  inline friend bool contains_all(const std::vector<MatType>& v, const std::vector<MatType> &n) {
698  return MatType::contains_all(v, n);
699  }
700 
701  inline friend bool contains_any(const std::vector<MatType>& v, const std::vector<MatType> &n) {
702  return MatType::contains_any(v, n);
703  }
705 
709  friend inline MatType substitute(const MatType& ex, const MatType& v,
710  const MatType& vdef) {
711  return MatType::substitute(ex, v, vdef);
712  }
713 
717  friend inline std::vector<MatType>
718  substitute(const std::vector<MatType>& ex, const std::vector<MatType>& v,
719  const std::vector<MatType>& vdef) {
720  return MatType::substitute(ex, v, vdef);
721  }
722 
729  inline friend void
730  substitute_inplace(const std::vector<MatType>& v,
731  std::vector<MatType>& inout_vdef,
732  std::vector<MatType>& inout_ex, bool reverse=false) {
733  return MatType::substitute_inplace(v, inout_vdef, inout_ex, reverse);
734  }
735 
739  inline friend MatType cse(const MatType& e) {
740  return MatType::cse({e}).at(0);
741  }
742 
743 
747  inline friend std::vector<MatType> cse(const std::vector<MatType>& e) {
748  return MatType::cse(e);
749  }
750 
769  friend inline MatType solve(const MatType& A, const MatType& b) {
770  // If A is scalar, just divide
771  if (A.is_scalar()) return b/A;
772  return MatType::solve(A, b);
773  }
774 
778  friend inline MatType solve(const MatType& A, const MatType& b,
779  const std::string& lsolver,
780  const Dict& dict = Dict()) {
781  // If A is scalar, just divide
782  if (A.is_scalar()) return b/A;
783  return MatType::solve(A, b, lsolver, dict);
784  }
785 
786 #ifdef WITH_DEPRECATED_FEATURES
803  friend inline MatType linearize(const MatType& f, const MatType& x, const MatType& x0,
804  const Dict& opts=Dict()) {
805  return MatType::linearize(f, x, x0, opts);
806  }
807 #endif // WITH_DEPRECATED_FEATURES
808 
821  friend inline MatType pinv(const MatType& A) {
822  return MatType::pinv(A);
823  }
824 
831  friend inline MatType pinv(const MatType& A, const std::string& lsolver,
832  const Dict& dict = Dict()) {
833  return MatType::pinv(A, lsolver, dict);
834  }
835 
836 
846  friend inline MatType expm_const(const MatType& A, const MatType& t) {
847  return MatType::expm_const(A, t);
848  }
849 
854  friend inline MatType expm(const MatType& A) {
855  return MatType::expm(A);
856  }
857 
863  inline friend MatType jacobian(const MatType &ex, const MatType &arg,
864  const Dict& opts = Dict()) {
865  return MatType::jacobian(ex, arg, opts);
866  }
876  inline friend MatType gradient(const MatType &ex, const MatType &arg, const Dict& opts=Dict()) {
877  return MatType::gradient(ex, arg, opts);
878  }
883  inline friend MatType tangent(const MatType &ex, const MatType &arg, const Dict& opts=Dict()) {
884  return MatType::tangent(ex, arg, opts);
885  }
886 
896  friend inline MatType jtimes(const MatType &ex, const MatType &arg,
897  const MatType &v, bool tr=false, const Dict& opts=Dict()) {
898  return MatType::jtimes(ex, arg, v, tr, opts);
899  }
900 
904  friend inline std::vector<std::vector<MatType> >
905  forward(const std::vector<MatType> &ex, const std::vector<MatType> &arg,
906  const std::vector<std::vector<MatType> > &v,
907  const Dict& opts = Dict()) {
908  return MatType::forward(ex, arg, v, opts);
909  }
910 
914  friend inline std::vector<std::vector<MatType> >
915  reverse(const std::vector<MatType> &ex, const std::vector<MatType> &arg,
916  const std::vector<std::vector<MatType> > &v,
917  const Dict& opts = Dict()) {
918  return MatType::reverse(ex, arg, v, opts);
919  }
920 
922 
925  inline friend MatType hessian(const MatType &ex, const MatType &arg,
926  const Dict& opts = Dict()) {
927  return MatType::hessian(ex, arg, opts);
928  }
929  inline friend MatType hessian(const MatType &ex, const MatType &arg, MatType& output_g,
930  const Dict& opts = Dict()) {
931  return MatType::hessian(ex, arg, output_g, opts);
932  }
934 
938  inline friend std::vector<bool> which_depends(const MatType &expr, const MatType &var,
939  casadi_int order, bool tr) {
940  return MatType::which_depends(expr, var, order, tr);
941  }
942 
948  inline friend Sparsity jacobian_sparsity(const MatType &f, const MatType &x) {
949  return MatType::jacobian_sparsity(f, x);
950  }
951 
959  inline friend bool is_linear(const MatType &expr, const MatType &var) {
960  return MatType::is_linear(expr, var);
961  }
962 
970  inline friend bool is_quadratic(const MatType &expr, const MatType &var) {
971  return MatType::is_quadratic(expr, var);
972  }
973 
984  inline friend void quadratic_coeff(const MatType &expr, const MatType &var,
985  MatType& A, MatType& b, MatType& c, bool check=true) {
986  MatType::quadratic_coeff(expr, var, A, b, c, check);
987  }
988 
997  inline friend void linear_coeff(const MatType &expr, const MatType &var,
998  MatType& A, MatType& b, bool check=true) {
999  MatType::linear_coeff(expr, var, A, b, check);
1000  }
1001 
1033  inline friend void extract_parametric(const MatType &expr, const MatType& par,
1034  MatType& SWIG_OUTPUT(expr_ret),
1035  std::vector<MatType>& SWIG_OUTPUT(symbols),
1036  std::vector<MatType>& SWIG_OUTPUT(parametric),
1037  const Dict& opts=Dict()) {
1038  MatType::extract_parametric(expr, par, expr_ret, symbols, parametric, opts);
1039  }
1040 
1041  inline friend void extract_parametric(const std::vector<MatType> &expr, const MatType& par,
1042  std::vector<MatType>& SWIG_OUTPUT(expr_ret),
1043  std::vector<MatType>& SWIG_OUTPUT(symbols),
1044  std::vector<MatType>& SWIG_OUTPUT(parametric),
1045  const Dict& opts=Dict()) {
1046  // Concatenate all vector elements
1047  MatType expr_cat = veccat(expr);
1048  MatType expr_ret_cat;
1049 
1050  // Concatenated extract_parametric
1051  MatType::extract_parametric(expr_cat, par, expr_ret_cat, symbols, parametric, opts);
1052 
1053  // Compute edges of vertsplit needed to undo concatenate
1054  std::vector<casadi_int> edges = {0};
1055  for (const MatType& e : expr) {
1056  edges.push_back(edges.back() + e.numel());
1057  }
1058  // Perform vertsplit
1059  std::vector<MatType> expr_ret_catv = MatType::vertsplit(expr_ret_cat, edges);
1060 
1061  // Reshape all elements back into original size
1062  expr_ret.resize(expr_ret_catv.size());
1063  for (casadi_int i=0; i<expr_ret_catv.size(); ++i) {
1064  expr_ret[i] = reshape(expr_ret_catv[i], expr[i].size1(), expr[i].size2());
1065  }
1066  }
1067 
1068  inline friend void extract_parametric(const std::vector<MatType> &expr,
1069  const std::vector<MatType>& par,
1070  std::vector<MatType>& SWIG_OUTPUT(expr_ret),
1071  std::vector<MatType>& SWIG_OUTPUT(symbols),
1072  std::vector<MatType>& SWIG_OUTPUT(parametric),
1073  const Dict& opts=Dict()) {
1074  extract_parametric(expr, veccat(par), expr_ret, symbols, parametric, opts);
1075  }
1076 
1077  inline friend void extract_parametric(const MatType &expr, const std::vector<MatType>& par,
1078  MatType& SWIG_OUTPUT(expr_ret),
1079  std::vector<MatType>& SWIG_OUTPUT(symbols),
1080  std::vector<MatType>& SWIG_OUTPUT(parametric),
1081  const Dict& opts=Dict()) {
1082  extract_parametric(expr, veccat(par), expr_ret, symbols, parametric, opts);
1083  }
1084 
1085  /* \brief separate an expression into subuexpression that are linear, constant, and nonlinear
1086  *
1087  * \param expr[in] The expression to be separated
1088  * \param sym_lin[in] The symbolic variables w.r.t. which linearity should be checked
1089  * \param sym_const[in] The symbolic variables that are deemed constant
1090  * \param expr_const[out] The constant part of the expression
1091  * \param expr_lin[out] The linear part of the expression
1092  * \param expr_nonlin[out] The nonlinear part of the expression
1093  *
1094  * Expression dependencies that are not in sym_lin or sym_const are considered nonlinear
1095  *
1096  * A post condition is that the following holds:
1097  * expr = expr_const + expr_lin + expr_nonlin
1098  *
1099  * Here, expr_const is not dependant on sym_const,
1100  * expr_lin is linear in sym_lin
1101  *
1102  * Example:
1103  *
1104  * [expr_const,expr_lin,expr_nonlin] =
1105  * separate_linear(cos(p)+7*x+x*y, vertcat(x,y), p)
1106  *
1107  * expr_const: cos(p)
1108  * expr_lin: 7*x
1109  * expr_nonlin: x*y
1110  *
1111  */
1112  inline friend void separate_linear(const MatType &expr,
1113  const MatType &sym_lin, const MatType &sym_const,
1114  MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1115  MatType::separate_linear(expr, sym_lin, sym_const, expr_const, expr_lin, expr_nonlin);
1116  }
1117 
1118  inline friend void separate_linear(const MatType &expr,
1119  const std::vector<MatType> &sym_lin, const std::vector<MatType> &sym_const,
1120  MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1121  separate_linear(expr, veccat(sym_lin), veccat(sym_const),
1122  expr_const, expr_lin, expr_nonlin);
1123  }
1124 
1126  inline friend casadi_int n_nodes(const MatType& A) {
1127  return MatType::n_nodes(A);
1128  }
1129 
1131  friend inline MatType simplify(const MatType &x) {
1132  return MatType::simplify(x);
1133  }
1134 
1137  friend inline MatType transform(const MatType &x, const Dict& opts = Dict()) {
1138  return MatType::transform(x, opts);
1139  }
1140  friend inline MatType transform(const MatType &x,
1141  const std::vector<std::vector<GenericType> >& passes, const Dict& opts = Dict()) {
1142  return MatType::transform(x, passes, opts);
1143  }
1144  friend inline std::vector<MatType> transform(const std::vector<MatType> &x,
1145  const Dict& opts = Dict()) {
1146  return MatType::transform(x, opts);
1147  }
1148  friend inline std::vector<MatType> transform(const std::vector<MatType> &x,
1149  const std::vector<std::vector<GenericType> >& passes, const Dict& opts = Dict()) {
1150  return MatType::transform(x, passes, opts);
1151  }
1153 
1157  inline friend std::string
1158  print_operator(const MatType& xb, const std::vector<std::string>& args) {
1159  return MatType::print_operator(xb, args);
1160  }
1161 
1165  inline friend void extract(std::vector<MatType>& ex,
1166  std::vector<MatType>& v,
1167  std::vector<MatType>& vdef,
1168  const Dict& opts = Dict()) {
1169  MatType::extract(ex, v, vdef, opts);
1170  }
1171 
1175  inline friend void shared(std::vector<MatType>& ex,
1176  std::vector<MatType>& v,
1177  std::vector<MatType>& vdef,
1178  const std::string& v_prefix="v_",
1179  const std::string& v_suffix="") {
1180  return MatType::shared(ex, v, vdef, v_prefix, v_suffix);
1181  }
1182 
1186  inline friend MatType repsum(const MatType &A, casadi_int n, casadi_int m=1) {
1187  return MatType::repsum(A, n, m);
1188  }
1189 
1191 
1194  friend inline MatType mmin(const MatType& x) {
1195  return MatType::mmin(x);
1196  }
1198 
1200 
1203  friend inline MatType mmax(const MatType& x) {
1204  return MatType::mmax(x);
1205  }
1207 
1210  static MatType jtimes(const MatType &ex, const MatType &arg,
1211  const MatType &v, bool tr=false, const Dict& opts=Dict());
1212  static MatType gradient(const MatType &ex, const MatType &arg, const Dict& opts=Dict());
1213  static MatType tangent(const MatType &ex, const MatType &arg, const Dict& opts=Dict());
1214  static MatType linearize(const MatType& f, const MatType& x, const MatType& x0,
1215  const Dict& opts=Dict());
1216  static MatType mpower(const MatType &x, const MatType &y);
1217  static MatType soc(const MatType &x, const MatType &y);
1219 
1221 #endif // SWIG
1222 
1229 
1233  static MatType sym(const std::string& name, casadi_int nrow=1, casadi_int ncol=1) {
1234  return sym(name, Sparsity::dense(nrow, ncol));
1235  }
1236 
1240  static MatType sym(const std::string& name, const std::pair<casadi_int, casadi_int> &rc) {
1241  return sym(name, rc.first, rc.second);
1242  }
1243 
1247  static MatType sym(const std::string& name, const Sparsity& sp) {
1248  return MatType::_sym(name, sp);
1249  }
1250 
1256  static std::vector<MatType > sym(const std::string& name, const Sparsity& sp, casadi_int p);
1257 
1261  static std::vector<MatType > sym(const std::string& name, casadi_int nrow,
1262  casadi_int ncol, casadi_int p) {
1263  return sym(name, Sparsity::dense(nrow, ncol), p);
1264  }
1265 
1271  static std::vector<std::vector<MatType> >
1272  sym(const std::string& name, const Sparsity& sp, casadi_int p, casadi_int r);
1273 
1279  static std::vector<std::vector<MatType> >
1280  sym(const std::string& name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r) {
1281  return sym(name, Sparsity::dense(nrow, ncol), p, r);
1282  }
1284 
1286 
1289  static MatType zeros(casadi_int nrow=1, casadi_int ncol=1) {
1290  return zeros(Sparsity::dense(nrow, ncol));
1291  }
1292  static MatType zeros(const Sparsity& sp) { return MatType(sp, 0, false);}
1293  static MatType zeros(const std::pair<casadi_int, casadi_int>& rc) {
1294  return zeros(rc.first, rc.second);
1295  }
1297 
1299 
1302  static MatType ones(casadi_int nrow=1, casadi_int ncol=1) {
1303  return ones(Sparsity::dense(nrow, ncol));
1304  }
1305  static MatType ones(const Sparsity& sp) { return MatType(sp, 1, false);}
1306  static MatType ones(const std::pair<casadi_int, casadi_int>& rc) {
1307  return ones(rc.first, rc.second);
1308  }
1310  };
1311 
1312  // Throw informative error message
1313  #define CASADI_THROW_ERROR(FNAME, WHAT) \
1314  throw CasadiException("Error in " + MatType::type_name() \
1315  + "::" FNAME " at " + CASADI_WHERE + ":\n" + std::string(WHAT));
1316 
1317 #ifndef SWIG
1318  // Implementations
1319  template<typename MatType>
1320  const Sparsity& GenericMatrix<MatType>::sparsity() const {
1321  return self().sparsity();
1322  }
1323 
1324  template<typename MatType>
1325  casadi_int GenericMatrix<MatType>::nnz() const {
1326  return sparsity().nnz();
1327  }
1328 
1329  template<typename MatType>
1330  casadi_int GenericMatrix<MatType>::nnz_lower() const {
1331  return sparsity().nnz_lower();
1332  }
1333 
1334  template<typename MatType>
1335  casadi_int GenericMatrix<MatType>::nnz_upper() const {
1336  return sparsity().nnz_upper();
1337  }
1338 
1339  template<typename MatType>
1340  casadi_int GenericMatrix<MatType>::nnz_diag() const {
1341  return sparsity().nnz_diag();
1342  }
1343 
1344  template<typename MatType>
1345  casadi_int GenericMatrix<MatType>::numel() const {
1346  return sparsity().numel();
1347  }
1348 
1349  template<typename MatType>
1350  casadi_int GenericMatrix<MatType>::size1() const {
1351  return sparsity().size1();
1352  }
1353 
1354  template<typename MatType>
1355  casadi_int GenericMatrix<MatType>::size2() const {
1356  return sparsity().size2();
1357  }
1358 
1359  template<typename MatType>
1360  std::pair<casadi_int, casadi_int> GenericMatrix<MatType>::size() const {
1361  return sparsity().size();
1362  }
1363 
1364  template<typename MatType>
1365  casadi_int GenericMatrix<MatType>::size(casadi_int axis) const {
1366  return sparsity().size(axis);
1367  }
1368 
1369  template<typename MatType>
1370  std::string GenericMatrix<MatType>::dim(bool with_nz) const {
1371  return sparsity().dim(with_nz);
1372  }
1373 
1374  template<typename MatType>
1375  bool GenericMatrix<MatType>::is_scalar(bool scalar_and_dense) const {
1376  return sparsity().is_scalar(scalar_and_dense);
1377  }
1378 
1379 #endif // SWIG
1380 
1381  template<typename MatType>
1382  std::vector<MatType> GenericMatrix<MatType>::sym(const std::string& name,
1383  const Sparsity& sp, casadi_int p) {
1384  std::vector<MatType> ret(p);
1385  std::stringstream ss;
1386  for (casadi_int k=0; k<p; ++k) {
1387  ss.str("");
1388  ss << name << k;
1389  ret[k] = sym(ss.str(), sp);
1390  }
1391  return ret;
1392  }
1393 
1394  template<typename MatType>
1395  std::vector<std::vector<MatType> > GenericMatrix<MatType>::sym(const std::string& name,
1396  const Sparsity& sp, casadi_int p,
1397  casadi_int r) {
1398  std::vector<std::vector<MatType> > ret(r);
1399  for (casadi_int k=0; k<r; ++k) {
1400  std::stringstream ss;
1401  ss << name << "_" << k;
1402  ret[k] = sym(ss.str(), sp, p);
1403  }
1404  return ret;
1405  }
1406 
1407  template<typename MatType>
1408  MatType GenericMatrix<MatType>::linspace(const MatType& a, const MatType& b, casadi_int nsteps) {
1409  std::vector<MatType> ret(nsteps);
1410  ret[0] = a;
1411  MatType step = (b-a)/static_cast<MatType>(nsteps-1);
1412 
1413  for (casadi_int i=1; i<nsteps-1; ++i)
1414  ret[i] = a + i * step;
1415 
1416  ret[nsteps-1] = b;
1417  return vertcat(ret);
1418  }
1419 
1420  template<typename MatType>
1421  MatType GenericMatrix<MatType>::cross(const MatType& a, const MatType& b, casadi_int dim) {
1422  casadi_assert(a.size1()==b.size1() && a.size2()==b.size2(),
1423  "cross(a, b): Inconsistent dimensions. Dimension of a ("
1424  + a.dim() + " ) must equal that of b (" + b.dim() + ").");
1425 
1426  casadi_assert(a.size1()==3 || a.size2()==3,
1427  "cross(a, b): One of the dimensions of a should have length 3, but got "
1428  + a.dim() + ".");
1429  casadi_assert(dim==-1 || dim==1 || dim==2,
1430  "cross(a, b, dim): Dim must be 1, 2 or -1 (automatic).");
1431 
1432  std::vector<MatType> ret(3);
1433 
1434  bool t = a.size1()==3;
1435 
1436  if (dim==1) t = true;
1437  if (dim==2) t = false;
1438 
1439  MatType a1 = t ? a(0, Slice()) : a(Slice(), 0);
1440  MatType a2 = t ? a(1, Slice()) : a(Slice(), 1);
1441  MatType a3 = t ? a(2, Slice()) : a(Slice(), 2);
1442 
1443  MatType b1 = t ? b(0, Slice()) : b(Slice(), 0);
1444  MatType b2 = t ? b(1, Slice()) : b(Slice(), 1);
1445  MatType b3 = t ? b(2, Slice()) : b(Slice(), 2);
1446 
1447  ret[0] = a2*b3-a3*b2;
1448  ret[1] = a3*b1-a1*b3;
1449  ret[2] = a1*b2-a2*b1;
1450 
1451  return t ? vertcat(ret) : horzcat(ret);
1452  }
1453 
1454  double CASADI_EXPORT index_interp1d(const std::vector<double>& x, double xq,
1455  bool equidistant=false);
1456 
1457  template<typename MatType>
1458  MatType GenericMatrix<MatType>::interp1d(const std::vector<double>& x, const MatType& v,
1459  const std::vector<double>& xq, const std::string& mode, bool equidistant) {
1460 
1461  bool mode_floor = false;
1462  bool mode_ceil = false;
1463  if (mode=="floor") {
1464  mode_floor = true;
1465  } else if (mode=="ceil") {
1466  mode_ceil = true;
1467  } else if (mode=="linear") {
1468  //
1469  } else {
1470  casadi_error("interp1d(x, v, xq, mode): "
1471  "Mode must be 'floor', 'ceil' or 'linear'. Got '" + mode + "' instead.");
1472  }
1473 
1474  casadi_assert(is_increasing(x), "interp1d(x, v, xq): x must be increasing.");
1475 
1476  casadi_assert(x.size()==v.size1(),
1477  "interp1d(x, v, xq): dimensions mismatch. v expected to have " + str(x.size()) + " rows,"
1478  " but got " + str(v.size1()) + " instead.");
1479 
1480  // Need at least two elements
1481  casadi_assert(x.size()>=2, "interp1d(x, v, xq): x must be at least length 2.");
1482 
1483  // Vectors to compose a sparse matrix
1484  std::vector<double> val;
1485  std::vector<casadi_int> colind(1, 0);
1486  std::vector<casadi_int> row;
1487 
1488  // Number of nonzeros in to-be composed matrix
1489  casadi_int nnz = 0;
1490  for (casadi_int i=0;i<xq.size();++i) {
1491  // Obtain index corresponding to xq[i]
1492  double ind = index_interp1d(x, xq[i], equidistant);
1493 
1494  if (mode_floor) ind = floor(ind);
1495  if (mode_ceil) ind = ceil(ind);
1496 
1497  // Split into integer and fractional part
1498  double int_partd;
1499  double frac_part = modf(ind, &int_partd);
1500  casadi_int int_part = static_cast<casadi_int>(int_partd);
1501 
1502  if (frac_part==0) {
1503  // Create a single entry
1504  val.push_back(1);
1505  row.push_back(int_part);
1506  nnz+=1;
1507  colind.push_back(nnz);
1508  } else {
1509  // Create a double entry
1510  val.push_back(1-frac_part);
1511  val.push_back(frac_part);
1512  row.push_back(int_part);
1513  row.push_back(int_part+1);
1514  nnz+=2;
1515  colind.push_back(nnz);
1516  }
1517  }
1518 
1519  // Construct sparsity for composed matrix
1520  Sparsity sp(x.size(), xq.size() , colind, row);
1521 
1522  return MatType::mtimes(MatType(sp, val).T(), v);
1523 
1524  }
1525 
1526  template<typename MatType>
1527  MatType GenericMatrix<MatType>::skew(const MatType& a) {
1528  casadi_assert(a.is_vector() && (a.size1()==3 || a.size2()==3),
1529  "skew(a): Expecting 3-vector, got " + a.dim() + ".");
1530 
1531  MatType x = a(0);
1532  MatType y = a(1);
1533  MatType z = a(2);
1534  return blockcat(std::vector< std::vector<MatType> >({{0, -z, y}, {z, 0, -x}, {-y, x, 0}}));
1535  }
1536 
1537  template<typename MatType>
1538  MatType GenericMatrix<MatType>::inv_skew(const MatType& a) {
1539  casadi_assert(a.size1()==3 && a.size2()==3,
1540  "inv_skew(a): Expecting 3-by-3 matrix, got " + a.dim() + ".");
1541 
1542  return 0.5*vertcat(std::vector<MatType>({a(2, 1)-a(1, 2), a(0, 2)-a(2, 0), a(1, 0)-a(0, 1)}));
1543  }
1544 
1545 
1546  template<typename MatType>
1547  MatType GenericMatrix<MatType>::tril2symm(const MatType& x) {
1548  casadi_assert(x.is_square(),
1549  "Shape error in tril2symm. Expecting square shape but got " + x.dim());
1550  casadi_assert(x.nnz_upper()-x.nnz_diag()==0,
1551  "Sparsity error in tril2symm. Found above-diagonal entries in argument: " + x.dim());
1552  return x + x.T() - diag(diag(x));
1553  }
1554 
1555  template<typename MatType>
1556  MatType GenericMatrix<MatType>::repsum(const MatType& x, casadi_int n, casadi_int m) {
1557  casadi_assert_dev(x.size1() % n==0);
1558  casadi_assert_dev(x.size2() % m==0);
1559  std::vector< std::vector< MatType> > s =
1560  blocksplit(x, x.size1()/n, x.size2()/m);
1561  MatType sum = 0;
1562  for (casadi_int i=0;i<s.size();++i) {
1563  for (casadi_int j=0;j<s[i].size();++j) {
1564  sum = sum + s[i][j];
1565  }
1566  }
1567  return sum;
1568  }
1569 
1570  template<typename MatType>
1571  MatType GenericMatrix<MatType>::triu2symm(const MatType& x) {
1572  casadi_assert(x.is_square(),
1573  "Shape error in triu2symm. Expecting square shape but got " + x.dim());
1574  casadi_assert(x.nnz_lower()-x.nnz_diag()==0,
1575  "Sparsity error in triu2symm. Found below-diagonal entries in argument: " + x.dim());
1576  return x + x.T() - diag(diag(x));
1577  }
1578 
1579  template<typename MatType>
1580  MatType GenericMatrix<MatType>::bilin(const MatType& A, const MatType& x,
1581  const MatType& y) {
1582  // Check/correct x
1583  casadi_assert_dev(x.is_vector());
1584  if (!x.is_column()) return bilin(A, x.T(), y);
1585  if (!x.is_dense()) return bilin(A, densify(x), y);
1586 
1587  // Check/correct y
1588  casadi_assert_dev(y.is_vector());
1589  if (!y.is_column()) return bilin(A, x, y.T());
1590  if (!y.is_dense()) return bilin(A, x, densify(y));
1591 
1592  // Assert dimensions
1593  casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1594  "Dimension mismatch. Got x.size1() = " + str(x.size1())
1595  + " and y.size1() = " + str(y.size1()) + " but A.size() = " + str(A.size()));
1596 
1597  // Call the class specific method
1598  return MatType::_bilin(A, x, y);
1599  }
1600 
1601  template<typename MatType>
1602  MatType GenericMatrix<MatType>::rank1(const MatType& A, const MatType& alpha,
1603  const MatType& x, const MatType& y) {
1604  // Check/correct x
1605  casadi_assert_dev(x.is_vector());
1606  if (!x.is_column()) return rank1(A, alpha, x.T(), y);
1607  if (!x.is_dense()) return rank1(A, alpha, densify(x), y);
1608 
1609  // Check/correct y
1610  casadi_assert_dev(y.is_vector());
1611  if (!y.is_column()) return rank1(A, alpha, x, y.T());
1612  if (!y.is_dense()) return rank1(A, alpha, x, densify(y));
1613 
1614  // Check alpha, quick return
1615  casadi_assert_dev(alpha.is_scalar());
1616  if (!alpha.is_dense()) return A;
1617 
1618  // Assert dimensions
1619  casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1620  "Dimension mismatch. Got x.size1() = " + str(x.size1())
1621  + " and y.size1() = " + str(y.size1())
1622  + " but A.size() = " + str(A.size()));
1623 
1624  // Call the class specific method
1625  return MatType::_rank1(A, alpha, x, y);
1626  }
1627 
1628  template<typename MatType>
1629  MatType GenericMatrix<MatType>::logsumexp(const MatType& x) {
1630  casadi_assert(x.is_dense(), "Argument must be dense");
1631  casadi_assert(x.is_column(), "Argument must be column vector");
1632  // Call the class specific method
1633  return MatType::_logsumexp(x);
1634  }
1635 
1636  template<typename MatType>
1637  MatType GenericMatrix<MatType>::jtimes(const MatType &ex, const MatType &arg,
1638  const MatType &v, bool tr, const Dict& opts) {
1639  try {
1640  // Assert consistent input dimensions
1641  if (tr) {
1642  if (ex.size2()==0 && v.size2()>0) {
1643  casadi_error("Ambiguous dimensions.");
1644  }
1645  casadi_assert(v.size1() == ex.size1() &&
1646  (v.size2()==0 || ex.size2()==0 || v.size2() % ex.size2() == 0),
1647  "'v' has inconsistent dimensions: "
1648  " v " + v.dim(false) + ", ex " + ex.dim(false) + ".");
1649  } else {
1650  if (arg.size2()==0 && v.size2()>0) {
1651  casadi_error("Ambiguous dimensions.");
1652  }
1653  casadi_assert(v.size1() == arg.size1() &&
1654  (v.size2()==0 || arg.size2()==0 || v.size2() % arg.size2() == 0),
1655  "'v' has inconsistent dimensions: "
1656  " v " + v.dim(false) + ", arg " + arg.dim(false) + ".");
1657  }
1658 
1659  casadi_int n_seeds = 1;
1660  if (tr) {
1661  if (ex.size2()>0) n_seeds = v.size2() / ex.size2();
1662  } else {
1663  if (arg.size2()>0) n_seeds = v.size2() / arg.size2();
1664  }
1665 
1666  // Quick return if no seeds
1667  if (v.is_empty() || ex.is_empty()) {
1668  return MatType(tr ? arg.size1() : ex.size1(),
1669  tr ? arg.size2()*n_seeds : ex.size2()*n_seeds);
1670  }
1671 
1672  // Split up the seed into its components
1673  std::vector<MatType> w = horzsplit(v, tr ? ex.size2() : arg.size2());
1674 
1675  // Seeds as a vector of vectors
1676  std::vector<std::vector<MatType> > ww(w.size());
1677  for (casadi_int i=0; i<w.size(); ++i) ww[i] = {w[i]};
1678 
1679  // Calculate directional derivatives
1680  if (tr) {
1681  ww = reverse({ex}, {arg}, ww, opts);
1682  } else {
1683  ww = forward({ex}, {arg}, ww, opts);
1684  }
1685 
1686  // Get results
1687  for (casadi_int i=0; i<w.size(); ++i) w[i] = ww[i][0];
1688  return horzcat(w);
1689  } catch (std::exception& e) {
1690  CASADI_THROW_ERROR("jtimes", e.what());
1691  }
1692  }
1693 
1694  template<typename MatType>
1695  MatType GenericMatrix<MatType>::gradient(const MatType &ex, const MatType &arg,
1696  const Dict& opts) {
1697  try {
1698  casadi_assert(ex.is_scalar(),
1699  "'gradient' only defined for scalar outputs: Use 'jacobian' instead.");
1700  return project(jtimes(ex, arg, MatType::ones(ex.sparsity()), true, opts), arg.sparsity());
1701  } catch (std::exception& e) {
1702  CASADI_THROW_ERROR("gradient", e.what());
1703  }
1704  }
1705 
1706  template<typename MatType>
1707  MatType GenericMatrix<MatType>::tangent(const MatType &ex, const MatType &arg,
1708  const Dict& opts) {
1709  try {
1710  casadi_assert(arg.is_scalar(),
1711  "'tangent' only defined for scalar inputs: Use 'jacobian' instead.");
1712  return project(jtimes(ex, arg, MatType::ones(arg.sparsity()), false, opts), ex.sparsity());
1713  } catch (std::exception& e) {
1714  CASADI_THROW_ERROR("tangent", e.what());
1715  }
1716  }
1717 
1718  template<typename MatType>
1719  MatType GenericMatrix<MatType>::
1720  linearize(const MatType& f, const MatType& x, const MatType& x0, const Dict& opts) {
1721  MatType x_lin = MatType::sym("x_lin", x.sparsity());
1722  // mismatching dimensions
1723  if (x0.size() != x.size()) {
1724  // Scalar x0 is ok
1725  if (x0.sparsity().is_scalar()) {
1726  return linearize(f, x, MatType(x.sparsity(), x0));
1727  }
1728  casadi_error("Dimension mismatch in 'linearize'");
1729  }
1730  return substitute(f + jtimes(f, x, x_lin, false, opts),
1731  MatType::vertcat({x_lin, x}), MatType::vertcat({x, x0}));
1732  }
1733 
1734  template<typename MatType>
1735  MatType GenericMatrix<MatType>::mpower(const MatType& a,
1736  const MatType& b) {
1737  if (a.is_scalar() && b.is_scalar()) return pow(a, b);
1738  casadi_assert(a.is_square() && b.is_constant() && b.is_scalar(),
1739  "Not Implemented");
1740  double bv = static_cast<double>(b);
1741  casadi_int N = static_cast<casadi_int>(bv);
1742  casadi_assert(bv-static_cast<double>(N)==0, "mpower only defined for integer powers.");
1743  casadi_assert(bv==N, "Not Implemented");
1744  if (N<0) return inv(mpower(a, -N));
1745  if (N==0) return MatType::eye(a.size1());
1746  if (N==1) return a;
1747  if (N % 2 == 0) {
1748  MatType h = mpower(a, N/2); // NOLINT
1749  return MatType::mtimes(h, h);
1750  } else {
1751  return MatType::mtimes(mpower(a, N-1), a);
1752  }
1753  }
1754 
1755  template<typename MatType>
1756  MatType GenericMatrix<MatType>::soc(const MatType& x,
1757  const MatType& y) {
1758  casadi_assert(y.is_scalar(), "y needs to be scalar. Got " + y.dim() + ".");
1759  casadi_assert(x.is_vector(), "x needs to be a vector. Got " + x.dim() + ".");
1760 
1761  MatType x_col = x.is_column() ? x : x.T();
1762 
1763  x_col = x_col.nz(Slice()); // NOLINT
1764 
1765  casadi_int n = x_col.numel();
1766  return blockcat(y*MatType::eye(n), x_col, x_col.T(), y);
1767  }
1768 
1769  template<typename MatType>
1770  bool GenericMatrix<MatType>::is_linear(const MatType &expr, const MatType &var) {
1771  return !any(MatType::which_depends(expr, var, 2, true));
1772  }
1773 
1774  template<typename MatType>
1775  bool GenericMatrix<MatType>::is_quadratic(const MatType &expr, const MatType &var) {
1776  return is_linear(gradient(expr, var), var);
1777  }
1778 
1779  template<typename MatType>
1780  void GenericMatrix<MatType>::quadratic_coeff(const MatType &expr, const MatType &var,
1781  MatType& A, MatType& b, MatType& c, bool check) {
1782  casadi_assert(expr.is_scalar(), "'quadratic_coeff' only defined for scalar expressions.");
1783  A = hessian(expr, var);
1784  b = substitute(jacobian(expr, var), var, 0).T();
1785  if (check)
1786  casadi_assert(!depends_on(A, var), "'quadratic_coeff' called on non-quadratic expression.");
1787  c = substitute(expr, var, 0);
1788  }
1789 
1790  template<typename MatType>
1791  void GenericMatrix<MatType>::linear_coeff(const MatType &expr, const MatType &var,
1792  MatType& A, MatType& b, bool check) {
1793  casadi_assert(expr.is_vector(), "'linear_coeff' only defined for vector expressions.");
1794  if (check)
1795  casadi_assert(is_linear(expr, var), "'linear_coeff' called on non-linear expression.");
1796  A = substitute(jacobian(expr, var), var, 0);
1797  b = vec(substitute(expr, var, 0));
1798  }
1799 
1800  template<typename MatType>
1801  MatType GenericMatrix<MatType>::diff(const MatType& x, casadi_int n, casadi_int axis) {
1802  casadi_assert(axis==-1 || axis==0 || axis==1, "Axis argument invalid");
1803  casadi_assert(n>=1, "n argument invalid");
1804 
1805  MatType ret = x;
1806  for (casadi_int i=0;i<n;++i) {
1807  // Matlab's special case
1808  if (axis==-1 && ret.is_scalar()) return MatType();
1809 
1810  casadi_int local_axis = (axis==-1) ? ret.is_row() : axis;
1811  if (local_axis==0) {
1812  if (ret.size1()<=1) {
1813  ret = MatType::zeros(0, ret.size2());
1814  } else {
1815  ret = ret(Slice(1, ret.size1()), Slice())-ret(Slice(0, ret.size1()-1), Slice());
1816  }
1817  } else {
1818  if (ret.size2()<=1) {
1819  ret = MatType::zeros(ret.size1(), 0);
1820  } else {
1821  ret = ret(Slice(), Slice(1, ret.size2()))-ret(Slice(), Slice(0, ret.size2()-1));
1822  }
1823  }
1824  }
1825  return ret;
1826  }
1827 
1828 #undef CASADI_THROW_ERROR
1829 
1830 } // namespace casadi
1831 
1832 #endif // CASADI_GENERIC_MATRIX_HPP
Matrix base class.
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.
General sparsity class.
Definition: sparsity.hpp:106
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.
static MatType logsumexp(const MatType &x)
friend void extract_parametric(const MatType &expr, const MatType &par, MatType &expr_ret, std::vector< MatType > &symbols, std::vector< MatType > &parametric, const Dict &opts=Dict())
Extract purely parametric parts from an expression graph.
friend MatType solve(const MatType &A, const MatType &b)
Solve a system of equations: A*x = b.
friend std::vector< MatType > transform(const std::vector< MatType > &x, const Dict &opts=Dict())
friend std::vector< MatType > transform(const std::vector< MatType > &x, const std::vector< std::vector< GenericType > > &passes, const Dict &opts=Dict())
friend MatType bilin(const MatType &A, const MatType &x)
Calculate bilinear/quadratic form x^T A y.
friend void separate_linear(const MatType &expr, const MatType &sym_lin, const MatType &sym_const, MatType &expr_const, MatType &expr_lin, MatType &expr_nonlin)
friend MatType nullspace(const MatType &A)
Computes the nullspace of a matrix A.
friend bool depends_on(const MatType &f, const MatType &arg)
Check if expression depends on the argument.
friend MatType trace(const MatType &x)
Matrix trace.
friend MatType norm_2(const MatType &x)
2-norm
friend void extract_parametric(const std::vector< MatType > &expr, const MatType &par, std::vector< MatType > &expr_ret, std::vector< MatType > &symbols, std::vector< MatType > &parametric, const Dict &opts=Dict())
static MatType gradient(const MatType &ex, const MatType &arg, const Dict &opts=Dict())
friend MatType soc(const MatType &x, const MatType &y)
Construct second-order-convex.
friend MatType rank1(const MatType &A, const MatType &alpha, const MatType &x, const MatType &y)
Make a rank-1 update to a matrix A.
friend MatType simplify(const MatType &x)
Simplify an expression.
static MatType mpower(const MatType &x, const MatType &y)
friend MatType einstein(const MatType &A, const MatType &B, const MatType &C, const std::vector< casadi_int > &dim_a, const std::vector< casadi_int > &dim_b, const std::vector< casadi_int > &dim_c, const std::vector< casadi_int > &a, const std::vector< casadi_int > &b, const std::vector< casadi_int > &c)
Compute any contraction of two dense tensors, using index/einstein notation.
friend MatType project(const MatType &A, const Sparsity &sp, bool intersect=false)
Create a new matrix with a given sparsity pattern but with the.
friend MatType repsum(const MatType &A, casadi_int n, casadi_int m=1)
Given a repeated matrix, computes the sum of repeated parts.
friend MatType sumsqr(const MatType &x)
Calculate sum of squares: sum_ij X_ij^2.
friend std::vector< bool > which_depends(const MatType &expr, const MatType &var, casadi_int order, bool tr)
Find out which variables enter with some order.
friend MatType inv(const MatType &A)
Matrix inverse.
friend bool contains_all(const std::vector< MatType > &v, const std::vector< MatType > &n)
Check if expression n is listed in v.
friend MatType norm_fro(const MatType &x)
Frobenius norm.
friend MatType interp1d(const std::vector< double > &x, const MatType &v, const std::vector< double > &xq, const std::string &mode, bool equidistant=false)
Performs 1d linear interpolation.
friend MatType hessian(const MatType &ex, const MatType &arg, MatType &output_g, const Dict &opts=Dict())
Hessian and (optionally) gradient.
static MatType jtimes(const MatType &ex, const MatType &arg, const MatType &v, bool tr=false, const Dict &opts=Dict())
friend void separate_linear(const MatType &expr, const std::vector< MatType > &sym_lin, const std::vector< MatType > &sym_const, MatType &expr_const, MatType &expr_lin, MatType &expr_nonlin)
friend MatType hessian(const MatType &ex, const MatType &arg, const Dict &opts=Dict())
Hessian and (optionally) gradient.
friend MatType mldivide(const MatType &x, const MatType &n)
Matrix divide (cf. backslash '\' in MATLAB)
friend MatType det(const MatType &A, const std::string &lsolver, const Dict &dict=Dict())
Matrix determinant (experimental)
friend std::vector< std::vector< MatType > > reverse(const std::vector< MatType > &ex, const std::vector< MatType > &arg, const std::vector< std::vector< MatType > > &v, const Dict &opts=Dict())
Reverse directional derivative.
friend std::string print_operator(const MatType &xb, const std::vector< std::string > &args)
Get a string representation for a binary MatType, using custom arguments.
friend casadi_int n_nodes(const MatType &A)
friend std::vector< MatType > symvar(const MatType &x)
Get all symbols contained in the supplied expression.
static MatType bilin(const MatType &A, const MatType &x, const MatType &y)
Calculate bilinear/quadratic form x^T A y.
friend MatType inv(const MatType &A, const std::string &lsolver, const Dict &options=Dict())
Matrix inverse.
friend bool is_quadratic(const MatType &expr, const MatType &var)
Is expr quadratic in var?
friend MatType logsumexp(const MatType &x)
x -> log(sum_i exp(x_i))
static MatType tangent(const MatType &ex, const MatType &arg, const Dict &opts=Dict())
friend void extract_parametric(const std::vector< MatType > &expr, const std::vector< MatType > &par, std::vector< MatType > &expr_ret, std::vector< MatType > &symbols, std::vector< MatType > &parametric, const Dict &opts=Dict())
friend bool contains(const std::vector< MatType > &v, const MatType &n)
Check if expression n is listed in v.
friend bool contains_any(const std::vector< MatType > &v, const std::vector< MatType > &n)
Check if expression n is listed in v.
static MatType linearize(const MatType &f, const MatType &x, const MatType &x0, const Dict &opts=Dict())
friend MatType det(const MatType &A)
Matrix determinant (experimental)
friend void linear_coeff(const MatType &expr, const MatType &var, MatType &A, MatType &b, bool check=true)
Recognizes linear form in vector expression.
friend MatType linearize(const MatType &f, const MatType &x, const MatType &x0, const Dict &opts=Dict())
Linearize an expression.
friend MatType expm_const(const MatType &A, const MatType &t)
Calculate Matrix exponential.
friend MatType einstein(const MatType &A, const MatType &B, const std::vector< casadi_int > &dim_a, const std::vector< casadi_int > &dim_b, const std::vector< casadi_int > &dim_c, const std::vector< casadi_int > &a, const std::vector< casadi_int > &b, const std::vector< casadi_int > &c)
Compute any contraction of two dense tensors, using index/einstein notation.
friend MatType transform(const MatType &x, const Dict &opts=Dict())
friend MatType diff(const MatType &x, casadi_int n=1, casadi_int axis=-1)
Returns difference (n-th order) along given axis (MATLAB convention)
friend MatType cross(const MatType &a, const MatType &b, casadi_int dim=-1)
Matlab's cross command.
friend MatType substitute(const MatType &ex, const MatType &v, const MatType &vdef)
Substitute variable v with expression vdef in an expression ex.
friend MatType norm_1(const MatType &x)
1-norm
friend void quadratic_coeff(const MatType &expr, const MatType &var, MatType &A, MatType &b, MatType &c, bool check=true)
Recognizes quadratic form in scalar expression.
friend MatType logsumexp(const MatType &x, const MatType &margin)
Scaled version of logsumexp.
friend MatType transform(const MatType &x, const std::vector< std::vector< GenericType > > &passes, const Dict &opts=Dict())
friend MatType mrdivide(const MatType &x, const MatType &n)
Matrix divide (cf. slash '/' in MATLAB)
friend MatType gradient(const MatType &ex, const MatType &arg, const Dict &opts=Dict())
Calculate the gradient of an expression.
friend MatType triu2symm(const MatType &a)
Convert a upper triangular matrix to a symmetric one.
friend Sparsity jacobian_sparsity(const MatType &f, const MatType &x)
Get the sparsity pattern of a jacobian.
friend MatType linspace(const MatType &a, const MatType &b, casadi_int nsteps)
Matlab's linspace command.
friend MatType mmax(const MatType &x)
Largest element in a matrix.
friend void substitute_inplace(const std::vector< MatType > &v, std::vector< MatType > &inout_vdef, std::vector< MatType > &inout_ex, bool reverse=false)
Inplace substitution with piggyback expressions.
friend bool is_linear(const MatType &expr, const MatType &var)
Is expr linear in var?
friend MatType densify(const MatType &x)
Make the matrix dense if not already.
friend std::vector< MatType > substitute(const std::vector< MatType > &ex, const std::vector< MatType > &v, const std::vector< MatType > &vdef)
Substitute variable var with expression expr in multiple expressions.
friend MatType inv_minor(const MatType &A)
Matrix inverse (experimental)
friend void extract(std::vector< MatType > &ex, std::vector< MatType > &v, std::vector< MatType > &vdef, const Dict &opts=Dict())
Introduce intermediate variables for selected nodes in a graph.
static MatType soc(const MatType &x, const MatType &y)
friend MatType tangent(const MatType &ex, const MatType &arg, const Dict &opts=Dict())
Calculate the tangent of an expression.
friend MatType mmin(const MatType &x)
Smallest element in a matrix.
friend MatType dot(const MatType &x, const MatType &y)
Inner product of two matrices.
friend MatType jtimes(const MatType &ex, const MatType &arg, const MatType &v, bool tr=false, const Dict &opts=Dict())
Calculate the Jacobian and multiply by a vector from the right.
friend std::vector< std::vector< MatType > > forward(const std::vector< MatType > &ex, const std::vector< MatType > &arg, const std::vector< std::vector< MatType > > &v, const Dict &opts=Dict())
Forward directional derivative.
friend MatType cse(const MatType &e)
Common subexpression elimination.
friend MatType inv_skew(const MatType &a)
Generate the 3-vector progenitor of a skew symmetric matrix.
friend MatType polyval(const MatType &p, const MatType &x)
Evaluate a polynomial with coefficients p in x.
friend MatType conditional(const MatType &ind, const std::vector< MatType > &x, const MatType &x_default, bool short_circuit=false)
Create a switch.
friend MatType if_else(const MatType &cond, const MatType &if_true, const MatType &if_false, bool short_circuit=false)
Branching on MX nodes.
friend MatType expm(const MatType &A)
Calculate Matrix exponential.
friend MatType skew(const MatType &a)
Generate a skew symmetric matrix from a 3-vector.
friend void shared(std::vector< MatType > &ex, std::vector< MatType > &v, std::vector< MatType > &vdef, const std::string &v_prefix="v_", const std::string &v_suffix="")
Extract shared subexpressions from an set of expressions.
friend MatType solve(const MatType &A, const MatType &b, const std::string &lsolver, const Dict &dict=Dict())
Solve a system of equations: A*x = b.
static MatType rank1(const MatType &A, const MatType &alpha, const MatType &x, const MatType &y)
Make a rank-1 update to a matrix A.
friend MatType cumsum(const MatType &x, casadi_int axis=-1)
Returns cumulative sum along given axis (MATLAB convention)
friend MatType unite(const MatType &A, const MatType &B)
Unite two matrices no overlapping sparsity.
friend MatType tril2symm(const MatType &a)
Convert a lower triangular matrix to a symmetric one.
friend MatType diag(const MatType &A)
Get the diagonal of a matrix or construct a diagonal.
friend MatType pinv(const MatType &A, const std::string &lsolver, const Dict &dict=Dict())
Computes the Moore-Penrose pseudo-inverse.
friend MatType densify(const MatType &x, const MatType &val)
Make the matrix dense and assign nonzeros to a value.
friend void extract_parametric(const MatType &expr, const std::vector< MatType > &par, MatType &expr_ret, std::vector< MatType > &symbols, std::vector< MatType > &parametric, const Dict &opts=Dict())
friend MatType jacobian(const MatType &ex, const MatType &arg, const Dict &opts=Dict())
Calculate Jacobian.
friend MatType norm_inf(const MatType &x)
Infinity-norm.
friend MatType pinv(const MatType &A)
Computes the Moore-Penrose pseudo-inverse.
friend MatType mpower(const MatType &x, const MatType &n)
Matrix power x^n.
friend std::vector< MatType > cse(const std::vector< MatType > &e)
Common subexpression elimination.
friend MatType bilin(const MatType &A, const MatType &x, const MatType &y)
Calculate bilinear/quadratic form x^T A y.
The casadi namespace.
Definition: archiver.hpp:32
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.