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 const std::string& blas =
"reference");
74 static std::vector<MatType > horzsplit(
const MatType& x, casadi_int incr);
75 static std::vector<MatType > vertsplit(
const MatType& x, casadi_int incr);
76 static std::vector<MatType > horzsplit_n(
const MatType& x, casadi_int n);
77 static std::vector<MatType > vertsplit_n(
const MatType& x, casadi_int n);
78 static MatType repmat(
const MatType &A,
const std::pair<casadi_int, casadi_int>& rc) {
79 return MatType::repmat(A, rc.first, rc.second);
98 inline friend MatType horzcat(
const std::vector<MatType> &v) {
99 return MatType::horzcat(v);
109 inline friend MatType vertcat(
const std::vector<MatType> &v) {
110 return MatType::vertcat(v);
121 inline friend std::vector<MatType >
122 horzsplit(
const MatType &x,
const std::vector<casadi_int>& offset) {
123 return MatType::horzsplit(x, offset);
135 inline friend std::vector<MatType > horzsplit(
const MatType& x, casadi_int incr=1) {
136 return MatType::horzsplit(x, incr);
150 inline friend std::vector<MatType > horzsplit_n(
const MatType& x, casadi_int n) {
151 return MatType::horzsplit_n(x, n);
162 inline friend std::vector<MatType >
163 vertsplit(
const MatType& x,
const std::vector<casadi_int>& offset) {
164 return MatType::vertsplit(x, offset);
170 inline friend std::vector<casadi_int > offset(
const std::vector<MatType> &v,
bool vert=
true) {
171 return MatType::offset(v, vert);
205 inline friend std::vector<MatType > vertsplit(
const MatType &x, casadi_int incr=1) {
206 return MatType::vertsplit(x, incr);
220 inline friend std::vector<MatType > vertsplit_n(
const MatType& x, casadi_int n) {
221 return MatType::vertsplit_n(x, n);
227 inline friend MatType blockcat(
const std::vector< std::vector<MatType > > &v) {
228 return MatType::blockcat(v);
234 inline friend MatType
235 blockcat(
const MatType &A,
const MatType &B,
const MatType &C,
const MatType &D) {
236 return vertcat(horzcat(A, B), horzcat(C, D));
247 inline friend std::vector< std::vector< MatType > >
248 blocksplit(
const MatType& x,
249 const std::vector<casadi_int>& vert_offset,
250 const std::vector<casadi_int>& horz_offset) {
251 return MatType::blocksplit(x, vert_offset, horz_offset);
262 inline friend std::vector< std::vector< MatType > >
263 blocksplit(
const MatType& x, casadi_int vert_incr=1, casadi_int horz_incr=1) {
264 return MatType::blocksplit(x, vert_incr, horz_incr);
270 inline friend MatType diagcat(
const std::vector<MatType> &A) {
271 return MatType::diagcat(A);
284 friend std::vector< MatType >
285 diagsplit(
const MatType& x,
286 const std::vector<casadi_int>& output_offset1,
287 const std::vector<casadi_int>& output_offset2) {
288 return MatType::diagsplit(x, output_offset1, output_offset2);
299 inline friend std::vector< MatType >
300 diagsplit(
const MatType& x,
const std::vector<casadi_int>& output_offset) {
301 return MatType::diagsplit(x, output_offset);
311 inline friend std::vector< MatType >
312 diagsplit(
const MatType& x, casadi_int incr=1) {
313 return MatType::diagsplit(x, incr);
324 inline friend std::vector< MatType >
325 diagsplit(
const MatType& x, casadi_int incr1, casadi_int incr2) {
326 return MatType::diagsplit(x, incr1, incr2);
332 inline friend MatType veccat(
const std::vector< MatType >& x) {
333 return MatType::veccat(x);
356 inline friend MatType mtimes(
const MatType &x,
const MatType &y,
357 const std::string& blas =
"reference") {
358 return MatType::mtimes(x, y, blas);
366 inline friend MatType mtimes(
const std::vector<MatType> &args,
367 const std::string& blas =
"reference") {
368 return MatType::mtimes(args, blas);
380 inline friend MatType
381 mac(
const MatType &x,
const MatType &y,
const MatType &z,
382 const std::string& blas =
"reference") {
383 return MatType::mac(x, y, z, blas);
389 inline friend MatType transpose(
const MatType& X) {
410 inline friend MatType vec(
const MatType& x) {
411 return MatType::vec(x);
417 inline friend MatType reshape(
const MatType& x, casadi_int nrow, casadi_int ncol) {
418 return MatType::reshape(x, nrow, ncol);
424 inline friend MatType reshape(
const MatType& x, std::pair<casadi_int, casadi_int> rc) {
425 return MatType::reshape(x, rc.first, rc.second);
431 inline friend MatType reshape(
const MatType& x,
const Sparsity& sp) {
432 return MatType::reshape(x, sp);
438 inline friend MatType sparsity_cast(
const MatType& x,
const Sparsity& sp) {
439 return MatType::sparsity_cast(x, sp);
445 inline friend casadi_int sprank(
const MatType& x) {
446 return MatType::sprank(x);
452 inline friend casadi_int norm_0_mul(
const MatType &x,
const MatType &y) {
453 return MatType::norm_0_mul(x, y);
459 inline friend MatType triu(
const MatType& x,
bool includeDiagonal=
true) {
460 return MatType::triu(x, includeDiagonal);
466 inline friend MatType tril(
const MatType& x,
bool includeDiagonal=
true) {
467 return MatType::tril(x, includeDiagonal);
475 inline friend MatType kron(
const MatType& a,
const MatType& b) {
476 return MatType::kron(a, b);
482 inline friend MatType repmat(
const MatType &A, casadi_int n, casadi_int m=1) {
483 return MatType::repmat(A, n, m);
489 inline friend MatType repmat(
const MatType &A,
const std::pair<casadi_int, casadi_int>& rc) {
490 return MatType::repmat(A, rc);
496 inline friend MatType horzcat(
const MatType &x,
const MatType &y) {
497 return horzcat(std::vector<MatType>{x, y});
503 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z) {
504 return horzcat(std::vector<MatType>{x, y, z});
510 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z,
512 return horzcat(std::vector<MatType>{x, y, z, w});
518 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z,
519 const MatType &w,
const MatType &v) {
520 return horzcat(std::vector<MatType>{x, y, z, w, v});
526 inline friend MatType horzcat(
const MatType &x,
const MatType &y,
const MatType &z,
527 const MatType &w,
const MatType &v,
const MatType &u) {
528 return horzcat(std::vector<MatType>{x, y, z, w, v, u});
534 inline friend MatType vertcat(
const MatType &x,
const MatType &y) {
535 return vertcat(std::vector<MatType>{x, y});
541 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z) {
542 return vertcat(std::vector<MatType>{x, y, z});
548 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z,
550 return vertcat(std::vector<MatType>{x, y, z, w});
556 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z,
557 const MatType &w,
const MatType &v) {
558 return vertcat(std::vector<MatType>{x, y, z, w, v});
564 inline friend MatType vertcat(
const MatType &x,
const MatType &y,
const MatType &z,
565 const MatType &w,
const MatType &v,
const MatType &u) {
566 return vertcat(std::vector<MatType>{x, y, z, w, v, u});
572 inline friend MatType diagcat(
const MatType &x,
const MatType &y) {
573 return diagcat(std::vector<MatType>{x, y});
579 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z) {
580 return diagcat(std::vector<MatType>{x, y, z});
586 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z,
588 return diagcat(std::vector<MatType>{x, y, z, w});
594 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z,
595 const MatType &w,
const MatType &v) {
596 return diagcat(std::vector<MatType>{x, y, z, w, v});
602 inline friend MatType diagcat(
const MatType &x,
const MatType &y,
const MatType &z,
603 const MatType &w,
const MatType &v,
const MatType &u) {
604 return diagcat(std::vector<MatType>{x, y, z, w, v, u});
610 inline friend MatType sum1(
const MatType &x) {
return MatType::sum1(x);}
615 inline friend MatType sum2(
const MatType &x) {
return MatType::sum2(x);}
620 inline friend MatType sum(
const MatType &x) {
623 return MatType::sum1(x);
625 return MatType::sum2(x);
628 if (x.size1()>x.size2()) {
629 return MatType::sum2(MatType::sum1(x));
631 return MatType::sum1(MatType::sum2(x));
640 template<
typename MatType>
641 MatType SparsityInterface<MatType>::vec(
const MatType& x) {
642 if (x.size2()==1)
return x;
643 return reshape(x, x.numel(), 1);
646 template<
typename MatType>
647 MatType SparsityInterface<MatType>::repmat(
const MatType& x, casadi_int n, casadi_int m) {
648 if (n==1 && m==1)
return x;
649 MatType allrows = vertcat(std::vector<MatType>(n, x));
650 if (n==0) allrows = MatType(0, x.size2());
651 MatType ret = horzcat(std::vector<MatType>(m, allrows));
652 if (m==0) ret = MatType(allrows.size1(), 0);
656 template<
typename MatType>
657 std::vector< std::vector< MatType > >
658 SparsityInterface<MatType>::blocksplit(
const MatType& x,
659 const std::vector<casadi_int>& vert_offset,
660 const std::vector<casadi_int>& horz_offset) {
661 std::vector<MatType> rows = MatType::vertsplit(x, vert_offset);
662 std::vector< std::vector< MatType > > ret;
663 for (
auto&& r : rows) ret.push_back(MatType::horzsplit(r, horz_offset));
667 template<
typename MatType>
668 std::vector< std::vector< MatType > >
669 SparsityInterface<MatType>::blocksplit(
const MatType& x,
670 casadi_int vert_incr, casadi_int horz_incr) {
671 casadi_assert_dev(horz_incr>=1);
672 casadi_assert_dev(vert_incr>=1);
673 casadi_int sz1 = x.size1();
674 std::vector<casadi_int> offset1 = range(0, sz1, vert_incr);
675 offset1.push_back(sz1);
676 casadi_int sz2 = x.size2();
677 std::vector<casadi_int> offset2 = range(0, sz2, horz_incr);
678 offset2.push_back(sz2);
679 return blocksplit(x, offset1, offset2);
682 template<
typename MatType>
683 std::vector<casadi_int>
684 SparsityInterface<MatType>::offset(
const std::vector< MatType > &v,
bool vert) {
685 std::vector<casadi_int> ret(v.size()+1);
687 for (casadi_int i=0; i<v.size(); ++i) {
688 ret[i+1] = ret[i] + (vert ? v[i].size1() : v[i].size2());
693 template<
typename MatType>
694 MatType SparsityInterface<MatType>::veccat(
const std::vector< MatType >& x) {
695 std::vector< MatType > x_vec = x;
696 for (
typename std::vector< MatType >::iterator it=x_vec.begin();
697 it!=x_vec.end(); ++it) {
701 return MatType(0, 1);
703 return vertcat(x_vec);
707 template<
typename MatType>
708 std::vector< MatType >
709 SparsityInterface<MatType>::diagsplit(
const MatType& x,
710 const std::vector<casadi_int>& output_offset) {
711 casadi_assert(x.is_square(),
"diagsplit(x,incr)::input must be square but got "
713 return MatType::diagsplit(x, output_offset, output_offset);
716 template<
typename MatType>
717 std::vector< MatType >
718 SparsityInterface<MatType>::diagsplit(
const MatType& x, casadi_int incr) {
719 casadi_assert_dev(incr>=1);
720 casadi_assert(x.is_square(),
"diagsplit(x,incr)::input must be square but got "
722 std::vector<casadi_int> offset2 = range(0, x.size2(), incr);
723 offset2.push_back(x.size2());
724 return MatType::diagsplit(x, offset2);
727 template<
typename MatType>
728 std::vector< MatType >
729 SparsityInterface<MatType>::diagsplit(
const MatType& x, casadi_int incr1, casadi_int incr2) {
730 casadi_assert_dev(incr1>=1);
731 casadi_assert_dev(incr2>=1);
732 std::vector<casadi_int> offset1 = range(0, x.size1(), incr1);
733 offset1.push_back(x.size1());
734 std::vector<casadi_int> offset2 = range(0, x.size2(), incr2);
735 offset2.push_back(x.size2());
736 return MatType::diagsplit(x, offset1, offset2);
739 template<
typename MatType>
740 MatType SparsityInterface<MatType>::mtimes(
const std::vector<MatType> &args,
741 const std::string& blas) {
742 casadi_assert(!args.empty(),
743 "mul(std::vector<MatType> &args): "
744 "supplied list must not be empty.");
745 MatType ret = args[0];
746 for (casadi_int i=1; i<args.size(); ++i) ret = MatType::mtimes(ret, args[i], blas);
750 template<
typename MatType>
751 std::vector<MatType > SparsityInterface<MatType>::horzsplit(
const MatType& x, casadi_int incr) {
752 casadi_assert_dev(incr>=1);
753 casadi_int sz2 = x.size2();
754 std::vector<casadi_int> offset2 = range(0, sz2, incr);
755 offset2.push_back(sz2);
756 return MatType::horzsplit(x, offset2);
759 template<
typename MatType>
760 std::vector<MatType > SparsityInterface<MatType>::vertsplit(
const MatType& x, casadi_int incr) {
761 casadi_assert_dev(incr>=1);
762 casadi_int sz1 = x.size1();
763 std::vector<casadi_int> offset1 = range(0, sz1, incr);
764 offset1.push_back(sz1);
765 return MatType::vertsplit(x, offset1);
767 template<
typename MatType>
768 std::vector<MatType > SparsityInterface<MatType>::horzsplit_n(
const MatType& x, casadi_int n) {
769 casadi_assert(n>=0,
"horzsplit_n(x,n): n (" + str(n) +
") must be non-negative");
770 if (x.size2()==0)
return std::vector<MatType>(n, x);
771 casadi_assert(x.size2() % n==0,
"horzsplit_n(x,n): x.size2() (" + str(x.size2()) +
772 ") must be a multiple of n (" + str(n) +
")");
773 return horzsplit(x, x.size2()/n);
775 template<
typename MatType>
776 std::vector<MatType > SparsityInterface<MatType>::vertsplit_n(
const MatType& x, casadi_int n) {
777 casadi_assert(n>=0,
"vertsplit_n(x,n): n (" + str(n) +
") must be non-negative");
778 if (x.size1()==0)
return std::vector<MatType>(n, x);
779 casadi_assert(x.size1() % n==0,
"vertsplit(x,n): x.size1() (" + str(x.size1()) +
780 ") must be a multiple of n (" + str(n) +
")");
781 return vertsplit(x, x.size1()/n);