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);}
598 template<
typename MatType>
599 MatType SparsityInterface<MatType>::vec(
const MatType& x) {
600 if (x.size2()==1)
return x;
601 return reshape(x, x.numel(), 1);
604 template<
typename MatType>
605 MatType SparsityInterface<MatType>::repmat(
const MatType& x, casadi_int n, casadi_int m) {
606 if (n==1 && m==1)
return x;
607 MatType allrows = vertcat(std::vector<MatType>(n, x));
608 if (n==0) allrows = MatType(0, x.size2());
609 MatType ret = horzcat(std::vector<MatType>(m, allrows));
610 if (m==0) ret = MatType(allrows.size1(), 0);
614 template<
typename MatType>
615 std::vector< std::vector< MatType > >
616 SparsityInterface<MatType>::blocksplit(
const MatType& x,
617 const std::vector<casadi_int>& vert_offset,
618 const std::vector<casadi_int>& horz_offset) {
619 std::vector<MatType> rows = MatType::vertsplit(x, vert_offset);
620 std::vector< std::vector< MatType > > ret;
621 for (
auto&& r : rows) ret.push_back(MatType::horzsplit(r, horz_offset));
625 template<
typename MatType>
626 std::vector< std::vector< MatType > >
627 SparsityInterface<MatType>::blocksplit(
const MatType& x,
628 casadi_int vert_incr, casadi_int horz_incr) {
629 casadi_assert_dev(horz_incr>=1);
630 casadi_assert_dev(vert_incr>=1);
631 casadi_int sz1 = x.size1();
632 std::vector<casadi_int> offset1 = range(0, sz1, vert_incr);
633 offset1.push_back(sz1);
634 casadi_int sz2 = x.size2();
635 std::vector<casadi_int> offset2 = range(0, sz2, horz_incr);
636 offset2.push_back(sz2);
637 return blocksplit(x, offset1, offset2);
640 template<
typename MatType>
641 std::vector<casadi_int>
642 SparsityInterface<MatType>::offset(
const std::vector< MatType > &v,
bool vert) {
643 std::vector<casadi_int> ret(v.size()+1);
645 for (casadi_int i=0; i<v.size(); ++i) {
646 ret[i+1] = ret[i] + (vert ? v[i].size1() : v[i].size2());
651 template<
typename MatType>
652 MatType SparsityInterface<MatType>::veccat(
const std::vector< MatType >& x) {
653 std::vector< MatType > x_vec = x;
654 for (
typename std::vector< MatType >::iterator it=x_vec.begin();
655 it!=x_vec.end(); ++it) {
659 return MatType(0, 1);
661 return vertcat(x_vec);
665 template<
typename MatType>
666 std::vector< MatType >
667 SparsityInterface<MatType>::diagsplit(
const MatType& x,
668 const std::vector<casadi_int>& output_offset) {
669 casadi_assert(x.is_square(),
"diagsplit(x,incr)::input must be square but got "
671 return MatType::diagsplit(x, output_offset, output_offset);
674 template<
typename MatType>
675 std::vector< MatType >
676 SparsityInterface<MatType>::diagsplit(
const MatType& x, casadi_int incr) {
677 casadi_assert_dev(incr>=1);
678 casadi_assert(x.is_square(),
"diagsplit(x,incr)::input must be square but got "
680 std::vector<casadi_int> offset2 = range(0, x.size2(), incr);
681 offset2.push_back(x.size2());
682 return MatType::diagsplit(x, offset2);
685 template<
typename MatType>
686 std::vector< MatType >
687 SparsityInterface<MatType>::diagsplit(
const MatType& x, casadi_int incr1, casadi_int incr2) {
688 casadi_assert_dev(incr1>=1);
689 casadi_assert_dev(incr2>=1);
690 std::vector<casadi_int> offset1 = range(0, x.size1(), incr1);
691 offset1.push_back(x.size1());
692 std::vector<casadi_int> offset2 = range(0, x.size2(), incr2);
693 offset2.push_back(x.size2());
694 return MatType::diagsplit(x, offset1, offset2);
697 template<
typename MatType>
698 MatType SparsityInterface<MatType>::mtimes(
const std::vector<MatType> &args) {
699 casadi_assert(!args.empty(),
700 "mul(std::vector<MatType> &args): "
701 "supplied list must not be empty.");
702 MatType ret = args[0];
703 for (casadi_int i=1; i<args.size(); ++i) ret = MatType::mtimes(ret, args[i]);
707 template<
typename MatType>
708 std::vector<MatType > SparsityInterface<MatType>::horzsplit(
const MatType& x, casadi_int incr) {
709 casadi_assert_dev(incr>=1);
710 casadi_int sz2 = x.size2();
711 std::vector<casadi_int> offset2 = range(0, sz2, incr);
712 offset2.push_back(sz2);
713 return MatType::horzsplit(x, offset2);
716 template<
typename MatType>
717 std::vector<MatType > SparsityInterface<MatType>::vertsplit(
const MatType& x, casadi_int incr) {
718 casadi_assert_dev(incr>=1);
719 casadi_int sz1 = x.size1();
720 std::vector<casadi_int> offset1 = range(0, sz1, incr);
721 offset1.push_back(sz1);
722 return MatType::vertsplit(x, offset1);
724 template<
typename MatType>
725 std::vector<MatType > SparsityInterface<MatType>::horzsplit_n(
const MatType& x, casadi_int n) {
726 casadi_assert(n>=0,
"horzsplit_n(x,n): n (" + str(n) +
") must be non-negative");
727 if (x.size2()==0)
return std::vector<MatType>(n, x);
728 casadi_assert(x.size2() % n==0,
"horzsplit_n(x,n): x.size2() (" + str(x.size2()) +
729 ") must be a multiple of n (" + str(n) +
")");
730 return horzsplit(x, x.size2()/n);
732 template<
typename MatType>
733 std::vector<MatType > SparsityInterface<MatType>::vertsplit_n(
const MatType& x, casadi_int n) {
734 casadi_assert(n>=0,
"vertsplit_n(x,n): n (" + str(n) +
") must be non-negative");
735 if (x.size1()==0)
return std::vector<MatType>(n, x);
736 casadi_assert(x.size1() % n==0,
"vertsplit(x,n): x.size1() (" + str(x.size1()) +
737 ") must be a multiple of n (" + str(n) +
")");
738 return vertsplit(x, x.size1()/n);