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 
123  casadi_int nnz() const;
124 
153  casadi_int nnz_lower() const;
154 
183  casadi_int nnz_upper() const;
184 
215  casadi_int nnz_diag() const;
216 
247  casadi_int numel() const;
248 
278  casadi_int size1() const;
279 
283  casadi_int rows() const {return size1();}
284 
290  casadi_int size2() const;
291 
295  casadi_int columns() const {return size2();}
296 
325  std::string dim(bool with_nz=false) const;
326 
358  std::pair<casadi_int, casadi_int> size() const;
359 
366  casadi_int size(casadi_int axis) const;
367 
402  bool is_empty(bool both=false) const { return sparsity().is_empty(both);}
403 
434  bool is_dense() const { return sparsity().is_dense();}
435 
465  bool is_scalar(bool scalar_and_dense=false) const;
466 
470  bool is_square() const { return sparsity().is_square();}
471 
507  bool is_vector() const { return sparsity().is_vector();}
508 
512  bool is_row() const { return sparsity().is_row();}
513 
517  bool is_column() const { return sparsity().is_column();}
518 
551  bool is_triu() const { return sparsity().is_triu();}
552 
560  bool is_tril() const { return sparsity().is_tril();}
561 
563 
602  std::vector<casadi_int> get_row() const { return sparsity().get_row(); }
603  std::vector<casadi_int> get_colind() const { return sparsity().get_colind(); }
604 #ifndef SWIG
605  const casadi_int* row() const { return sparsity().row(); }
606  const casadi_int* colind() const { return sparsity().colind(); }
607 #endif
608  casadi_int row(casadi_int el) const { return sparsity().row(el); }
609  casadi_int colind(casadi_int col) const { return sparsity().colind(col); }
611 
642  SWIG_CONSTREF(Sparsity) sparsity() const;
643 
644 #ifndef SWIG
646 
648  static MatType interp1d(const std::vector<double>& x, const MatType &v,
649  const std::vector<double>& xq, const std::string& mode, bool equidistant);
650  static casadi_int sprank(const MatType &x) { return Sparsity::sprank(x.sparsity());}
651  static casadi_int norm_0_mul(const MatType &x, const MatType &y) {
652  return Sparsity::norm_0_mul(x.sparsity(), y.sparsity());
653  }
654  static MatType tril(const MatType &x, bool includeDiagonal=true) {
655  return project(x, Sparsity::tril(x.sparsity(), includeDiagonal));
656  }
657  static MatType triu(const MatType &x, bool includeDiagonal=true) {
658  return project(x, Sparsity::triu(x.sparsity(), includeDiagonal));
659  }
660  static MatType sumsqr(const MatType &x) { return dot(x, x);}
661  static MatType linspace(const MatType &a, const MatType &b, casadi_int nsteps);
662  static MatType cross(const MatType &a, const MatType &b, casadi_int dim=-1);
663  static MatType skew(const MatType &a);
664  static MatType inv_skew(const MatType &a);
665  static MatType tril2symm(const MatType &x);
666  static MatType triu2symm(const MatType &x);
667  static MatType repsum(const MatType &x, casadi_int n, casadi_int m=1);
668  static MatType diff(const MatType &x, casadi_int n=1, casadi_int axis=-1);
669 
670  static bool is_linear(const MatType &expr, const MatType &var);
671  static bool is_quadratic(const MatType &expr, const MatType &var);
672  static void quadratic_coeff(const MatType &expr, const MatType &var,
673  MatType& A, MatType& b, MatType& c, bool check);
674  static void linear_coeff(const MatType &expr, const MatType &var,
675  MatType& A, MatType& b, bool check);
678 
682  template<typename K>
683  const MatType nz(const K& k) const {
684  MatType ret;
685  self().get_nz(ret, false, k);
686  return ret;
687  }
688 
692  template<typename K>
693  NonZeros<MatType, K> nz(const K& k) {
694  return NonZeros<MatType, K>(self(), k);
695  }
696 
700  template<typename RR>
701  const MatType operator()(const RR& rr) const {
702  MatType ret;
703  self().get(ret, false, rr);
704  return ret;
705  }
706 
710  template<typename RR, typename CC>
711  const MatType operator()(const RR& rr, const CC& cc) const {
712  MatType ret;
713  self().get(ret, false, rr, cc);
714  return ret;
715  }
716 
720  template<typename RR>
721  SubIndex<MatType, RR> operator()(const RR& rr) {
722  return SubIndex<MatType, RR>(self(), rr);
723  }
724 
728  template<typename RR, typename CC>
729  SubMatrix<MatType, RR, CC> operator()(const RR& rr, const CC& cc) {
730  return SubMatrix<MatType, RR, CC>(self(), rr, cc);
731  }
732 #endif // SWIG
733 
734 #if !defined(SWIG) || defined(DOXYGEN)
812  inline friend MatType interp1d(const std::vector<double>& x, const MatType&v,
813  const std::vector<double>& xq, const std::string& mode, bool equidistant=false) {
814  return MatType::interp1d(x, v, xq, mode, equidistant);
815  }
816 
891  inline friend MatType mpower(const MatType& x, const MatType& n) {
892  return MatType::mpower(x, n);
893  }
894 
936  inline friend MatType soc(const MatType& x, const MatType& y) {
937  return MatType::soc(x, y);
938  }
939 
1001  inline friend MatType
1002  einstein(const MatType &A, const MatType &B, const MatType &C,
1003  const std::vector<casadi_int>& dim_a, const std::vector<casadi_int>& dim_b,
1004  const std::vector<casadi_int>& dim_c,
1005  const std::vector<casadi_int>& a, const std::vector<casadi_int>& b,
1006  const std::vector<casadi_int>& c) {
1007  return MatType::einstein(A, B, C, dim_a, dim_b, dim_c, a, b, c);
1008  }
1009 
1010  inline friend MatType
1011  einstein(const MatType &A, const MatType &B,
1012  const std::vector<casadi_int>& dim_a, const std::vector<casadi_int>& dim_b,
1013  const std::vector<casadi_int>& dim_c,
1014  const std::vector<casadi_int>& a, const std::vector<casadi_int>& b,
1015  const std::vector<casadi_int>& c) {
1016  return MatType::einstein(A, B, dim_a, dim_b, dim_c, a, b, c);
1017  }
1019 
1052  inline friend MatType mrdivide(const MatType& x, const MatType& n) {
1053  return MatType::mrdivide(x, n);
1054  }
1055 
1088  inline friend MatType mldivide(const MatType& x, const MatType& n) {
1089  return MatType::mldivide(x, n);
1090  }
1091 
1157  inline friend std::vector<MatType> symvar(const MatType& x) {
1158  return MatType::symvar(x);
1159  }
1160 
1162 
1207  inline friend MatType bilin(const MatType &A, const MatType &x, const MatType &y) {
1208  return MatType::bilin(A, x, y);
1209  }
1210  inline friend MatType bilin(const MatType &A, const MatType &x) {
1211  return MatType::bilin(A, x, x);
1212  }
1213  static MatType bilin(const MatType& A, const MatType& x, const MatType& y);
1215 
1217 
1263  inline friend MatType rank1(const MatType &A, const MatType &alpha,
1264  const MatType &x, const MatType &y) {
1265  return MatType::rank1(A, alpha, x, y);
1266  }
1267  static MatType rank1(const MatType& A, const MatType& alpha,
1268  const MatType& x, const MatType& y);
1270 
1312  inline friend MatType sumsqr(const MatType &x) {
1313  return MatType::sumsqr(x);
1314  }
1315 
1369  inline friend MatType logsumexp(const MatType& x) {
1370  return MatType::logsumexp(x);
1371  }
1400  inline friend MatType logsumexp(const MatType& x, const MatType& margin) {
1401  MatType alpha = log(x.size1()) / margin;
1402  return MatType::logsumexp(alpha*x)/alpha;
1403  }
1404  static MatType logsumexp(const MatType& x);
1405 
1447  inline friend MatType linspace(const MatType &a, const MatType &b, casadi_int nsteps) {
1448  return MatType::linspace(a, b, nsteps);
1449  }
1450 
1501  inline friend MatType cross(const MatType &a, const MatType &b, casadi_int dim = -1) {
1502  return MatType::cross(a, b, dim);
1503  }
1504 
1547  inline friend MatType skew(const MatType &a) {
1548  return MatType::skew(a);
1549  }
1550 
1560  inline friend MatType inv_skew(const MatType &a) {
1561  return MatType::inv_skew(a);
1562  }
1563 
1607  inline friend MatType det(const MatType& A) { return MatType::det(A);}
1608 
1639  inline friend MatType det(const MatType& A, const std::string& lsolver,
1640  const Dict& dict=Dict()) {
1641  return MatType::det(A, lsolver, dict);
1642  }
1643 
1678  inline friend MatType inv_minor(const MatType& A) { return MatType::inv_minor(A);}
1679 
1737  inline friend MatType inv(const MatType& A) {
1738  return MatType::inv(A);
1739  }
1740 
1776  inline friend MatType inv(const MatType& A,
1777  const std::string& lsolver,
1778  const Dict& options=Dict()) {
1779  return MatType::inv(A, lsolver, options);
1780  }
1781 
1817  inline friend MatType trace(const MatType& x) { return MatType::trace(x);}
1818 
1871  inline friend MatType tril2symm(const MatType &a) { return MatType::tril2symm(a);}
1872 
1910  inline friend MatType triu2symm(const MatType &a) { return MatType::triu2symm(a);}
1911 
1948  inline friend MatType norm_fro(const MatType &x) { return MatType::norm_fro(x);}
1949 
1994  inline friend MatType norm_2(const MatType &x) { return MatType::norm_2(x);}
1995 
2031  inline friend MatType norm_1(const MatType &x) { return MatType::norm_1(x);}
2032 
2068  inline friend MatType norm_inf(const MatType &x) { return MatType::norm_inf(x);}
2069 
2128  inline friend MatType diff(const MatType &x, casadi_int n=1, casadi_int axis=-1) {
2129  return MatType::diff(x, n, axis);
2130  }
2131 
2190  inline friend MatType cumsum(const MatType &x, casadi_int axis=-1) {
2191  return MatType::cumsum(x, axis);
2192  }
2193 
2242  inline friend MatType dot(const MatType &x, const MatType &y) {
2243  return MatType::dot(x, y);
2244  }
2245 
2287  inline friend MatType nullspace(const MatType& A) {
2288  return MatType::nullspace(A);
2289  }
2290 
2335  inline friend MatType polyval(const MatType& p, const MatType& x) {
2336  return MatType::polyval(p, x);
2337  }
2338 
2393  inline friend MatType diag(const MatType &A) {
2394  return MatType::diag(A);
2395  }
2396 
2445  inline friend MatType unite(const MatType& A, const MatType& B) {
2446  return MatType::unite(A, B);
2447  }
2448 
2501  inline friend MatType densify(const MatType& x) {
2502  return MatType::densify(x);
2503  }
2504 
2510  inline friend MatType densify(const MatType& x, const MatType& val) {
2511  return MatType::densify(x, val);
2512  }
2513 
2574  inline friend MatType project(const MatType& A, const Sparsity& sp,
2575  bool intersect=false) {
2576  return MatType::project(A, sp, intersect);
2577  }
2578 
2650  inline friend MatType if_else(const MatType &cond, const MatType &if_true,
2651  const MatType &if_false, bool short_circuit=false) {
2652  return MatType::if_else(cond, if_true, if_false, short_circuit);
2653  }
2654 
2711  inline friend MatType conditional(const MatType& ind, const std::vector<MatType> &x,
2712  const MatType &x_default, bool short_circuit=false) {
2713  return MatType::conditional(ind, x, x_default, short_circuit);
2714  }
2715 
2779  inline friend bool depends_on(const MatType& f, const MatType &arg) {
2780  return MatType::depends_on(f, arg);
2781  }
2782 
2846  inline friend bool contains(const std::vector<MatType>& v, const MatType &n) {
2847  return contains_all(v, std::vector<MatType>{n});
2848  }
2849 
2850  inline friend bool contains_all(const std::vector<MatType>& v, const std::vector<MatType> &n) {
2851  return MatType::contains_all(v, n);
2852  }
2853 
2854  inline friend bool contains_any(const std::vector<MatType>& v, const std::vector<MatType> &n) {
2855  return MatType::contains_any(v, n);
2856  }
2858 
2917  friend inline MatType substitute(const MatType& ex, const MatType& v,
2918  const MatType& vdef) {
2919  return MatType::substitute(ex, v, vdef);
2920  }
2921 
2964  friend inline std::vector<MatType>
2965  substitute(const std::vector<MatType>& ex, const std::vector<MatType>& v,
2966  const std::vector<MatType>& vdef) {
2967  return MatType::substitute(ex, v, vdef);
2968  }
2969 
3023  inline friend void
3024  substitute_inplace(const std::vector<MatType>& v,
3025  std::vector<MatType>& inout_vdef,
3026  std::vector<MatType>& inout_ex, bool reverse=false) {
3027  return MatType::substitute_inplace(v, inout_vdef, inout_ex, reverse);
3028  }
3029 
3072  inline friend MatType cse(const MatType& e) {
3073  return MatType::cse({e}).at(0);
3074  }
3075 
3076 
3113  inline friend std::vector<MatType> cse(const std::vector<MatType>& e) {
3114  return MatType::cse(e);
3115  }
3116 
3197  friend inline MatType solve(const MatType& A, const MatType& b) {
3198  // If A is scalar, just divide
3199  if (A.is_scalar()) return b/A;
3200  return MatType::solve(A, b);
3201  }
3202 
3245  friend inline MatType solve(const MatType& A, const MatType& b,
3246  const std::string& lsolver,
3247  const Dict& dict = Dict()) {
3248  // If A is scalar, just divide
3249  if (A.is_scalar()) return b/A;
3250  return MatType::solve(A, b, lsolver, dict);
3251  }
3252 
3253 #ifdef WITH_DEPRECATED_FEATURES
3293  friend inline MatType linearize(const MatType& f, const MatType& x, const MatType& x0,
3294  const Dict& opts=Dict()) {
3295  return MatType::linearize(f, x, x0, opts);
3296  }
3297 #endif // WITH_DEPRECATED_FEATURES
3298 
3364  friend inline MatType pinv(const MatType& A) {
3365  return MatType::pinv(A);
3366  }
3367 
3405  friend inline MatType pinv(const MatType& A, const std::string& lsolver,
3406  const Dict& dict = Dict()) {
3407  return MatType::pinv(A, lsolver, dict);
3408  }
3409 
3410 
3422  friend inline MatType expm_const(const MatType& A, const MatType& t) {
3423  return MatType::expm_const(A, t);
3424  }
3425 
3434  friend inline MatType expm(const MatType& A) {
3435  return MatType::expm(A);
3436  }
3437 
3508  inline friend MatType jacobian(const MatType &ex, const MatType &arg,
3509  const Dict& opts = Dict()) {
3510  return MatType::jacobian(ex, arg, opts);
3511  }
3570  inline friend MatType gradient(const MatType &ex, const MatType &arg, const Dict& opts=Dict()) {
3571  return MatType::gradient(ex, arg, opts);
3572  }
3606  inline friend MatType tangent(const MatType &ex, const MatType &arg, const Dict& opts=Dict()) {
3607  return MatType::tangent(ex, arg, opts);
3608  }
3609 
3677  friend inline MatType jtimes(const MatType &ex, const MatType &arg,
3678  const MatType &v, bool tr=false, const Dict& opts=Dict()) {
3679  return MatType::jtimes(ex, arg, v, tr, opts);
3680  }
3681 
3734  friend inline std::vector<std::vector<MatType> >
3735  forward(const std::vector<MatType> &ex, const std::vector<MatType> &arg,
3736  const std::vector<std::vector<MatType> > &v,
3737  const Dict& opts = Dict()) {
3738  return MatType::forward(ex, arg, v, opts);
3739  }
3740 
3791  friend inline std::vector<std::vector<MatType> >
3792  reverse(const std::vector<MatType> &ex, const std::vector<MatType> &arg,
3793  const std::vector<std::vector<MatType> > &v,
3794  const Dict& opts = Dict()) {
3795  return MatType::reverse(ex, arg, v, opts);
3796  }
3797 
3799 
3851  inline friend MatType hessian(const MatType &ex, const MatType &arg,
3852  const Dict& opts = Dict()) {
3853  return MatType::hessian(ex, arg, opts);
3854  }
3855  inline friend MatType hessian(const MatType &ex, const MatType &arg, MatType& output_g,
3856  const Dict& opts = Dict()) {
3857  return MatType::hessian(ex, arg, output_g, opts);
3858  }
3860 
3927  inline friend std::vector<bool> which_depends(const MatType &expr, const MatType &var,
3928  casadi_int order, bool tr) {
3929  return MatType::which_depends(expr, var, order, tr);
3930  }
3931 
3963  inline friend Sparsity jacobian_sparsity(const MatType &f, const MatType &x) {
3964  return MatType::jacobian_sparsity(f, x);
3965  }
3966 
4010  inline friend bool is_linear(const MatType &expr, const MatType &var) {
4011  return MatType::is_linear(expr, var);
4012  }
4013 
4055  inline friend bool is_quadratic(const MatType &expr, const MatType &var) {
4056  return MatType::is_quadratic(expr, var);
4057  }
4058 
4122  inline friend void quadratic_coeff(const MatType &expr, const MatType &var,
4123  MatType& A, MatType& b, MatType& c, bool check=true) {
4124  MatType::quadratic_coeff(expr, var, A, b, c, check);
4125  }
4126 
4179  inline friend void linear_coeff(const MatType &expr, const MatType &var,
4180  MatType& A, MatType& b, bool check=true) {
4181  MatType::linear_coeff(expr, var, A, b, check);
4182  }
4183 
4272  inline friend void extract_parametric(const MatType &expr, const MatType& par,
4273  MatType& SWIG_OUTPUT(expr_ret),
4274  std::vector<MatType>& SWIG_OUTPUT(symbols),
4275  std::vector<MatType>& SWIG_OUTPUT(parametric),
4276  const Dict& opts=Dict()) {
4277  MatType::extract_parametric(expr, par, expr_ret, symbols, parametric, opts);
4278  }
4279 
4280  inline friend void extract_parametric(const std::vector<MatType> &expr, const MatType& par,
4281  std::vector<MatType>& SWIG_OUTPUT(expr_ret),
4282  std::vector<MatType>& SWIG_OUTPUT(symbols),
4283  std::vector<MatType>& SWIG_OUTPUT(parametric),
4284  const Dict& opts=Dict()) {
4285  // Concatenate all vector elements
4286  MatType expr_cat = veccat(expr);
4287  MatType expr_ret_cat;
4288 
4289  // Concatenated extract_parametric
4290  MatType::extract_parametric(expr_cat, par, expr_ret_cat, symbols, parametric, opts);
4291 
4292  // Compute edges of vertsplit needed to undo concatenate
4293  std::vector<casadi_int> edges = {0};
4294  for (const MatType& e : expr) {
4295  edges.push_back(edges.back() + e.numel());
4296  }
4297  // Perform vertsplit
4298  std::vector<MatType> expr_ret_catv = MatType::vertsplit(expr_ret_cat, edges);
4299 
4300  // Reshape all elements back into original size
4301  expr_ret.resize(expr_ret_catv.size());
4302  for (casadi_int i=0; i<expr_ret_catv.size(); ++i) {
4303  expr_ret[i] = reshape(expr_ret_catv[i], expr[i].size1(), expr[i].size2());
4304  }
4305  }
4306 
4307  inline friend void extract_parametric(const std::vector<MatType> &expr,
4308  const std::vector<MatType>& par,
4309  std::vector<MatType>& SWIG_OUTPUT(expr_ret),
4310  std::vector<MatType>& SWIG_OUTPUT(symbols),
4311  std::vector<MatType>& SWIG_OUTPUT(parametric),
4312  const Dict& opts=Dict()) {
4313  extract_parametric(expr, veccat(par), expr_ret, symbols, parametric, opts);
4314  }
4315 
4316  inline friend void extract_parametric(const MatType &expr, const std::vector<MatType>& par,
4317  MatType& SWIG_OUTPUT(expr_ret),
4318  std::vector<MatType>& SWIG_OUTPUT(symbols),
4319  std::vector<MatType>& SWIG_OUTPUT(parametric),
4320  const Dict& opts=Dict()) {
4321  extract_parametric(expr, veccat(par), expr_ret, symbols, parametric, opts);
4322  }
4323 
4392  inline friend void separate_linear(const MatType &expr,
4393  const MatType &sym_lin, const MatType &sym_const,
4394  MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
4395  MatType::separate_linear(expr, sym_lin, sym_const, expr_const, expr_lin, expr_nonlin);
4396  }
4397 
4398  inline friend void separate_linear(const MatType &expr,
4399  const std::vector<MatType> &sym_lin, const std::vector<MatType> &sym_const,
4400  MatType& expr_const, MatType& expr_lin, MatType& expr_nonlin) {
4401  separate_linear(expr, veccat(sym_lin), veccat(sym_const),
4402  expr_const, expr_lin, expr_nonlin);
4403  }
4404 
4445  inline friend casadi_int n_nodes(const MatType& A) {
4446  return MatType::n_nodes(A);
4447  }
4448 
4482  friend inline MatType simplify(const MatType &x) {
4483  return MatType::simplify(x);
4484  }
4485 
4521  friend inline MatType transform(const MatType &x, const Dict& opts = Dict()) {
4522  return MatType::transform(x, opts);
4523  }
4524  friend inline MatType transform(const MatType &x,
4525  const std::vector<std::vector<GenericType> >& passes, const Dict& opts = Dict()) {
4526  return MatType::transform(x, passes, opts);
4527  }
4528  friend inline std::vector<MatType> transform(const std::vector<MatType> &x,
4529  const Dict& opts = Dict()) {
4530  return MatType::transform(x, opts);
4531  }
4532  friend inline std::vector<MatType> transform(const std::vector<MatType> &x,
4533  const std::vector<std::vector<GenericType> >& passes, const Dict& opts = Dict()) {
4534  return MatType::transform(x, passes, opts);
4535  }
4537 
4579  inline friend std::string
4580  print_operator(const MatType& xb, const std::vector<std::string>& args) {
4581  return MatType::print_operator(xb, args);
4582  }
4583 
4666  inline friend void extract(std::vector<MatType>& ex,
4667  std::vector<MatType>& v,
4668  std::vector<MatType>& vdef,
4669  const Dict& opts = Dict()) {
4670  MatType::extract(ex, v, vdef, opts);
4671  }
4672 
4721  inline friend void shared(std::vector<MatType>& ex,
4722  std::vector<MatType>& v,
4723  std::vector<MatType>& vdef,
4724  const std::string& v_prefix="v_",
4725  const std::string& v_suffix="") {
4726  return MatType::shared(ex, v, vdef, v_prefix, v_suffix);
4727  }
4728 
4771  inline friend MatType repsum(const MatType &A, casadi_int n, casadi_int m=1) {
4772  return MatType::repsum(A, n, m);
4773  }
4774 
4776 
4821  friend inline MatType mmin(const MatType& x) {
4822  return MatType::mmin(x);
4823  }
4825 
4827 
4861  friend inline MatType mmax(const MatType& x) {
4862  return MatType::mmax(x);
4863  }
4865 
4868  static MatType jtimes(const MatType &ex, const MatType &arg,
4869  const MatType &v, bool tr=false, const Dict& opts=Dict());
4870  static MatType gradient(const MatType &ex, const MatType &arg, const Dict& opts=Dict());
4871  static MatType tangent(const MatType &ex, const MatType &arg, const Dict& opts=Dict());
4872  static MatType linearize(const MatType& f, const MatType& x, const MatType& x0,
4873  const Dict& opts=Dict());
4874  static MatType mpower(const MatType &x, const MatType &y);
4875  static MatType soc(const MatType &x, const MatType &y);
4877 
4879 #endif // SWIG
4880 
4887 
4948  static MatType sym(const std::string& name, casadi_int nrow=1, casadi_int ncol=1) {
4949  return sym(name, Sparsity::dense(nrow, ncol));
4950  }
4951 
4955  static MatType sym(const std::string& name, const std::pair<casadi_int, casadi_int> &rc) {
4956  return sym(name, rc.first, rc.second);
4957  }
4958 
4997  static MatType sym(const std::string& name, const Sparsity& sp) {
4998  return MatType::_sym(name, sp);
4999  }
5000 
5033  static std::vector<MatType > sym(const std::string& name, const Sparsity& sp, casadi_int p);
5034 
5063  static std::vector<MatType > sym(const std::string& name, casadi_int nrow,
5064  casadi_int ncol, casadi_int p) {
5065  return sym(name, Sparsity::dense(nrow, ncol), p);
5066  }
5067 
5074  static std::vector<std::vector<MatType> >
5075  sym(const std::string& name, const Sparsity& sp, casadi_int p, casadi_int r);
5076 
5106  static std::vector<std::vector<MatType> >
5107  sym(const std::string& name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r) {
5108  return sym(name, Sparsity::dense(nrow, ncol), p, r);
5109  }
5111 
5113 
5151  static MatType zeros(casadi_int nrow=1, casadi_int ncol=1) {
5152  return zeros(Sparsity::dense(nrow, ncol));
5153  }
5154  static MatType zeros(const Sparsity& sp) { return MatType(sp, 0, false);}
5155  static MatType zeros(const std::pair<casadi_int, casadi_int>& rc) {
5156  return zeros(rc.first, rc.second);
5157  }
5159 
5161 
5206  static MatType ones(casadi_int nrow=1, casadi_int ncol=1) {
5207  return ones(Sparsity::dense(nrow, ncol));
5208  }
5209  static MatType ones(const Sparsity& sp) { return MatType(sp, 1, false);}
5210  static MatType ones(const std::pair<casadi_int, casadi_int>& rc) {
5211  return ones(rc.first, rc.second);
5212  }
5214  };
5215 
5216  // Throw informative error message
5217  #define CASADI_THROW_ERROR(FNAME, WHAT) \
5218  throw CasadiException("Error in " + MatType::type_name() \
5219  + "::" FNAME " at " + CASADI_WHERE + ":\n" + std::string(WHAT));
5220 
5221 #ifndef SWIG
5222  // Implementations
5223  template<typename MatType>
5224  const Sparsity& GenericMatrix<MatType>::sparsity() const {
5225  return self().sparsity();
5226  }
5227 
5228  template<typename MatType>
5229  casadi_int GenericMatrix<MatType>::nnz() const {
5230  return sparsity().nnz();
5231  }
5232 
5233  template<typename MatType>
5234  casadi_int GenericMatrix<MatType>::nnz_lower() const {
5235  return sparsity().nnz_lower();
5236  }
5237 
5238  template<typename MatType>
5239  casadi_int GenericMatrix<MatType>::nnz_upper() const {
5240  return sparsity().nnz_upper();
5241  }
5242 
5243  template<typename MatType>
5244  casadi_int GenericMatrix<MatType>::nnz_diag() const {
5245  return sparsity().nnz_diag();
5246  }
5247 
5248  template<typename MatType>
5249  casadi_int GenericMatrix<MatType>::numel() const {
5250  return sparsity().numel();
5251  }
5252 
5253  template<typename MatType>
5254  casadi_int GenericMatrix<MatType>::size1() const {
5255  return sparsity().size1();
5256  }
5257 
5258  template<typename MatType>
5259  casadi_int GenericMatrix<MatType>::size2() const {
5260  return sparsity().size2();
5261  }
5262 
5263  template<typename MatType>
5264  std::pair<casadi_int, casadi_int> GenericMatrix<MatType>::size() const {
5265  return sparsity().size();
5266  }
5267 
5268  template<typename MatType>
5269  casadi_int GenericMatrix<MatType>::size(casadi_int axis) const {
5270  return sparsity().size(axis);
5271  }
5272 
5273  template<typename MatType>
5274  std::string GenericMatrix<MatType>::dim(bool with_nz) const {
5275  return sparsity().dim(with_nz);
5276  }
5277 
5278  template<typename MatType>
5279  bool GenericMatrix<MatType>::is_scalar(bool scalar_and_dense) const {
5280  return sparsity().is_scalar(scalar_and_dense);
5281  }
5282 
5283 #endif // SWIG
5284 
5285  template<typename MatType>
5286  std::vector<MatType> GenericMatrix<MatType>::sym(const std::string& name,
5287  const Sparsity& sp, casadi_int p) {
5288  std::vector<MatType> ret(p);
5289  std::stringstream ss;
5290  for (casadi_int k=0; k<p; ++k) {
5291  ss.str("");
5292  ss << name << k;
5293  ret[k] = sym(ss.str(), sp);
5294  }
5295  return ret;
5296  }
5297 
5298  template<typename MatType>
5299  std::vector<std::vector<MatType> > GenericMatrix<MatType>::sym(const std::string& name,
5300  const Sparsity& sp, casadi_int p,
5301  casadi_int r) {
5302  std::vector<std::vector<MatType> > ret(r);
5303  for (casadi_int k=0; k<r; ++k) {
5304  std::stringstream ss;
5305  ss << name << "_" << k;
5306  ret[k] = sym(ss.str(), sp, p);
5307  }
5308  return ret;
5309  }
5310 
5311  template<typename MatType>
5312  MatType GenericMatrix<MatType>::linspace(const MatType& a, const MatType& b, casadi_int nsteps) {
5313  casadi_assert(nsteps>=1, "linspace: nsteps (" + str(nsteps) + ") must be at least 1");
5314  std::vector<MatType> ret(nsteps);
5315  ret[0] = a;
5316  MatType step = (b-a)/static_cast<MatType>(nsteps-1);
5317 
5318  for (casadi_int i=1; i<nsteps-1; ++i)
5319  ret[i] = a + i * step;
5320 
5321  ret[nsteps-1] = b;
5322  return vertcat(ret);
5323  }
5324 
5325  template<typename MatType>
5326  MatType GenericMatrix<MatType>::cross(const MatType& a, const MatType& b, casadi_int dim) {
5327  casadi_assert(a.size1()==b.size1() && a.size2()==b.size2(),
5328  "cross(a, b): Inconsistent dimensions. Dimension of a ("
5329  + a.dim() + " ) must equal that of b (" + b.dim() + ").");
5330 
5331  casadi_assert(a.size1()==3 || a.size2()==3,
5332  "cross(a, b): One of the dimensions of a should have length 3, but got "
5333  + a.dim() + ".");
5334  casadi_assert(dim==-1 || dim==1 || dim==2,
5335  "cross(a, b, dim): Dim must be 1, 2 or -1 (automatic).");
5336 
5337  std::vector<MatType> ret(3);
5338 
5339  bool t = a.size1()==3;
5340 
5341  if (dim==1) t = true;
5342  if (dim==2) t = false;
5343 
5344  MatType a1 = t ? a(0, Slice()) : a(Slice(), 0);
5345  MatType a2 = t ? a(1, Slice()) : a(Slice(), 1);
5346  MatType a3 = t ? a(2, Slice()) : a(Slice(), 2);
5347 
5348  MatType b1 = t ? b(0, Slice()) : b(Slice(), 0);
5349  MatType b2 = t ? b(1, Slice()) : b(Slice(), 1);
5350  MatType b3 = t ? b(2, Slice()) : b(Slice(), 2);
5351 
5352  ret[0] = a2*b3-a3*b2;
5353  ret[1] = a3*b1-a1*b3;
5354  ret[2] = a1*b2-a2*b1;
5355 
5356  return t ? vertcat(ret) : horzcat(ret);
5357  }
5358 
5359  double CASADI_EXPORT index_interp1d(const std::vector<double>& x, double xq,
5360  bool equidistant=false);
5361 
5362  template<typename MatType>
5363  MatType GenericMatrix<MatType>::interp1d(const std::vector<double>& x, const MatType& v,
5364  const std::vector<double>& xq, const std::string& mode, bool equidistant) {
5365 
5366  bool mode_floor = false;
5367  bool mode_ceil = false;
5368  if (mode=="floor") {
5369  mode_floor = true;
5370  } else if (mode=="ceil") {
5371  mode_ceil = true;
5372  } else if (mode=="linear") {
5373  //
5374  } else {
5375  casadi_error("interp1d(x, v, xq, mode): "
5376  "Mode must be 'floor', 'ceil' or 'linear'. Got '" + mode + "' instead.");
5377  }
5378 
5379  casadi_assert(is_increasing(x), "interp1d(x, v, xq): x must be increasing.");
5380 
5381  casadi_assert(x.size()==v.size1(),
5382  "interp1d(x, v, xq): dimensions mismatch. v expected to have " + str(x.size()) + " rows,"
5383  " but got " + str(v.size1()) + " instead.");
5384 
5385  // Need at least two elements
5386  casadi_assert(x.size()>=2, "interp1d(x, v, xq): x must be at least length 2.");
5387 
5388  // Vectors to compose a sparse matrix
5389  std::vector<double> val;
5390  std::vector<casadi_int> colind(1, 0);
5391  std::vector<casadi_int> row;
5392 
5393  // Number of nonzeros in to-be composed matrix
5394  casadi_int nnz = 0;
5395  for (casadi_int i=0;i<xq.size();++i) {
5396  // Obtain index corresponding to xq[i]
5397  double ind = index_interp1d(x, xq[i], equidistant);
5398 
5399  if (mode_floor) ind = floor(ind);
5400  if (mode_ceil) ind = ceil(ind);
5401 
5402  // Split into integer and fractional part
5403  double int_partd;
5404  double frac_part = modf(ind, &int_partd);
5405  casadi_int int_part = static_cast<casadi_int>(int_partd);
5406 
5407  if (frac_part==0) {
5408  // Create a single entry
5409  val.push_back(1);
5410  row.push_back(int_part);
5411  nnz+=1;
5412  colind.push_back(nnz);
5413  } else {
5414  // Create a double entry
5415  val.push_back(1-frac_part);
5416  val.push_back(frac_part);
5417  row.push_back(int_part);
5418  row.push_back(int_part+1);
5419  nnz+=2;
5420  colind.push_back(nnz);
5421  }
5422  }
5423 
5424  // Construct sparsity for composed matrix
5425  Sparsity sp(x.size(), xq.size() , colind, row);
5426 
5427  return MatType::mtimes(MatType(sp, val).T(), v);
5428 
5429  }
5430 
5431  template<typename MatType>
5432  MatType GenericMatrix<MatType>::skew(const MatType& a) {
5433  casadi_assert(a.is_vector() && (a.size1()==3 || a.size2()==3),
5434  "skew(a): Expecting 3-vector, got " + a.dim() + ".");
5435 
5436  MatType x = a(0);
5437  MatType y = a(1);
5438  MatType z = a(2);
5439  return blockcat(std::vector< std::vector<MatType> >({{0, -z, y}, {z, 0, -x}, {-y, x, 0}}));
5440  }
5441 
5442  template<typename MatType>
5443  MatType GenericMatrix<MatType>::inv_skew(const MatType& a) {
5444  casadi_assert(a.size1()==3 && a.size2()==3,
5445  "inv_skew(a): Expecting 3-by-3 matrix, got " + a.dim() + ".");
5446 
5447  return 0.5*vertcat(std::vector<MatType>({a(2, 1)-a(1, 2), a(0, 2)-a(2, 0), a(1, 0)-a(0, 1)}));
5448  }
5449 
5450 
5451  template<typename MatType>
5452  MatType GenericMatrix<MatType>::tril2symm(const MatType& x) {
5453  casadi_assert(x.is_square(),
5454  "Shape error in tril2symm. Expecting square shape but got " + x.dim());
5455  casadi_assert(x.nnz_upper()-x.nnz_diag()==0,
5456  "Sparsity error in tril2symm. Found above-diagonal entries in argument: " + x.dim());
5457  return x + x.T() - diag(diag(x));
5458  }
5459 
5460  template<typename MatType>
5461  MatType GenericMatrix<MatType>::repsum(const MatType& x, casadi_int n, casadi_int m) {
5462  casadi_assert(n>0 && x.size1() % n==0,
5463  "repsum: x.size1() (" + str(x.size1()) + ") must be a multiple of n (" + str(n) + ")");
5464  casadi_assert(m>0 && x.size2() % m==0,
5465  "repsum: x.size2() (" + str(x.size2()) + ") must be a multiple of m (" + str(m) + ")");
5466  std::vector< std::vector< MatType> > s =
5467  blocksplit(x, x.size1()/n, x.size2()/m);
5468  MatType sum = 0;
5469  for (casadi_int i=0;i<s.size();++i) {
5470  for (casadi_int j=0;j<s[i].size();++j) {
5471  sum = sum + s[i][j];
5472  }
5473  }
5474  return sum;
5475  }
5476 
5477  template<typename MatType>
5478  MatType GenericMatrix<MatType>::triu2symm(const MatType& x) {
5479  casadi_assert(x.is_square(),
5480  "Shape error in triu2symm. Expecting square shape but got " + x.dim());
5481  casadi_assert(x.nnz_lower()-x.nnz_diag()==0,
5482  "Sparsity error in triu2symm. Found below-diagonal entries in argument: " + x.dim());
5483  return x + x.T() - diag(diag(x));
5484  }
5485 
5486  template<typename MatType>
5487  MatType GenericMatrix<MatType>::bilin(const MatType& A, const MatType& x,
5488  const MatType& y) {
5489  // Check/correct x
5490  casadi_assert_dev(x.is_vector());
5491  if (!x.is_column()) return bilin(A, x.T(), y);
5492  if (!x.is_dense()) return bilin(A, densify(x), y);
5493 
5494  // Check/correct y
5495  casadi_assert_dev(y.is_vector());
5496  if (!y.is_column()) return bilin(A, x, y.T());
5497  if (!y.is_dense()) return bilin(A, x, densify(y));
5498 
5499  // Assert dimensions
5500  casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
5501  "Dimension mismatch. Got x.size1() = " + str(x.size1())
5502  + " and y.size1() = " + str(y.size1()) + " but A.size() = " + str(A.size()));
5503 
5504  // Call the class specific method
5505  return MatType::_bilin(A, x, y);
5506  }
5507 
5508  template<typename MatType>
5509  MatType GenericMatrix<MatType>::rank1(const MatType& A, const MatType& alpha,
5510  const MatType& x, const MatType& y) {
5511  // Check/correct x
5512  casadi_assert_dev(x.is_vector());
5513  if (!x.is_column()) return rank1(A, alpha, x.T(), y);
5514  if (!x.is_dense()) return rank1(A, alpha, densify(x), y);
5515 
5516  // Check/correct y
5517  casadi_assert_dev(y.is_vector());
5518  if (!y.is_column()) return rank1(A, alpha, x, y.T());
5519  if (!y.is_dense()) return rank1(A, alpha, x, densify(y));
5520 
5521  // Check alpha, quick return
5522  casadi_assert_dev(alpha.is_scalar());
5523  if (!alpha.is_dense()) return A;
5524 
5525  // Assert dimensions
5526  casadi_assert(x.size1()==A.size1() && y.size1()==A.size2(),
5527  "Dimension mismatch. Got x.size1() = " + str(x.size1())
5528  + " and y.size1() = " + str(y.size1())
5529  + " but A.size() = " + str(A.size()));
5530 
5531  // Call the class specific method
5532  return MatType::_rank1(A, alpha, x, y);
5533  }
5534 
5535  template<typename MatType>
5536  MatType GenericMatrix<MatType>::logsumexp(const MatType& x) {
5537  casadi_assert(x.is_dense(), "Argument must be dense");
5538  casadi_assert(x.is_column(), "Argument must be column vector");
5539  casadi_assert(!x.is_empty(), "Argument must be nonempty");
5540  // Call the class specific method
5541  return MatType::_logsumexp(x);
5542  }
5543 
5544  template<typename MatType>
5545  MatType GenericMatrix<MatType>::jtimes(const MatType &ex, const MatType &arg,
5546  const MatType &v, bool tr, const Dict& opts) {
5547  try {
5548  // Assert consistent input dimensions
5549  if (tr) {
5550  if (ex.size2()==0 && v.size2()>0) {
5551  casadi_error("Ambiguous dimensions.");
5552  }
5553  casadi_assert(v.size1() == ex.size1() &&
5554  (v.size2()==0 || ex.size2()==0 || v.size2() % ex.size2() == 0),
5555  "'v' has inconsistent dimensions: "
5556  " v " + v.dim(false) + ", ex " + ex.dim(false) + ".");
5557  } else {
5558  if (arg.size2()==0 && v.size2()>0) {
5559  casadi_error("Ambiguous dimensions.");
5560  }
5561  casadi_assert(v.size1() == arg.size1() &&
5562  (v.size2()==0 || arg.size2()==0 || v.size2() % arg.size2() == 0),
5563  "'v' has inconsistent dimensions: "
5564  " v " + v.dim(false) + ", arg " + arg.dim(false) + ".");
5565  }
5566 
5567  casadi_int n_seeds = 1;
5568  if (tr) {
5569  if (ex.size2()>0) n_seeds = v.size2() / ex.size2();
5570  } else {
5571  if (arg.size2()>0) n_seeds = v.size2() / arg.size2();
5572  }
5573 
5574  // Quick return if no seeds
5575  if (v.is_empty() || ex.is_empty()) {
5576  return MatType(tr ? arg.size1() : ex.size1(),
5577  tr ? arg.size2()*n_seeds : ex.size2()*n_seeds);
5578  }
5579 
5580  // Split up the seed into its components
5581  std::vector<MatType> w = horzsplit(v, tr ? ex.size2() : arg.size2());
5582 
5583  // Seeds as a vector of vectors
5584  std::vector<std::vector<MatType> > ww(w.size());
5585  for (casadi_int i=0; i<w.size(); ++i) ww[i] = {w[i]};
5586 
5587  // Calculate directional derivatives
5588  if (tr) {
5589  ww = reverse({ex}, {arg}, ww, opts);
5590  } else {
5591  ww = forward({ex}, {arg}, ww, opts);
5592  }
5593 
5594  // Get results
5595  for (casadi_int i=0; i<w.size(); ++i) w[i] = ww[i][0];
5596  return horzcat(w);
5597  } catch (std::exception& e) {
5598  CASADI_THROW_ERROR("jtimes", e.what());
5599  }
5600  }
5601 
5602  template<typename MatType>
5603  MatType GenericMatrix<MatType>::gradient(const MatType &ex, const MatType &arg,
5604  const Dict& opts) {
5605  try {
5606  casadi_assert(ex.is_scalar(),
5607  "'gradient' only defined for scalar outputs: Use 'jacobian' instead.");
5608  return project(jtimes(ex, arg, MatType::ones(ex.sparsity()), true, opts), arg.sparsity());
5609  } catch (std::exception& e) {
5610  CASADI_THROW_ERROR("gradient", e.what());
5611  }
5612  }
5613 
5614  template<typename MatType>
5615  MatType GenericMatrix<MatType>::tangent(const MatType &ex, const MatType &arg,
5616  const Dict& opts) {
5617  try {
5618  casadi_assert(arg.is_scalar(),
5619  "'tangent' only defined for scalar inputs: Use 'jacobian' instead.");
5620  return project(jtimes(ex, arg, MatType::ones(arg.sparsity()), false, opts), ex.sparsity());
5621  } catch (std::exception& e) {
5622  CASADI_THROW_ERROR("tangent", e.what());
5623  }
5624  }
5625 
5626  template<typename MatType>
5627  MatType GenericMatrix<MatType>::
5628  linearize(const MatType& f, const MatType& x, const MatType& x0, const Dict& opts) {
5629  MatType x_lin = MatType::sym("x_lin", x.sparsity());
5630  // mismatching dimensions
5631  if (x0.size() != x.size()) {
5632  // Scalar x0 is ok
5633  if (x0.sparsity().is_scalar()) {
5634  return linearize(f, x, MatType(x.sparsity(), x0));
5635  }
5636  casadi_error("Dimension mismatch in 'linearize'");
5637  }
5638  return substitute(f + jtimes(f, x, x_lin, false, opts),
5639  MatType::vertcat({x_lin, x}), MatType::vertcat({x, x0}));
5640  }
5641 
5642  template<typename MatType>
5643  MatType GenericMatrix<MatType>::mpower(const MatType& a,
5644  const MatType& b) {
5645  if (a.is_scalar() && b.is_scalar()) return pow(a, b);
5646  casadi_assert(a.is_square() && b.is_constant() && b.is_scalar(),
5647  "Not Implemented");
5648  double bv = static_cast<double>(b);
5649  casadi_int N = static_cast<casadi_int>(bv);
5650  casadi_assert(bv-static_cast<double>(N)==0, "mpower only defined for integer powers.");
5651  casadi_assert(bv==N, "Not Implemented");
5652  if (N<0) return inv(mpower(a, -N));
5653  if (N==0) return MatType::eye(a.size1());
5654  if (N==1) return a;
5655  if (N % 2 == 0) {
5656  MatType h = mpower(a, N/2); // NOLINT
5657  return MatType::mtimes(h, h);
5658  } else {
5659  return MatType::mtimes(mpower(a, N-1), a);
5660  }
5661  }
5662 
5663  template<typename MatType>
5664  MatType GenericMatrix<MatType>::soc(const MatType& x,
5665  const MatType& y) {
5666  casadi_assert(y.is_scalar(), "y needs to be scalar. Got " + y.dim() + ".");
5667  casadi_assert(x.is_vector(), "x needs to be a vector. Got " + x.dim() + ".");
5668 
5669  MatType x_col = x.is_column() ? x : x.T();
5670 
5671  x_col = x_col.nz(Slice()); // NOLINT
5672 
5673  casadi_int n = x_col.numel();
5674  return blockcat(y*MatType::eye(n), x_col, x_col.T(), y);
5675  }
5676 
5677  template<typename MatType>
5678  bool GenericMatrix<MatType>::is_linear(const MatType &expr, const MatType &var) {
5679  return !any(MatType::which_depends(expr, var, 2, true));
5680  }
5681 
5682  template<typename MatType>
5683  bool GenericMatrix<MatType>::is_quadratic(const MatType &expr, const MatType &var) {
5684  return is_linear(gradient(expr, var), var);
5685  }
5686 
5687  template<typename MatType>
5688  void GenericMatrix<MatType>::quadratic_coeff(const MatType &expr, const MatType &var,
5689  MatType& A, MatType& b, MatType& c, bool check) {
5690  casadi_assert(expr.is_scalar(), "'quadratic_coeff' only defined for scalar expressions.");
5691  A = hessian(expr, var);
5692  b = substitute(jacobian(expr, var), var, 0).T();
5693  if (check)
5694  casadi_assert(!depends_on(A, var), "'quadratic_coeff' called on non-quadratic expression.");
5695  c = substitute(expr, var, 0);
5696  }
5697 
5698  template<typename MatType>
5699  void GenericMatrix<MatType>::linear_coeff(const MatType &expr, const MatType &var,
5700  MatType& A, MatType& b, bool check) {
5701  casadi_assert(expr.is_vector(), "'linear_coeff' only defined for vector expressions.");
5702  if (check)
5703  casadi_assert(is_linear(expr, var), "'linear_coeff' called on non-linear expression.");
5704  A = substitute(jacobian(expr, var), var, 0);
5705  b = vec(substitute(expr, var, 0));
5706  }
5707 
5708  template<typename MatType>
5709  MatType GenericMatrix<MatType>::diff(const MatType& x, casadi_int n, casadi_int axis) {
5710  casadi_assert(axis==-1 || axis==0 || axis==1, "Axis argument invalid");
5711  casadi_assert(n>=1, "n argument invalid");
5712 
5713  MatType ret = x;
5714  for (casadi_int i=0;i<n;++i) {
5715  // Matlab's special case
5716  if (axis==-1 && ret.is_scalar()) return MatType();
5717 
5718  casadi_int local_axis = (axis==-1) ? ret.is_row() : axis;
5719  if (local_axis==0) {
5720  if (ret.size1()<=1) {
5721  ret = MatType::zeros(0, ret.size2());
5722  } else {
5723  ret = ret(Slice(1, ret.size1()), Slice())-ret(Slice(0, ret.size1()-1), Slice());
5724  }
5725  } else {
5726  if (ret.size2()<=1) {
5727  ret = MatType::zeros(ret.size1(), 0);
5728  } else {
5729  ret = ret(Slice(), Slice(1, ret.size2()))-ret(Slice(), Slice(0, ret.size2()-1));
5730  }
5731  }
5732  }
5733  return ret;
5734  }
5735 
5736 #undef CASADI_THROW_ERROR
5737 
5738 } // namespace casadi
5739 
5740 #endif // CASADI_GENERIC_MATRIX_HPP
Matrix base class.
casadi_int numel() const
Get the number of elements, size1()*size2()
Sparsity sparsity() const
Get the sparsity pattern.
bool is_dense() const
Check if the matrix is dense, i.e. nnz() equals numel()
bool is_column() const
Check if the matrix is a column vector (i.e. size2()==1)
static MatType zeros(const Sparsity &sp)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
bool is_empty(bool both=false) const
Check if the matrix is empty, i.e. if one of the dimensions is zero.
casadi_int row(casadi_int el) const
Get the sparsity pattern. See the Sparsity class for details.
std::vector< casadi_int > get_colind() const
Get the sparsity pattern. See the Sparsity class for details.
bool is_vector() const
Check if the matrix is a row or column vector.
casadi_int nnz() const
Get the number of structural nonzeros.
casadi_int size2() const
Get the second dimension (i.e. number of columns)
casadi_int rows() const
Get the number of rows, Octave-style syntax (same as size1())
bool is_tril() const
Check if the matrix is lower triangular.
static MatType zeros(const std::pair< casadi_int, casadi_int > &rc)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
static MatType sym(const std::string &name, const std::pair< casadi_int, casadi_int > &rc)
Construct a symbolic primitive with given dimensions, as a pair (nrow, ncol)
static MatType sym(const std::string &name, const Sparsity &sp)
Create symbolic primitive with a given sparsity pattern.
static std::vector< MatType > sym(const std::string &name, casadi_int nrow, casadi_int ncol, casadi_int p)
Create a list of length p of nrow-by-ncol symbolic primitives.
casadi_int size(casadi_int axis) const
Get the size along a particular dimension.
casadi_int nnz_upper() const
Get the number of structural nonzeros on or above the diagonal.
bool is_row() const
Check if the matrix is a row vector (i.e. size1()==1)
bool is_triu() const
Check if the matrix is upper triangular.
casadi_int size1() const
Get the first dimension (i.e. number of rows)
std::string dim(bool with_nz=false) const
Get string representation of dimensions.
casadi_int nnz_diag() const
Get the number of structural nonzeros on the diagonal.
static MatType ones(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries one.
static MatType ones(const Sparsity &sp)
Create a dense matrix or a matrix with specified sparsity with all entries one.
static MatType sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
static std::vector< std::vector< MatType > > sym(const std::string &name, casadi_int nrow, casadi_int ncol, casadi_int p, casadi_int r)
Create a list of length r of lists of length p of nrow-by-ncol symbolic primitives.
static MatType ones(const std::pair< casadi_int, casadi_int > &rc)
Create a dense matrix or a matrix with specified sparsity with all entries one.
casadi_int colind(casadi_int col) const
Get the sparsity pattern. See the Sparsity class for details.
bool is_square() const
Check if the matrix is square, i.e. size1() equals size2()
static std::vector< MatType > sym(const std::string &name, const Sparsity &sp, casadi_int p)
Create a list of length p of symbolic primitives with a given sparsity.
casadi_int columns() const
Get the number of columns, Octave-style syntax (same as size2())
static MatType zeros(casadi_int nrow=1, casadi_int ncol=1)
Create a dense matrix or a matrix with specified sparsity with all entries zero.
std::vector< casadi_int > get_row() const
Get the sparsity pattern. See the Sparsity class for details.
static std::vector< std::vector< MatType > > sym(const std::string &name, const Sparsity &sp, casadi_int p, casadi_int r)
Create a list of length r of lists of length p of symbolic primitives.
std::pair< casadi_int, casadi_int > size() const
Get the shape as a pair (number of rows, number of columns)
casadi_int nnz_lower() const
Get the number of structural nonzeros on or below the diagonal.
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix is scalar, i.e. 1-by-1.
General sparsity class.
Definition: sparsity.hpp:200
casadi_int colind(casadi_int cc) const
Index of the first nonzero of column cc.
bool is_vector() const
Check whether the pattern is a row or a column vector.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern.
std::vector< casadi_int > get_colind() const
Column offsets of the compressed column storage.
bool is_column() const
Check whether the pattern is a column vector, i.e. size2() == 1.
bool is_row() const
Check whether the pattern is a row vector, i.e. size1() == 1.
bool is_tril(bool strictly=false) const
Check whether all nonzeros are on or below the diagonal (row >= col)
casadi_int row(casadi_int el) const
Row index of nonzero el.
bool is_empty(bool both=false) const
Check whether the pattern has a zero dimension.
bool is_dense() const
Check whether every entry is a structural nonzero, i.e. nnz() == numel()
bool is_square() const
Check whether the number of rows equals the number of columns.
bool is_triu(bool strictly=false) const
Check whether all nonzeros are on or above the diagonal (row <= col)
std::vector< casadi_int > get_row() const
Row index of every nonzero, in nonzero (column-major) order.
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())
Apply transformation passes to an expression.
friend std::vector< MatType > transform(const std::vector< MatType > &x, const std::vector< std::vector< GenericType > > &passes, const Dict &opts=Dict())
Apply transformation passes to an expression.
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)
Separate an expression into subexpressions that are constant, linear and nonlinear.
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-cone matrix.
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 left divide, A\b (cf. backslash '\' in MATLAB)
friend MatType det(const MatType &A, const std::string &lsolver, const Dict &dict=Dict())
Matrix determinant through a linear solver factorization (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)
Count the number of nodes in an expression graph.
friend std::vector< MatType > symvar(const MatType &x)
Get all symbolic primitives present in an 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 using a linear solver plugin.
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())
Apply transformation passes to an expression.
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())
Apply transformation passes to an expression.
friend MatType mrdivide(const MatType &x, const MatType &n)
Matrix right divide, x/A (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 variables v with expressions vdef in multiple expressions ex.
friend MatType inv_minor(const MatType &A)
Matrix inverse by the adjugate (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, using a linear solver plugin.
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 with non-overlapping sparsity patterns.
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 using a linear solver plugin.
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 over a list of expressions.
friend MatType bilin(const MatType &A, const MatType &x, const MatType &y)
Calculate bilinear/quadratic form x^T A y.
const long double alpha[8][8]
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.