26 #ifndef CASADI_SPARSITY_INTERFACE_HPP
27 #define CASADI_SPARSITY_INTERFACE_HPP
29 #include "casadi_misc.hpp"
50 template<
typename MatType>
54 inline const MatType&
self()
const {
return static_cast<const MatType&
>(*this); }
55 inline MatType&
self() {
return static_cast<MatType&
>(*this); }
59 static std::vector< std::vector< MatType > >
60 blocksplit(
const MatType& x,
const std::vector<casadi_int>& vert_offset,
61 const std::vector<casadi_int>& horz_offset);
62 static std::vector< std::vector< MatType > >
63 blocksplit(
const MatType& x, casadi_int vert_incr, casadi_int horz_incr);
64 static MatType veccat(
const std::vector< MatType >& x);
65 static MatType vec(
const MatType& x);
66 static MatType repmat(
const MatType& x, casadi_int n, casadi_int m=1);
67 static std::vector<casadi_int> offset(
const std::vector< MatType > &v,
bool vert=
true);
68 static std::vector< MatType > diagsplit(
const MatType& x,
69 const std::vector<casadi_int>& output_offset);
70 static std::vector< MatType > diagsplit(
const MatType& x, casadi_int incr);
71 static std::vector< MatType > diagsplit(
const MatType& x, casadi_int incr1, casadi_int incr2);
72 static MatType mtimes(
const std::vector<MatType> &args);
73 static std::vector<MatType > horzsplit(
const MatType& x, casadi_int incr);
74 static std::vector<MatType > vertsplit(
const MatType& x, casadi_int incr);
75 static std::vector<MatType > horzsplit_n(
const MatType& x, casadi_int n);
76 static std::vector<MatType > vertsplit_n(
const MatType& x, casadi_int n);
77 static MatType repmat(
const MatType &A,
const std::pair<casadi_int, casadi_int>& rc) {
78 return MatType::repmat(A, rc.first, rc.second);
97 inline friend MatType horzcat(
const std::vector<MatType> &v) {
98 return MatType::horzcat(v);
108 inline friend MatType vertcat(
const std::vector<MatType> &v) {
109 return MatType::vertcat(v);
120 inline friend std::vector<MatType >
121 horzsplit(
const MatType &x,
const std::vector<casadi_int>& offset) {
122 return MatType::horzsplit(x, offset);
134 inline friend std::vector<MatType > horzsplit(
const MatType& x, casadi_int incr=1) {
135 return MatType::horzsplit(x, incr);
149 inline friend std::vector<MatType > horzsplit_n(
const MatType& x, casadi_int n) {
150 return MatType::horzsplit_n(x, n);
161 inline friend std::vector<MatType >
162 vertsplit(
const MatType& x,
const std::vector<casadi_int>& offset) {
163 return MatType::vertsplit(x, offset);
169 inline friend std::vector<casadi_int > offset(
const std::vector<MatType> &v,
bool vert=
true) {
170 return MatType::offset(v, vert);
204 inline friend std::vector<MatType > vertsplit(
const MatType &x, casadi_int incr=1) {
205 return MatType::vertsplit(x, incr);
219 inline friend std::vector<MatType > vertsplit_n(
const MatType& x, casadi_int n) {
220 return MatType::vertsplit_n(x, n);
226 inline friend MatType blockcat(
const std::vector< std::vector<MatType > > &v) {
227 return MatType::blockcat(v);
233 inline friend MatType
234 blockcat(
const MatType &A,
const MatType &B,
const MatType &C,
const MatType &D) {
235 return vertcat(horzcat(A, B), horzcat(C, D));
246 inline friend std::vector< std::vector< MatType > >
247 blocksplit(
const MatType& x,
248 const std::vector<casadi_int>& vert_offset,
249 const std::vector<casadi_int>& horz_offset) {
250 return MatType::blocksplit(x, vert_offset, horz_offset);
261 inline friend std::vector< std::vector< MatType > >
262 blocksplit(
const MatType& x, casadi_int vert_incr=1, casadi_int horz_incr=1) {
263 return MatType::blocksplit(x, vert_incr, horz_incr);
269 inline friend MatType diagcat(
const std::vector<MatType> &A) {
270 return MatType::diagcat(A);
283 friend std::vector< MatType >
284 diagsplit(
const MatType& x,
285 const std::vector<casadi_int>& output_offset1,
286 const std::vector<casadi_int>& output_offset2) {
287 return MatType::diagsplit(x, output_offset1, output_offset2);
298 inline friend std::vector< MatType >
299 diagsplit(
const MatType& x,
const std::vector<casadi_int>& output_offset) {
300 return MatType::diagsplit(x, output_offset);
310 inline friend std::vector< MatType >
311 diagsplit(
const MatType& x, casadi_int incr=1) {
312 return MatType::diagsplit(x, incr);
323 inline friend std::vector< MatType >
324 diagsplit(
const MatType& x, casadi_int incr1, casadi_int incr2) {
325 return MatType::diagsplit(x, incr1, incr2);
331 inline friend MatType veccat(
const std::vector< MatType >& x) {
332 return MatType::veccat(x);
338 inline friend MatType mtimes(
const MatType &x,
const MatType &y) {
339 return MatType::mtimes(x, y);
345 inline friend MatType mtimes(
const std::vector<MatType> &args) {
346 return MatType::mtimes(args);
357 inline friend MatType
358 mac(
const MatType &x,
const MatType &y,
const MatType &z) {
359 return MatType::mac(x, y, z);
365 inline friend MatType transpose(
const MatType& X) {
386 inline friend MatType vec(
const MatType& x) {
387 return MatType::vec(x);
393 inline friend MatType reshape(
const MatType& x, casadi_int nrow, casadi_int ncol) {
394 return MatType::reshape(x, nrow, ncol);
400 inline friend MatType reshape(
const MatType& x, std::pair<casadi_int, casadi_int> rc) {
401 return MatType::reshape(x, rc.first, rc.second);
407 inline friend MatType reshape(
const MatType& x,
const Sparsity& sp) {
408 return MatType::reshape(x, sp);
414 inline friend MatType sparsity_cast(
const MatType& x,
const Sparsity& sp) {
415 return MatType::sparsity_cast(x, sp);
421 inline friend casadi_int sprank(
const MatType& x) {
422 return MatType::sprank(x);
428 inline friend casadi_int norm_0_mul(
const MatType &x,
const MatType &y) {
429 return MatType::norm_0_mul(x, y);
435 inline friend MatType triu(
const MatType& x,
bool includeDiagonal=
true) {
436 return MatType::triu(x, includeDiagonal);
442 inline friend MatType tril(
const MatType& x,
bool includeDiagonal=
true) {
443 return MatType::tril(x, includeDiagonal);
451 inline friend MatType kron(
const MatType& a,
const MatType& b) {
452 return MatType::kron(a, b);
458 inline friend MatType repmat(
const MatType &A, casadi_int n, casadi_int m=1) {
459 return MatType::repmat(A, n, m);
465 inline friend MatType repmat(
const MatType &A,
const std::pair<casadi_int, casadi_int>& rc) {
466 return MatType::repmat(A, rc);
472 inline friend MatType horzcat(
const MatType &x,
const MatType &y) {
473 return horzcat(std::vector<MatType>{x, y});
479 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z) {
480 return horzcat(std::vector<MatType>{x, y, z});
486 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z,
488 return horzcat(std::vector<MatType>{x, y, z, w});
494 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z,
495 const MatType &w,
const MatType &v) {
496 return horzcat(std::vector<MatType>{x, y, z, w, v});
502 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z,
503 const MatType &w,
const MatType &v,
const MatType &u) {
504 return horzcat(std::vector<MatType>{x, y, z, w, v, u});
510 inline friend MatType vertcat(
const MatType &x,
const MatType &y) {
511 return vertcat(std::vector<MatType>{x, y});
517 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z) {
518 return vertcat(std::vector<MatType>{x, y, z});
524 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z,
526 return vertcat(std::vector<MatType>{x, y, z, w});
532 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z,
533 const MatType &w,
const MatType &v) {
534 return vertcat(std::vector<MatType>{x, y, z, w, v});
540 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z,
541 const MatType &w,
const MatType &v,
const MatType &u) {
542 return vertcat(std::vector<MatType>{x, y, z, w, v, u});
548 inline friend MatType diagcat(
const MatType &x,
const MatType &y) {
549 return diagcat(std::vector<MatType>{x, y});
555 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z) {
556 return diagcat(std::vector<MatType>{x, y, z});
562 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z,
564 return diagcat(std::vector<MatType>{x, y, z, w});
570 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z,
571 const MatType &w,
const MatType &v) {
572 return diagcat(std::vector<MatType>{x, y, z, w, v});
578 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z,
579 const MatType &w,
const MatType &v,
const MatType &u) {
580 return diagcat(std::vector<MatType>{x, y, z, w, v, u});
586 inline friend MatType sum1(
const MatType &x) {
return MatType::sum1(x);}
591 inline friend MatType sum2(
const MatType &x) {
return MatType::sum2(x);}
596 inline friend MatType sum(
const MatType &x) {
599 return MatType::sum1(x);
601 return MatType::sum2(x);
604 if (x.size1()>x.size2()) {
605 return MatType::sum2(MatType::sum1(x));
607 return MatType::sum1(MatType::sum2(x));
616 template<
typename MatType>
617 MatType SparsityInterface<MatType>::vec(
const MatType& x) {
618 if (x.size2()==1)
return x;
619 return reshape(x, x.numel(), 1);
622 template<
typename MatType>
623 MatType SparsityInterface<MatType>::repmat(
const MatType& x, casadi_int n, casadi_int m) {
624 if (n==1 && m==1)
return x;
625 MatType allrows = vertcat(std::vector<MatType>(n, x));
626 if (n==0) allrows = MatType(0, x.size2());
627 MatType ret = horzcat(std::vector<MatType>(m, allrows));
628 if (m==0) ret = MatType(allrows.size1(), 0);
632 template<
typename MatType>
633 std::vector< std::vector< MatType > >
634 SparsityInterface<MatType>::blocksplit(
const MatType& x,
635 const std::vector<casadi_int>& vert_offset,
636 const std::vector<casadi_int>& horz_offset) {
637 std::vector<MatType> rows = MatType::vertsplit(x, vert_offset);
638 std::vector< std::vector< MatType > > ret;
639 for (
auto&& r : rows) ret.push_back(MatType::horzsplit(r, horz_offset));
643 template<
typename MatType>
644 std::vector< std::vector< MatType > >
645 SparsityInterface<MatType>::blocksplit(
const MatType& x,
646 casadi_int vert_incr, casadi_int horz_incr) {
647 casadi_assert_dev(horz_incr>=1);
648 casadi_assert_dev(vert_incr>=1);
649 casadi_int sz1 = x.size1();
650 std::vector<casadi_int> offset1 = range(0, sz1, vert_incr);
651 offset1.push_back(sz1);
652 casadi_int sz2 = x.size2();
653 std::vector<casadi_int> offset2 = range(0, sz2, horz_incr);
654 offset2.push_back(sz2);
655 return blocksplit(x, offset1, offset2);
658 template<
typename MatType>
659 std::vector<casadi_int>
660 SparsityInterface<MatType>::offset(
const std::vector< MatType > &v,
bool vert) {
661 std::vector<casadi_int> ret(v.size()+1);
663 for (casadi_int i=0; i<v.size(); ++i) {
664 ret[i+1] = ret[i] + (vert ? v[i].size1() : v[i].size2());
669 template<
typename MatType>
670 MatType SparsityInterface<MatType>::veccat(
const std::vector< MatType >& x) {
671 std::vector< MatType > x_vec = x;
672 for (
typename std::vector< MatType >::iterator it=x_vec.begin();
673 it!=x_vec.end(); ++it) {
677 return MatType(0, 1);
679 return vertcat(x_vec);
683 template<
typename MatType>
684 std::vector< MatType >
685 SparsityInterface<MatType>::diagsplit(
const MatType& x,
686 const std::vector<casadi_int>& output_offset) {
687 casadi_assert(x.is_square(),
"diagsplit(x,incr)::input must be square but got "
689 return MatType::diagsplit(x, output_offset, output_offset);
692 template<
typename MatType>
693 std::vector< MatType >
694 SparsityInterface<MatType>::diagsplit(
const MatType& x, casadi_int incr) {
695 casadi_assert_dev(incr>=1);
696 casadi_assert(x.is_square(),
"diagsplit(x,incr)::input must be square but got "
698 std::vector<casadi_int> offset2 = range(0, x.size2(), incr);
699 offset2.push_back(x.size2());
700 return MatType::diagsplit(x, offset2);
703 template<
typename MatType>
704 std::vector< MatType >
705 SparsityInterface<MatType>::diagsplit(
const MatType& x, casadi_int incr1, casadi_int incr2) {
706 casadi_assert_dev(incr1>=1);
707 casadi_assert_dev(incr2>=1);
708 std::vector<casadi_int> offset1 = range(0, x.size1(), incr1);
709 offset1.push_back(x.size1());
710 std::vector<casadi_int> offset2 = range(0, x.size2(), incr2);
711 offset2.push_back(x.size2());
712 return MatType::diagsplit(x, offset1, offset2);
715 template<
typename MatType>
716 MatType SparsityInterface<MatType>::mtimes(
const std::vector<MatType> &args) {
717 casadi_assert(!args.empty(),
718 "mul(std::vector<MatType> &args): "
719 "supplied list must not be empty.");
720 MatType ret = args[0];
721 for (casadi_int i=1; i<args.size(); ++i) ret = MatType::mtimes(ret, args[i]);
725 template<
typename MatType>
726 std::vector<MatType > SparsityInterface<MatType>::horzsplit(
const MatType& x, casadi_int incr) {
727 casadi_assert_dev(incr>=1);
728 casadi_int sz2 = x.size2();
729 std::vector<casadi_int> offset2 = range(0, sz2, incr);
730 offset2.push_back(sz2);
731 return MatType::horzsplit(x, offset2);
734 template<
typename MatType>
735 std::vector<MatType > SparsityInterface<MatType>::vertsplit(
const MatType& x, casadi_int incr) {
736 casadi_assert_dev(incr>=1);
737 casadi_int sz1 = x.size1();
738 std::vector<casadi_int> offset1 = range(0, sz1, incr);
739 offset1.push_back(sz1);
740 return MatType::vertsplit(x, offset1);
742 template<
typename MatType>
743 std::vector<MatType > SparsityInterface<MatType>::horzsplit_n(
const MatType& x, casadi_int n) {
744 casadi_assert(n>=0,
"horzsplit_n(x,n): n (" + str(n) +
") must be non-negative");
745 if (x.size2()==0)
return std::vector<MatType>(n, x);
746 casadi_assert(x.size2() % n==0,
"horzsplit_n(x,n): x.size2() (" + str(x.size2()) +
747 ") must be a multiple of n (" + str(n) +
")");
748 return horzsplit(x, x.size2()/n);
750 template<
typename MatType>
751 std::vector<MatType > SparsityInterface<MatType>::vertsplit_n(
const MatType& x, casadi_int n) {
752 casadi_assert(n>=0,
"vertsplit_n(x,n): n (" + str(n) +
") must be non-negative");
753 if (x.size1()==0)
return std::vector<MatType>(n, x);
754 casadi_assert(x.size1() % n==0,
"vertsplit(x,n): x.size1() (" + str(x.size1()) +
755 ") must be a multiple of n (" + str(n) +
")");
756 return vertsplit(x, x.size1()/n);