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>) {
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>
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 inv_minor(const MatType& A) { return MatType::inv_minor(A);}
494 
498  inline friend MatType inv(const MatType& A) {
499  return MatType::inv(A);
500  }
501 
505  inline friend MatType inv(const MatType& A,
506  const std::string& lsolver,
507  const Dict& options=Dict()) {
508  return MatType::inv(A, lsolver, options);
509  }
510 
514  inline friend MatType trace(const MatType& x) { return MatType::trace(x);}
515 
519  inline friend MatType tril2symm(const MatType &a) { return MatType::tril2symm(a);}
520 
524  inline friend MatType triu2symm(const MatType &a) { return MatType::triu2symm(a);}
525 
529  inline friend MatType norm_fro(const MatType &x) { return MatType::norm_fro(x);}
530 
534  inline friend MatType norm_2(const MatType &x) { return MatType::norm_2(x);}
535 
539  inline friend MatType norm_1(const MatType &x) { return MatType::norm_1(x);}
540 
544  inline friend MatType norm_inf(const MatType &x) { return MatType::norm_inf(x);}
545 
549  inline friend MatType diff(const MatType &x, casadi_int n=1, casadi_int axis=-1) {
550  return MatType::diff(x, n, axis);
551  }
552 
556  inline friend MatType cumsum(const MatType &x, casadi_int axis=-1) {
557  return MatType::cumsum(x, axis);
558  }
559 
565  inline friend MatType dot(const MatType &x, const MatType &y) {
566  return MatType::dot(x, y);
567  }
568 
579  inline friend MatType nullspace(const MatType& A) {
580  return MatType::nullspace(A);
581  }
582 
586  inline friend MatType polyval(const MatType& p, const MatType& x) {
587  return MatType::polyval(p, x);
588  }
589 
596  inline friend MatType diag(const MatType &A) {
597  return MatType::diag(A);
598  }
599 
603  inline friend MatType unite(const MatType& A, const MatType& B) {
604  return MatType::unite(A, B);
605  }
606 
610  inline friend MatType densify(const MatType& x) {
611  return MatType::densify(x);
612  }
613 
617  inline friend MatType densify(const MatType& x, const MatType& val) {
618  return MatType::densify(x, val);
619  }
620 
626  inline friend MatType project(const MatType& A, const Sparsity& sp,
627  bool intersect=false) {
628  return MatType::project(A, sp, intersect);
629  }
630 
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);
639  }
640 
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);
650  }
651 
665  inline friend bool depends_on(const MatType& f, const MatType &arg) {
666  return MatType::depends_on(f, arg);
667  }
668 
685  inline friend bool contains(const std::vector<MatType>& v, const MatType &n) {
686  return contains_all(v, std::vector<MatType>{n});
687  }
688 
689  inline friend bool contains_all(const std::vector<MatType>& v, const std::vector<MatType> &n) {
690  return MatType::contains_all(v, n);
691  }
692 
693  inline friend bool contains_any(const std::vector<MatType>& v, const std::vector<MatType> &n) {
694  return MatType::contains_any(v, n);
695  }
697 
701  friend inline MatType substitute(const MatType& ex, const MatType& v,
702  const MatType& vdef) {
703  return MatType::substitute(ex, v, vdef);
704  }
705 
709  friend inline std::vector<MatType>
710  substitute(const std::vector<MatType>& ex, const std::vector<MatType>& v,
711  const std::vector<MatType>& vdef) {
712  return MatType::substitute(ex, v, vdef);
713  }
714 
721  inline friend void
722  substitute_inplace(const std::vector<MatType>& v,
723  std::vector<MatType>& inout_vdef,
724  std::vector<MatType>& inout_ex, bool reverse=false) {
725  return MatType::substitute_inplace(v, inout_vdef, inout_ex, reverse);
726  }
727 
731  inline friend MatType cse(const MatType& e) {
732  return MatType::cse({e}).at(0);
733  }
734 
735 
739  inline friend std::vector<MatType> cse(const std::vector<MatType>& e) {
740  return MatType::cse(e);
741  }
742 
761  friend inline MatType solve(const MatType& A, const MatType& b) {
762  // If A is scalar, just divide
763  if (A.is_scalar()) return b/A;
764  return MatType::solve(A, b);
765  }
766 
770  friend inline MatType solve(const MatType& A, const MatType& b,
771  const std::string& lsolver,
772  const Dict& dict = Dict()) {
773  // If A is scalar, just divide
774  if (A.is_scalar()) return b/A;
775  return MatType::solve(A, b, lsolver, dict);
776  }
777 
778 #ifdef WITH_DEPRECATED_FEATURES
795  friend inline MatType linearize(const MatType& f, const MatType& x, const MatType& x0,
796  const Dict& opts=Dict()) {
797  return MatType::linearize(f, x, x0, opts);
798  }
799 #endif // WITH_DEPRECATED_FEATURES
800 
813  friend inline MatType pinv(const MatType& A) {
814  return MatType::pinv(A);
815  }
816 
823  friend inline MatType pinv(const MatType& A, const std::string& lsolver,
824  const Dict& dict = Dict()) {
825  return MatType::pinv(A, lsolver, dict);
826  }
827 
828 
838  friend inline MatType expm_const(const MatType& A, const MatType& t) {
839  return MatType::expm_const(A, t);
840  }
841 
846  friend inline MatType expm(const MatType& A) {
847  return MatType::expm(A);
848  }
849 
855  inline friend MatType jacobian(const MatType &ex, const MatType &arg,
856  const Dict& opts = Dict()) {
857  return MatType::jacobian(ex, arg, opts);
858  }
868  inline friend MatType gradient(const MatType &ex, const MatType &arg, const Dict& opts=Dict()) {
869  return MatType::gradient(ex, arg, opts);
870  }
875  inline friend MatType tangent(const MatType &ex, const MatType &arg, const Dict& opts=Dict()) {
876  return MatType::tangent(ex, arg, opts);
877  }
878 
888  friend inline MatType jtimes(const MatType &ex, const MatType &arg,
889  const MatType &v, bool tr=false, const Dict& opts=Dict()) {
890  return MatType::jtimes(ex, arg, v, tr, opts);
891  }
892 
896  friend inline std::vector<std::vector<MatType> >
897  forward(const std::vector<MatType> &ex, const std::vector<MatType> &arg,
898  const std::vector<std::vector<MatType> > &v,
899  const Dict& opts = Dict()) {
900  return MatType::forward(ex, arg, v, opts);
901  }
902 
906  friend inline std::vector<std::vector<MatType> >
907  reverse(const std::vector<MatType> &ex, const std::vector<MatType> &arg,
908  const std::vector<std::vector<MatType> > &v,
909  const Dict& opts = Dict()) {
910  return MatType::reverse(ex, arg, v, opts);
911  }
912 
914 
917  inline friend MatType hessian(const MatType &ex, const MatType &arg,
918  const Dict& opts = Dict()) {
919  return MatType::hessian(ex, arg, opts);
920  }
921  inline friend MatType hessian(const MatType &ex, const MatType &arg, MatType& output_g,
922  const Dict& opts = Dict()) {
923  return MatType::hessian(ex, arg, output_g, opts);
924  }
926 
930  inline friend std::vector<bool> which_depends(const MatType &expr, const MatType &var,
931  casadi_int order, bool tr) {
932  return MatType::which_depends(expr, var, order, tr);
933  }
934 
940  inline friend Sparsity jacobian_sparsity(const MatType &f, const MatType &x) {
941  return MatType::jacobian_sparsity(f, x);
942  }
943 
951  inline friend bool is_linear(const MatType &expr, const MatType &var) {
952  return MatType::is_linear(expr, var);
953  }
954 
962  inline friend bool is_quadratic(const MatType &expr, const MatType &var) {
963  return MatType::is_quadratic(expr, var);
964  }
965 
976  inline friend void quadratic_coeff(const MatType &expr, const MatType &var,
977  MatType& A, MatType& b, MatType& c, bool check=true) {
978  MatType::quadratic_coeff(expr, var, A, b, c, check);
979  }
980 
989  inline friend void linear_coeff(const MatType &expr, const MatType &var,
990  MatType& A, MatType& b, bool check=true) {
991  MatType::linear_coeff(expr, var, A, b, check);
992  }
993 
1025  inline friend void extract_parametric(const MatType &expr, const MatType& par,
1026  MatType& SWIG_OUTPUT(expr_ret),
1027  std::vector<MatType>& SWIG_OUTPUT(symbols),
1028  std::vector<MatType>& SWIG_OUTPUT(parametric),
1029  const Dict& opts=Dict()) {
1030  MatType::extract_parametric(expr, par, expr_ret, symbols, parametric, opts);
1031  }
1032 
1033  inline friend void extract_parametric(const std::vector<MatType> &expr, const MatType& par,
1034  std::vector<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  // Concatenate all vector elements
1039  MatType expr_cat = veccat(expr);
1040  MatType expr_ret_cat;
1041 
1042  // Concatenated extract_parametric
1043  MatType::extract_parametric(expr_cat, par, expr_ret_cat, symbols, parametric, opts);
1044 
1045  // Compute edges of vertsplit needed to undo concatenate
1046  std::vector<casadi_int> edges = {0};
1047  for (const MatType& e : expr) {
1048  edges.push_back(edges.back() + e.numel());
1049  }
1050  // Perform vertsplit
1051  std::vector<MatType> expr_ret_catv = MatType::vertsplit(expr_ret_cat, edges);
1052 
1053  // Reshape all elements back into original size
1054  expr_ret.resize(expr_ret_catv.size());
1055  for (casadi_int i=0; i<expr_ret_catv.size(); ++i) {
1056  expr_ret[i] = reshape(expr_ret_catv[i], expr[i].size1(), expr[i].size2());
1057  }
1058  }
1059 
1060  inline friend void extract_parametric(const std::vector<MatType> &expr,
1061  const std::vector<MatType>& par,
1062  std::vector<MatType>& SWIG_OUTPUT(expr_ret),
1063  std::vector<MatType>& SWIG_OUTPUT(symbols),
1064  std::vector<MatType>& SWIG_OUTPUT(parametric),
1065  const Dict& opts=Dict()) {
1066  extract_parametric(expr, veccat(par), expr_ret, symbols, parametric, opts);
1067  }
1068 
1069  inline friend void extract_parametric(const MatType &expr, const std::vector<MatType>& par,
1070  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  /* \brief separate an expression into subuexpression that are linear, constant, and nonlinear
1078  *
1079  * \param expr[in] The expression to be separated
1080  * \param sym_lin[in] The symbolic variables w.r.t. which linearity should be checked
1081  * \param sym_const[in] The symbolic variables that are deemed constant
1082  * \param expr_const[out] The constant part of the expression
1083  * \param expr_lin[out] The linear part of the expression
1084  * \param expr_nonlin[out] The nonlinear part of the expression
1085  *
1086  * Expression dependencies that are not in sym_lin or sym_const are considered nonlinear
1087  *
1088  * A post condition is that the following holds:
1089  * expr = expr_const + expr_lin + expr_nonlin
1090  *
1091  * Here, expr_const is not dependant on sym_const,
1092  * expr_lin is linear in sym_lin
1093  *
1094  * Example:
1095  *
1096  * [expr_const,expr_lin,expr_nonlin] =
1097  * separate_linear(cos(p)+7*x+x*y, vertcat(x,y), p)
1098  *
1099  * expr_const: cos(p)
1100  * expr_lin: 7*x
1101  * expr_nonlin: x*y
1102  *
1103  */
1104  inline friend void separate_linear(const MatType &expr,
1105  const MatType &sym_lin, const MatType &sym_const,
1106  MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1107  MatType::separate_linear(expr, sym_lin, sym_const, expr_const, expr_lin, expr_nonlin);
1108  }
1109 
1110  inline friend void separate_linear(const MatType &expr,
1111  const std::vector<MatType> &sym_lin, const std::vector<MatType> &sym_const,
1112  MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
1113  separate_linear(expr, veccat(sym_lin), veccat(sym_const),
1114  expr_const, expr_lin, expr_nonlin);
1115  }
1116 
1118  inline friend casadi_int n_nodes(const MatType& A) {
1119  return MatType::n_nodes(A);
1120  }
1121 
1123  friend inline MatType simplify(const MatType &x) {
1124  return MatType::simplify(x);
1125  }
1126 
1130  inline friend std::string
1131  print_operator(const MatType& xb, const std::vector<std::string>& args) {
1132  return MatType::print_operator(xb, args);
1133  }
1134 
1138  inline friend void extract(std::vector<MatType>& ex,
1139  std::vector<MatType>& v,
1140  std::vector<MatType>& vdef,
1141  const Dict& opts = Dict()) {
1142  MatType::extract(ex, v, vdef, opts);
1143  }
1144 
1148  inline friend void shared(std::vector<MatType>& ex,
1149  std::vector<MatType>& v,
1150  std::vector<MatType>& vdef,
1151  const std::string& v_prefix="v_",
1152  const std::string& v_suffix="") {
1153  return MatType::shared(ex, v, vdef, v_prefix, v_suffix);
1154  }
1155 
1159  inline friend MatType repsum(const MatType &A, casadi_int n, casadi_int m=1) {
1160  return MatType::repsum(A, n, m);
1161  }
1162 
1164 
1167  friend inline MatType mmin(const MatType& x) {
1168  return MatType::mmin(x);
1169  }
1171 
1173 
1176  friend inline MatType mmax(const MatType& x) {
1177  return MatType::mmax(x);
1178  }
1180 
1183  static MatType jtimes(const MatType &ex, const MatType &arg,
1184  const MatType &v, bool tr=false, const Dict& opts=Dict());
1185  static MatType gradient(const MatType &ex, const MatType &arg, const Dict& opts=Dict());
1186  static MatType tangent(const MatType &ex, const MatType &arg, const Dict& opts=Dict());
1187  static MatType linearize(const MatType& f, const MatType& x, const MatType& x0,
1188  const Dict& opts=Dict());
1189  static MatType mpower(const MatType &x, const MatType &y);
1190  static MatType soc(const MatType &x, const MatType &y);
1192 
1194 #endif // SWIG
1195 
1202 
1206  static MatType sym(const std::string& name, casadi_int nrow=1, casadi_int ncol=1) {
1207  return sym(name, Sparsity::dense(nrow, ncol));
1208  }
1209 
1213  static MatType sym(const std::string& name, const std::pair<casadi_int, casadi_int> &rc) {
1214  return sym(name, rc.first, rc.second);
1215  }
1216 
1220  static MatType sym(const std::string& name, const Sparsity& sp) {
1221  return MatType::_sym(name, sp);
1222  }
1223 
1229  static std::vector<MatType > sym(const std::string& name, const Sparsity& sp, casadi_int p);
1230 
1234  static std::vector<MatType > sym(const std::string& name, casadi_int nrow,
1235  casadi_int ncol, casadi_int p) {
1236  return sym(name, Sparsity::dense(nrow, ncol), p);
1237  }
1238 
1244  static std::vector<std::vector<MatType> >
1245  sym(const std::string& name, const Sparsity& sp, casadi_int p, casadi_int r);
1246 
1252  static std::vector<std::vector<MatType> >
1253  sym(const std::string& name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r) {
1254  return sym(name, Sparsity::dense(nrow, ncol), p, r);
1255  }
1257 
1259 
1262  static MatType zeros(casadi_int nrow=1, casadi_int ncol=1) {
1263  return zeros(Sparsity::dense(nrow, ncol));
1264  }
1265  static MatType zeros(const Sparsity& sp) { return MatType(sp, 0, false);}
1266  static MatType zeros(const std::pair<casadi_int, casadi_int>& rc) {
1267  return zeros(rc.first, rc.second);
1268  }
1270 
1272 
1275  static MatType ones(casadi_int nrow=1, casadi_int ncol=1) {
1276  return ones(Sparsity::dense(nrow, ncol));
1277  }
1278  static MatType ones(const Sparsity& sp) { return MatType(sp, 1, false);}
1279  static MatType ones(const std::pair<casadi_int, casadi_int>& rc) {
1280  return ones(rc.first, rc.second);
1281  }
1283  };
1284 
1285  // Throw informative error message
1286  #define CASADI_THROW_ERROR(FNAME, WHAT) \
1287  throw CasadiException("Error in " + MatType::type_name() \
1288  + "::" FNAME " at " + CASADI_WHERE + ":\n" + std::string(WHAT));
1289 
1290 #ifndef SWIG
1291  // Implementations
1292  template<typename MatType>
1294  return self().sparsity();
1295  }
1296 
1297  template<typename MatType>
1298  casadi_int GenericMatrix<MatType>::nnz() const {
1299  return sparsity().nnz();
1300  }
1301 
1302  template<typename MatType>
1304  return sparsity().nnz_lower();
1305  }
1306 
1307  template<typename MatType>
1309  return sparsity().nnz_upper();
1310  }
1311 
1312  template<typename MatType>
1314  return sparsity().nnz_diag();
1315  }
1316 
1317  template<typename MatType>
1318  casadi_int GenericMatrix<MatType>::numel() const {
1319  return sparsity().numel();
1320  }
1321 
1322  template<typename MatType>
1323  casadi_int GenericMatrix<MatType>::size1() const {
1324  return sparsity().size1();
1325  }
1326 
1327  template<typename MatType>
1328  casadi_int GenericMatrix<MatType>::size2() const {
1329  return sparsity().size2();
1330  }
1331 
1332  template<typename MatType>
1333  std::pair<casadi_int, casadi_int> GenericMatrix<MatType>::size() const {
1334  return sparsity().size();
1335  }
1336 
1337  template<typename MatType>
1338  casadi_int GenericMatrix<MatType>::size(casadi_int axis) const {
1339  return sparsity().size(axis);
1340  }
1341 
1342  template<typename MatType>
1343  std::string GenericMatrix<MatType>::dim(bool with_nz) const {
1344  return sparsity().dim(with_nz);
1345  }
1346 
1347  template<typename MatType>
1348  bool GenericMatrix<MatType>::is_scalar(bool scalar_and_dense) const {
1349  return sparsity().is_scalar(scalar_and_dense);
1350  }
1351 
1352 #endif // SWIG
1353 
1354  template<typename MatType>
1355  std::vector<MatType> GenericMatrix<MatType>::sym(const std::string& name,
1356  const Sparsity& sp, casadi_int p) {
1357  std::vector<MatType> ret(p);
1358  std::stringstream ss;
1359  for (casadi_int k=0; k<p; ++k) {
1360  ss.str("");
1361  ss << name << k;
1362  ret[k] = sym(ss.str(), sp);
1363  }
1364  return ret;
1365  }
1366 
1367  template<typename MatType>
1368  std::vector<std::vector<MatType> > GenericMatrix<MatType>::sym(const std::string& name,
1369  const Sparsity& sp, casadi_int p,
1370  casadi_int r) {
1371  std::vector<std::vector<MatType> > ret(r);
1372  for (casadi_int k=0; k<r; ++k) {
1373  std::stringstream ss;
1374  ss << name << "_" << k;
1375  ret[k] = sym(ss.str(), sp, p);
1376  }
1377  return ret;
1378  }
1379 
1380  template<typename MatType>
1381  MatType GenericMatrix<MatType>::linspace(const MatType& a, const MatType& b, casadi_int nsteps) {
1382  std::vector<MatType> ret(nsteps);
1383  ret[0] = a;
1384  MatType step = (b-a)/static_cast<MatType>(nsteps-1);
1385 
1386  for (casadi_int i=1; i<nsteps-1; ++i)
1387  ret[i] = a + i * step;
1388 
1389  ret[nsteps-1] = b;
1390  return vertcat(ret);
1391  }
1392 
1393  template<typename MatType>
1394  MatType GenericMatrix<MatType>::cross(const MatType& a, const MatType& b, casadi_int dim) {
1395  casadi_assert(a.size1()==b.size1() && a.size2()==b.size2(),
1396  "cross(a, b): Inconsistent dimensions. Dimension of a ("
1397  + a.dim() + " ) must equal that of b (" + b.dim() + ").");
1398 
1399  casadi_assert(a.size1()==3 || a.size2()==3,
1400  "cross(a, b): One of the dimensions of a should have length 3, but got "
1401  + a.dim() + ".");
1402  casadi_assert(dim==-1 || dim==1 || dim==2,
1403  "cross(a, b, dim): Dim must be 1, 2 or -1 (automatic).");
1404 
1405  std::vector<MatType> ret(3);
1406 
1407  bool t = a.size1()==3;
1408 
1409  if (dim==1) t = true;
1410  if (dim==2) t = false;
1411 
1412  MatType a1 = t ? a(0, Slice()) : a(Slice(), 0);
1413  MatType a2 = t ? a(1, Slice()) : a(Slice(), 1);
1414  MatType a3 = t ? a(2, Slice()) : a(Slice(), 2);
1415 
1416  MatType b1 = t ? b(0, Slice()) : b(Slice(), 0);
1417  MatType b2 = t ? b(1, Slice()) : b(Slice(), 1);
1418  MatType b3 = t ? b(2, Slice()) : b(Slice(), 2);
1419 
1420  ret[0] = a2*b3-a3*b2;
1421  ret[1] = a3*b1-a1*b3;
1422  ret[2] = a1*b2-a2*b1;
1423 
1424  return t ? vertcat(ret) : horzcat(ret);
1425  }
1426 
1427  double CASADI_EXPORT index_interp1d(const std::vector<double>& x, double xq,
1428  bool equidistant=false);
1429 
1430  template<typename MatType>
1431  MatType GenericMatrix<MatType>::interp1d(const std::vector<double>& x, const MatType& v,
1432  const std::vector<double>& xq, const std::string& mode, bool equidistant) {
1433 
1434  bool mode_floor = false;
1435  bool mode_ceil = false;
1436  if (mode=="floor") {
1437  mode_floor = true;
1438  } else if (mode=="ceil") {
1439  mode_ceil = true;
1440  } else if (mode=="linear") {
1441  //
1442  } else {
1443  casadi_error("interp1d(x, v, xq, mode): "
1444  "Mode must be 'floor', 'ceil' or 'linear'. Got '" + mode + "' instead.");
1445  }
1446 
1447  casadi_assert(is_increasing(x), "interp1d(x, v, xq): x must be increasing.");
1448 
1449  casadi_assert(x.size()==v.size1(),
1450  "interp1d(x, v, xq): dimensions mismatch. v expected to have " + str(x.size()) + " rows,"
1451  " but got " + str(v.size1()) + " instead.");
1452 
1453  // Need at least two elements
1454  casadi_assert(x.size()>=2, "interp1d(x, v, xq): x must be at least length 2.");
1455 
1456  // Vectors to compose a sparse matrix
1457  std::vector<double> val;
1458  std::vector<casadi_int> colind(1, 0);
1459  std::vector<casadi_int> row;
1460 
1461  // Number of nonzeros in to-be composed matrix
1462  casadi_int nnz = 0;
1463  for (casadi_int i=0;i<xq.size();++i) {
1464  // Obtain index corresponding to xq[i]
1465  double ind = index_interp1d(x, xq[i], equidistant);
1466 
1467  if (mode_floor) ind = floor(ind);
1468  if (mode_ceil) ind = ceil(ind);
1469 
1470  // Split into integer and fractional part
1471  double int_partd;
1472  double frac_part = modf(ind, &int_partd);
1473  casadi_int int_part = static_cast<casadi_int>(int_partd);
1474 
1475  if (frac_part==0) {
1476  // Create a single entry
1477  val.push_back(1);
1478  row.push_back(int_part);
1479  nnz+=1;
1480  colind.push_back(nnz);
1481  } else {
1482  // Create a double entry
1483  val.push_back(1-frac_part);
1484  val.push_back(frac_part);
1485  row.push_back(int_part);
1486  row.push_back(int_part+1);
1487  nnz+=2;
1488  colind.push_back(nnz);
1489  }
1490  }
1491 
1492  // Construct sparsity for composed matrix
1493  Sparsity sp(x.size(), xq.size() , colind, row);
1494 
1495  return MatType::mtimes(MatType(sp, val).T(), v);
1496 
1497  }
1498 
1499  template<typename MatType>
1500  MatType GenericMatrix<MatType>::skew(const MatType& a) {
1501  casadi_assert(a.is_vector() && (a.size1()==3 || a.size2()==3),
1502  "skew(a): Expecting 3-vector, got " + a.dim() + ".");
1503 
1504  MatType x = a(0);
1505  MatType y = a(1);
1506  MatType z = a(2);
1507  return blockcat(std::vector< std::vector<MatType> >({{0, -z, y}, {z, 0, -x}, {-y, x, 0}}));
1508  }
1509 
1510  template<typename MatType>
1511  MatType GenericMatrix<MatType>::inv_skew(const MatType& a) {
1512  casadi_assert(a.size1()==3 && a.size2()==3,
1513  "inv_skew(a): Expecting 3-by-3 matrix, got " + a.dim() + ".");
1514 
1515  return 0.5*vertcat(std::vector<MatType>({a(2, 1)-a(1, 2), a(0, 2)-a(2, 0), a(1, 0)-a(0, 1)}));
1516  }
1517 
1518 
1519  template<typename MatType>
1520  MatType GenericMatrix<MatType>::tril2symm(const MatType& x) {
1521  casadi_assert(x.is_square(),
1522  "Shape error in tril2symm. Expecting square shape but got " + x.dim());
1523  casadi_assert(x.nnz_upper()-x.nnz_diag()==0,
1524  "Sparsity error in tril2symm. Found above-diagonal entries in argument: " + x.dim());
1525  return x + x.T() - diag(diag(x));
1526  }
1527 
1528  template<typename MatType>
1529  MatType GenericMatrix<MatType>::repsum(const MatType& x, casadi_int n, casadi_int m) {
1530  casadi_assert_dev(x.size1() % n==0);
1531  casadi_assert_dev(x.size2() % m==0);
1532  std::vector< std::vector< MatType> > s =
1533  blocksplit(x, x.size1()/n, x.size2()/m);
1534  MatType sum = 0;
1535  for (casadi_int i=0;i<s.size();++i) {
1536  for (casadi_int j=0;j<s[i].size();++j) {
1537  sum = sum + s[i][j];
1538  }
1539  }
1540  return sum;
1541  }
1542 
1543  template<typename MatType>
1544  MatType GenericMatrix<MatType>::triu2symm(const MatType& x) {
1545  casadi_assert(x.is_square(),
1546  "Shape error in triu2symm. Expecting square shape but got " + x.dim());
1547  casadi_assert(x.nnz_lower()-x.nnz_diag()==0,
1548  "Sparsity error in triu2symm. Found below-diagonal entries in argument: " + x.dim());
1549  return x + x.T() - diag(diag(x));
1550  }
1551 
1552  template<typename MatType>
1553  MatType GenericMatrix<MatType>::bilin(const MatType& A, const MatType& x,
1554  const MatType& y) {
1555  // Check/correct x
1556  casadi_assert_dev(x.is_vector());
1557  if (!x.is_column()) return bilin(A, x.T(), y);
1558  if (!x.is_dense()) return bilin(A, densify(x), y);
1559 
1560  // Check/correct y
1561  casadi_assert_dev(y.is_vector());
1562  if (!y.is_column()) return bilin(A, x, y.T());
1563  if (!y.is_dense()) return bilin(A, x, densify(y));
1564 
1565  // Assert dimensions
1566  casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1567  "Dimension mismatch. Got x.size1() = " + str(x.size1())
1568  + " and y.size1() = " + str(y.size1()) + " but A.size() = " + str(A.size()));
1569 
1570  // Call the class specific method
1571  return MatType::_bilin(A, x, y);
1572  }
1573 
1574  template<typename MatType>
1575  MatType GenericMatrix<MatType>::rank1(const MatType& A, const MatType& alpha,
1576  const MatType& x, const MatType& y) {
1577  // Check/correct x
1578  casadi_assert_dev(x.is_vector());
1579  if (!x.is_column()) return rank1(A, alpha, x.T(), y);
1580  if (!x.is_dense()) return rank1(A, alpha, densify(x), y);
1581 
1582  // Check/correct y
1583  casadi_assert_dev(y.is_vector());
1584  if (!y.is_column()) return rank1(A, alpha, x, y.T());
1585  if (!y.is_dense()) return rank1(A, alpha, x, densify(y));
1586 
1587  // Check alpha, quick return
1588  casadi_assert_dev(alpha.is_scalar());
1589  if (!alpha.is_dense()) return A;
1590 
1591  // Assert dimensions
1592  casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
1593  "Dimension mismatch. Got x.size1() = " + str(x.size1())
1594  + " and y.size1() = " + str(y.size1())
1595  + " but A.size() = " + str(A.size()));
1596 
1597  // Call the class specific method
1598  return MatType::_rank1(A, alpha, x, y);
1599  }
1600 
1601  template<typename MatType>
1602  MatType GenericMatrix<MatType>::logsumexp(const MatType& x) {
1603  casadi_assert(x.is_dense(), "Argument must be dense");
1604  casadi_assert(x.is_column(), "Argument must be column vector");
1605  // Call the class specific method
1606  return MatType::_logsumexp(x);
1607  }
1608 
1609  template<typename MatType>
1610  MatType GenericMatrix<MatType>::jtimes(const MatType &ex, const MatType &arg,
1611  const MatType &v, bool tr, const Dict& opts) {
1612  try {
1613  // Assert consistent input dimensions
1614  if (tr) {
1615  if (ex.size2()==0 && v.size2()>0) {
1616  casadi_error("Ambiguous dimensions.");
1617  }
1618  casadi_assert(v.size1() == ex.size1() &&
1619  (v.size2()==0 || ex.size2()==0 || v.size2() % ex.size2() == 0),
1620  "'v' has inconsistent dimensions: "
1621  " v " + v.dim(false) + ", ex " + ex.dim(false) + ".");
1622  } else {
1623  if (arg.size2()==0 && v.size2()>0) {
1624  casadi_error("Ambiguous dimensions.");
1625  }
1626  casadi_assert(v.size1() == arg.size1() &&
1627  (v.size2()==0 || arg.size2()==0 || v.size2() % arg.size2() == 0),
1628  "'v' has inconsistent dimensions: "
1629  " v " + v.dim(false) + ", arg " + arg.dim(false) + ".");
1630  }
1631 
1632  casadi_int n_seeds = 1;
1633  if (tr) {
1634  if (ex.size2()>0) n_seeds = v.size2() / ex.size2();
1635  } else {
1636  if (arg.size2()>0) n_seeds = v.size2() / arg.size2();
1637  }
1638 
1639  // Quick return if no seeds
1640  if (v.is_empty() || ex.is_empty()) {
1641  return MatType(tr ? arg.size1() : ex.size1(),
1642  tr ? arg.size2()*n_seeds : ex.size2()*n_seeds);
1643  }
1644 
1645  // Split up the seed into its components
1646  std::vector<MatType> w = horzsplit(v, tr ? ex.size2() : arg.size2());
1647 
1648  // Seeds as a vector of vectors
1649  std::vector<std::vector<MatType> > ww(w.size());
1650  for (casadi_int i=0; i<w.size(); ++i) ww[i] = {w[i]};
1651 
1652  // Calculate directional derivatives
1653  if (tr) {
1654  ww = reverse({ex}, {arg}, ww, opts);
1655  } else {
1656  ww = forward({ex}, {arg}, ww, opts);
1657  }
1658 
1659  // Get results
1660  for (casadi_int i=0; i<w.size(); ++i) w[i] = ww[i][0];
1661  return horzcat(w);
1662  } catch (std::exception& e) {
1663  CASADI_THROW_ERROR("jtimes", e.what());
1664  }
1665  }
1666 
1667  template<typename MatType>
1668  MatType GenericMatrix<MatType>::gradient(const MatType &ex, const MatType &arg,
1669  const Dict& opts) {
1670  try {
1671  casadi_assert(ex.is_scalar(),
1672  "'gradient' only defined for scalar outputs: Use 'jacobian' instead.");
1673  return project(jtimes(ex, arg, MatType::ones(ex.sparsity()), true, opts), arg.sparsity());
1674  } catch (std::exception& e) {
1675  CASADI_THROW_ERROR("gradient", e.what());
1676  }
1677  }
1678 
1679  template<typename MatType>
1680  MatType GenericMatrix<MatType>::tangent(const MatType &ex, const MatType &arg,
1681  const Dict& opts) {
1682  try {
1683  casadi_assert(arg.is_scalar(),
1684  "'tangent' only defined for scalar inputs: Use 'jacobian' instead.");
1685  return project(jtimes(ex, arg, MatType::ones(arg.sparsity()), false, opts), ex.sparsity());
1686  } catch (std::exception& e) {
1687  CASADI_THROW_ERROR("tangent", e.what());
1688  }
1689  }
1690 
1691  template<typename MatType>
1692  MatType GenericMatrix<MatType>::
1693  linearize(const MatType& f, const MatType& x, const MatType& x0, const Dict& opts) {
1694  MatType x_lin = MatType::sym("x_lin", x.sparsity());
1695  // mismatching dimensions
1696  if (x0.size() != x.size()) {
1697  // Scalar x0 is ok
1698  if (x0.sparsity().is_scalar()) {
1699  return linearize(f, x, MatType(x.sparsity(), x0));
1700  }
1701  casadi_error("Dimension mismatch in 'linearize'");
1702  }
1703  return substitute(f + jtimes(f, x, x_lin, false, opts),
1704  MatType::vertcat({x_lin, x}), MatType::vertcat({x, x0}));
1705  }
1706 
1707  template<typename MatType>
1708  MatType GenericMatrix<MatType>::mpower(const MatType& a,
1709  const MatType& b) {
1710  if (a.is_scalar() && b.is_scalar()) return pow(a, b);
1711  casadi_assert(a.is_square() && b.is_constant() && b.is_scalar(),
1712  "Not Implemented");
1713  double bv = static_cast<double>(b);
1714  casadi_int N = static_cast<casadi_int>(bv);
1715  casadi_assert(bv-static_cast<double>(N)==0, "mpower only defined for integer powers.");
1716  casadi_assert(bv==N, "Not Implemented");
1717  if (N<0) return inv(mpower(a, -N));
1718  if (N==0) return MatType::eye(a.size1());
1719  if (N==1) return a;
1720  if (N % 2 == 0) {
1721  MatType h = mpower(a, N/2); // NOLINT
1722  return MatType::mtimes(h, h);
1723  } else {
1724  return MatType::mtimes(mpower(a, N-1), a);
1725  }
1726  }
1727 
1728  template<typename MatType>
1729  MatType GenericMatrix<MatType>::soc(const MatType& x,
1730  const MatType& y) {
1731  casadi_assert(y.is_scalar(), "y needs to be scalar. Got " + y.dim() + ".");
1732  casadi_assert(x.is_vector(), "x needs to be a vector. Got " + x.dim() + ".");
1733 
1734  MatType x_col = x.is_column() ? x : x.T();
1735 
1736  x_col = x_col.nz(Slice()); // NOLINT
1737 
1738  casadi_int n = x_col.numel();
1739  return blockcat(y*MatType::eye(n), x_col, x_col.T(), y);
1740  }
1741 
1742  template<typename MatType>
1743  bool GenericMatrix<MatType>::is_linear(const MatType &expr, const MatType &var) {
1744  return !any(MatType::which_depends(expr, var, 2, true));
1745  }
1746 
1747  template<typename MatType>
1748  bool GenericMatrix<MatType>::is_quadratic(const MatType &expr, const MatType &var) {
1749  return is_linear(gradient(expr, var), var);
1750  }
1751 
1752  template<typename MatType>
1753  void GenericMatrix<MatType>::quadratic_coeff(const MatType &expr, const MatType &var,
1754  MatType& A, MatType& b, MatType& c, bool check) {
1755  casadi_assert(expr.is_scalar(), "'quadratic_coeff' only defined for scalar expressions.");
1756  A = hessian(expr, var);
1757  b = substitute(jacobian(expr, var), var, 0).T();
1758  if (check)
1759  casadi_assert(!depends_on(A, var), "'quadratic_coeff' called on non-quadratic expression.");
1760  c = substitute(expr, var, 0);
1761  }
1762 
1763  template<typename MatType>
1764  void GenericMatrix<MatType>::linear_coeff(const MatType &expr, const MatType &var,
1765  MatType& A, MatType& b, bool check) {
1766  casadi_assert(expr.is_vector(), "'linear_coeff' only defined for vector expressions.");
1767  if (check)
1768  casadi_assert(is_linear(expr, var), "'linear_coeff' called on non-linear expression.");
1769  A = substitute(jacobian(expr, var), var, 0);
1770  b = vec(substitute(expr, var, 0));
1771  }
1772 
1773  template<typename MatType>
1774  MatType GenericMatrix<MatType>::diff(const MatType& x, casadi_int n, casadi_int axis) {
1775  casadi_assert(axis==-1 || axis==0 || axis==1, "Axis argument invalid");
1776  casadi_assert(n>=1, "n argument invalid");
1777 
1778  MatType ret = x;
1779  for (casadi_int i=0;i<n;++i) {
1780  // Matlab's special case
1781  if (axis==-1 && ret.is_scalar()) return MatType();
1782 
1783  casadi_int local_axis = (axis==-1) ? ret.is_row() : axis;
1784  if (local_axis==0) {
1785  if (ret.size1()<=1) {
1786  ret = MatType::zeros(0, ret.size2());
1787  } else {
1788  ret = ret(Slice(1, ret.size1()), Slice())-ret(Slice(0, ret.size1()-1), Slice());
1789  }
1790  } else {
1791  if (ret.size2()<=1) {
1792  ret = MatType::zeros(ret.size1(), 0);
1793  } else {
1794  ret = ret(Slice(), Slice(1, ret.size2()))-ret(Slice(), Slice(0, ret.size2()-1));
1795  }
1796  }
1797  }
1798  return ret;
1799  }
1800 
1801 #undef CASADI_THROW_ERROR
1802 
1803 } // namespace casadi
1804 
1805 #endif // CASADI_GENERIC_MATRIX_HPP
Matrix base class.
static MatType interp1d(const std::vector< double > &x, const MatType &v, const std::vector< double > &xq, const std::string &mode, bool equidistant)
Functions called by friend functions defined here.
Sparsity sparsity() const
Get the sparsity pattern.
const MatType operator()(const RR &rr, const CC &cc) const
Get Matrix element or slice.
static casadi_int sprank(const MatType &x)
Functions called by friend functions defined here.
casadi_int numel() const
Get the number of elements.
static casadi_int norm_0_mul(const MatType &x, const MatType &y)
Functions called by friend functions defined here.
bool is_dense() const
Check if the matrix expression is dense.
bool is_column() const
Check if the matrix is a column vector (i.e. size2()==1)
static MatType zeros(const Sparsity &sp)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
static void quadratic_coeff(const MatType &expr, const MatType &var, MatType &A, MatType &b, MatType &c, bool check)
Functions called by friend functions defined here.
bool is_empty(bool both=false) const
Check if the sparsity is empty, i.e. if one of the dimensions is zero.
std::pair< casadi_int, casadi_int > size() const
Get the shape.
casadi_int row(casadi_int el) const
Get the sparsity pattern. See the Sparsity class for details.
std::vector< casadi_int > get_colind() const
Get the sparsity pattern. See the Sparsity class for details.
bool is_vector() const
Check if the matrix is a row or column vector.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
casadi_int size2() const
Get the second dimension (i.e. number of columns)
static void linear_coeff(const MatType &expr, const MatType &var, MatType &A, MatType &b, bool check)
Functions called by friend functions defined here.
static bool is_quadratic(const MatType &expr, const MatType &var)
Functions called by friend functions defined here.
casadi_int rows() const
Get the number of rows, Octave-style syntax.
SubMatrix< MatType, RR, CC > operator()(const RR &rr, const CC &cc)
Access Matrix elements (two arguments)
static MatType sumsqr(const MatType &x)
Functions called by friend functions defined here.
const MatType nz(const K &k) const
Get vector nonzero or slice of nonzeros.
bool is_tril() const
Check if the matrix is lower triangular.
static MatType zeros(const std::pair< casadi_int, casadi_int > &rc)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
static MatType sym(const std::string &name, const std::pair< casadi_int, casadi_int > &rc)
Construct a symbolic primitive with given dimensions.
static MatType sym(const std::string &name, const Sparsity &sp)
Create symbolic primitive with a given sparsity pattern.
static MatType diff(const MatType &x, casadi_int n=1, casadi_int axis=-1)
Functions called by friend functions defined here.
static MatType cross(const MatType &a, const MatType &b, casadi_int dim=-1)
Functions called by friend functions defined here.
static std::vector< MatType > sym(const std::string &name, casadi_int nrow, casadi_int ncol, casadi_int p)
Create a vector of length p with nrow-by-ncol symbolic primitives.
const MatType operator()(const RR &rr) const
Get vector element or slice.
casadi_int size(casadi_int axis) const
Get the size along a particular dimensions.
casadi_int nnz_upper() const
Get the number of non-zeros in the upper triangular half.
bool is_row() const
Check if the matrix is a row vector (i.e. size1()==1)
bool is_triu() const
Check if the matrix is upper triangular.
casadi_int size1() const
Get the first dimension (i.e. number of rows)
static MatType tril(const MatType &x, bool includeDiagonal=true)
Functions called by friend functions defined here.
static MatType linspace(const MatType &a, const MatType &b, casadi_int nsteps)
Functions called by friend functions defined here.
static bool is_linear(const MatType &expr, const MatType &var)
Functions called by friend functions defined here.
NonZeros< MatType, K > nz(const K &k)
Access vector nonzero or slice of nonzeros.
std::string dim(bool with_nz=false) const
Get string representation of dimensions.
casadi_int nnz_diag() const
Get get the number of non-zeros on the diagonal.
static MatType ones(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries one.
static MatType ones(const Sparsity &sp)
Create a dense matrix or a matrix with specified sparsity with all entries one.
static MatType sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
static std::vector< std::vector< MatType > > sym(const std::string &name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r)
Create a vector of length r of vectors of length p.
static MatType ones(const std::pair< casadi_int, casadi_int > &rc)
Create a dense matrix or a matrix with specified sparsity with all entries one.
const casadi_int * colind() const
Get the sparsity pattern. See the Sparsity class for details.
SubIndex< MatType, RR > operator()(const RR &rr)
Access Matrix elements (one argument)
casadi_int colind(casadi_int col) const
Get the sparsity pattern. See the Sparsity class for details.
static MatType repsum(const MatType &x, casadi_int n, casadi_int m=1)
Functions called by friend functions defined here.
static MatType triu2symm(const MatType &x)
Functions called by friend functions defined here.
static MatType inv_skew(const MatType &a)
Functions called by friend functions defined here.
const casadi_int * row() const
Get the sparsity pattern. See the Sparsity class for details.
bool is_square() const
Check if the matrix expression is square.
static MatType skew(const MatType &a)
Functions called by friend functions defined here.
static std::vector< MatType > sym(const std::string &name, const Sparsity &sp, casadi_int p)
Create a vector of length p with with matrices.
static MatType triu(const MatType &x, bool includeDiagonal=true)
Functions called by friend functions defined here.
casadi_int columns() const
Get the number of columns, Octave-style syntax.
static MatType tril2symm(const MatType &x)
Functions called by friend functions defined here.
static MatType zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
std::vector< casadi_int > get_row() const
Get the sparsity pattern. See the Sparsity class for details.
static std::vector< std::vector< MatType > > sym(const std::string &name, const Sparsity &sp, casadi_int p, casadi_int r)
Create a vector of length r of vectors of length p with.
casadi_int nnz_lower() const
Get the number of non-zeros in the lower triangular half.
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix expression is scalar.
Access to a set of nonzeros.
Definition: nonzeros.hpp:40
Class representing a Slice.
Definition: slice.hpp:48
Sparsity interface class.
static MatType veccat(const std::vector< MatType > &x)
General sparsity class.
Definition: sparsity.hpp:106
bool is_vector() const
Check if the pattern is a row or column vector.
Definition: sparsity.cpp:289
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Definition: sparsity.cpp:1012
static Sparsity triu(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
Definition: sparsity.cpp:983
bool is_column() const
Check if the pattern is a column vector (i.e. size2()==1)
Definition: sparsity.cpp:285
bool is_row() const
Check if the pattern is a row vector (i.e. size1()==1)
Definition: sparsity.cpp:281
static Sparsity tril(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
Definition: sparsity.cpp:979
bool is_tril(bool strictly=false) const
Is lower triangular?
Definition: sparsity.cpp:321
const casadi_int * row() const
Get a reference to row-vector,.
Definition: sparsity.cpp:164
std::vector< casadi_int > get_colind() const
Get the column index for each column.
Definition: sparsity.cpp:364
static casadi_int sprank(const Sparsity &x)
Enlarge matrix.
Definition: sparsity.cpp:1655
bool is_empty(bool both=false) const
Check if the sparsity is empty.
Definition: sparsity.cpp:144
static casadi_int norm_0_mul(const Sparsity &x, const Sparsity &A)
Enlarge matrix.
Definition: sparsity.cpp:1665
std::vector< casadi_int > get_row() const
Get the row for each non-zero entry.
Definition: sparsity.cpp:372
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
Definition: sparsity.cpp:168
bool is_dense() const
Is dense?
Definition: sparsity.cpp:273
bool is_square() const
Is square?
Definition: sparsity.cpp:293
bool is_triu(bool strictly=false) const
Is upper triangular?
Definition: sparsity.cpp:325
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 bool is_quadratic(const MatType &expr, const MatType &var)
Is expr quadratic in var?
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 MatType linspace(const MatType &a, const MatType &b, casadi_int nsteps)
Matlab's linspace command.
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 inv_skew(const MatType &a)
Generate the 3-vector progenitor of a skew symmetric matrix.
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 sumsqr(const MatType &x)
Calculate sum of squares: sum_ij X_ij^2.
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 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 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 skew(const MatType &a)
Generate a skew symmetric matrix from a 3-vector.
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 MatType cross(const MatType &a, const MatType &b, casadi_int dim=-1)
Matlab's cross command.
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 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 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 substitute(const MatType &ex, const MatType &v, const MatType &vdef)
Substitute variable v with expression vdef in an expression ex.
friend bool is_linear(const MatType &expr, const MatType &var)
Is expr linear in var?
friend MatType norm_1(const MatType &x)
1-norm
friend MatType logsumexp(const MatType &x, const MatType &margin)
Scaled version of logsumexp.
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 Sparsity jacobian_sparsity(const MatType &f, const MatType &x)
Get the sparsity pattern of a jacobian.
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 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 MatType tril2symm(const MatType &a)
Convert a lower triangular matrix to a symmetric one.
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 repsum(const MatType &A, casadi_int n, casadi_int m=1)
Given a repeated matrix, computes the sum of repeated parts.
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 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 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 reshape(const MatType &x, casadi_int nrow, casadi_int ncol)
Returns a reshaped version of the matrix.
friend MatType cumsum(const MatType &x, casadi_int axis=-1)
Returns cumulative sum along given axis (MATLAB convention)
friend MatType triu2symm(const MatType &a)
Convert a upper triangular matrix to a symmetric one.
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 unite(const MatType &A, const MatType &B)
Unite two matrices no overlapping sparsity.
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 void linear_coeff(const MatType &expr, const MatType &var, MatType &A, MatType &b, bool check=true)
Recognizes linear form in vector expression.
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.cpp:28
double index_interp1d(const std::vector< double > &x, double xq, bool equidistant)
bool is_increasing(const std::vector< T > &v)
Check if the vector is strictly increasing.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
bool any(const std::vector< bool > &v)
Check if any arguments are true.
Definition: casadi_misc.cpp:84
T sum(const std::vector< T > &values)
sum
std::vector< T > reverse(const std::vector< T > &v)
Reverse a list.