1#ifndef ZONOOPT_POLYMORPHIC_FUNCTIONS_HPP_
2#define ZONOOPT_POLYMORPHIC_FUNCTIONS_HPP_
31using namespace detail;
72 const Eigen::SparseMatrix<zono_float>& R,
const Eigen::Vector<zono_float, -1>& s)
76 const Eigen::Vector<
zono_float, -1> * s_ptr =
nullptr;
79 s_def.resize(R.rows());
88 if (R.cols() != Z.
n || R.rows() != s_ptr->size())
90 throw std::invalid_argument(
"Linear_map: invalid input dimensions.");
95 return std::make_unique<EmptySet>(
static_cast<int>(R.rows()));
99 Eigen::SparseMatrix<zono_float> Gc = R*Z.
Gc;
100 Eigen::SparseMatrix<zono_float> Gb = R*Z.
Gb;
111 return std::make_unique<Point>(c);
117 for (
const int dim : dims)
119 if (dim < 0 || dim >= Z.
n)
121 throw std::invalid_argument(
"Project onto dims: invalid dimension.");
127 return std::make_unique<EmptySet>(
static_cast<int>(dims.size()));
131 Eigen::SparseMatrix<zono_float> R (
static_cast<Eigen::Index
>(dims.size()),
static_cast<Eigen::Index
>(Z.
n));
132 std::vector<Eigen::Triplet<zono_float>> tripvec;
133 for (
int i=0; i<static_cast<int>(dims.size()); i++)
135 tripvec.emplace_back(i, dims[i], one);
137 R.setFromTriplets(tripvec.begin(), tripvec.end());
148 throw std::invalid_argument(
"Minkowski sum: n dimensions must match.");
153 return std::make_unique<EmptySet>(Z1.
n);
156 return std::unique_ptr<HybZono>(Z2.
clone());
159 return std::unique_ptr<HybZono>(Z1.
clone());
168 std::vector<Eigen::Triplet<zono_float>> tripvec;
170 Eigen::SparseMatrix<zono_float> Gc = hcat<zono_float>(Z1.
Gc, Z2.
Gc);
171 Eigen::SparseMatrix<zono_float> Gb = hcat<zono_float>(Z1.
Gb, Z2.
Gb);
174 Eigen::SparseMatrix<zono_float> Ac (Z1.
nC + Z2.
nC, Z1.
nGc + Z2.
nGc);
175 get_triplets_offset<zono_float>(Z1.
Ac, tripvec, 0, 0);
176 get_triplets_offset<zono_float>(Z2.
Ac, tripvec, Z1.
nC, Z1.
nGc);
177 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
180 Eigen::SparseMatrix<zono_float> Ab (Z1.
nC + Z2.
nC, Z1.
nGb + Z2.
nGb);
181 get_triplets_offset<zono_float>(Z1.
Ab, tripvec, 0, 0);
182 get_triplets_offset<zono_float>(Z2.
Ab, tripvec, Z1.
nC, Z1.
nGb);
183 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
186 b.segment(0, Z1.
nC) = Z1.
b;
187 b.segment(Z1.
nC, Z2.
nC) = Z2.
b;
191 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b, Z1.
zero_one_form);
193 return std::make_unique<ConZono>(Gc, c, Ac, b, Z1.
zero_one_form);
201 const Eigen::SparseMatrix<zono_float> * R_ptr =
nullptr;
202 Eigen::SparseMatrix<zono_float> R_def;
203 if (R.rows() == 0 && R.cols() == 0)
205 R_def.resize(Z1.
n, Z1.
n);
215 if (R_ptr->rows() != Z2.
n || R_ptr->cols() != Z1.
n)
217 throw std::invalid_argument(
"Intersection: inconsistent input dimensions.");
222 return std::make_unique<EmptySet>(Z1.
n);
232 Eigen::SparseMatrix<zono_float> Gc = Z1.
Gc;
233 Gc.conservativeResize(Z1.
n, Z1.
nGc + Z2.
nGc);
235 Eigen::SparseMatrix<zono_float> Gb = Z1.
Gb;
236 Gb.conservativeResize(Z1.
n, Z1.
nGb + Z2.
nGb);
240 std::vector<Eigen::Triplet<zono_float>> tripvec;
241 Eigen::SparseMatrix<zono_float> Ac (Z1.
nC + Z2.
nC + R_ptr->rows(), Z1.
nGc + Z2.
nGc);
242 get_triplets_offset<zono_float>(Z1.
Ac, tripvec, 0, 0);
243 get_triplets_offset<zono_float>(Z2.
Ac, tripvec, Z1.
nC, Z1.
nGc);
244 Eigen::SparseMatrix<zono_float> RZ1Gc = (*R_ptr)*Z1.
Gc;
245 get_triplets_offset<zono_float>(RZ1Gc, tripvec, Z1.
nC + Z2.
nC, 0);
246 Eigen::SparseMatrix<zono_float> mZ2Gc = -Z2.
Gc;
247 get_triplets_offset<zono_float>(mZ2Gc, tripvec, Z1.
nC + Z2.
nC, Z1.
nGc);
248 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
251 Eigen::SparseMatrix<zono_float> Ab (Z1.
nC + Z2.
nC + R_ptr->rows(), Z1.
nGb + Z2.
nGb);
252 get_triplets_offset<zono_float>(Z1.
Ab, tripvec, 0, 0);
253 get_triplets_offset<zono_float>(Z2.
Ab, tripvec, Z1.
nC, Z1.
nGb);
254 Eigen::SparseMatrix<zono_float> RZ1Gb = (*R_ptr)*Z1.
Gb;
255 get_triplets_offset<zono_float>(RZ1Gb, tripvec, Z1.
nC + Z2.
nC, 0);
256 Eigen::SparseMatrix<zono_float> mZ2Gb = -Z2.
Gb;
257 get_triplets_offset<zono_float>(mZ2Gb, tripvec, Z1.
nC + Z2.
nC, Z1.
nGb);
258 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
262 b.segment(0, Z1.
nC) = Z1.
b;
263 b.segment(Z1.
nC, Z2.
nC) = Z2.
b;
264 b.segment(Z1.
nC + Z2.
nC, R_ptr->rows()) = Z2.
c - (*R_ptr)*Z1.
c;
268 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b, Z1.
zero_one_form);
270 return std::make_unique<ConZono>(Gc, c, Ac, b, Z1.
zero_one_form);
274 HybZono& Z2,
const std::vector<int>& dims)
277 if (
static_cast<size_t>(Z2.
n) != dims.size())
279 throw std::invalid_argument(
"Intersection over dims: Z2.n must equal number of dimensions.");
283 for (
const int dim : dims)
285 if (dim < 0 || dim >= Z1.
n)
287 throw std::invalid_argument(
"Intersection over dims: invalid dimension.");
292 Eigen::SparseMatrix<zono_float> R (
static_cast<Eigen::Index
>(dims.size()),
static_cast<Eigen::Index
>(Z1.
n));
293 std::vector<Eigen::Triplet<zono_float>> tripvec;
294 for (
int i=0; i<static_cast<int>(dims.size()); ++i)
296 tripvec.emplace_back(i, dims[i], one);
298 R.setFromTriplets(tripvec.begin(), tripvec.end());
305 const Eigen::Vector<zono_float, -1>& f,
const Eigen::SparseMatrix<zono_float>& R)
310 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> H_rm = H;
311 std::vector<Inequality> ineqs;
312 for (
int k=0; k<H_rm.rows(); ++k)
315 std::vector<Eigen::Triplet<zono_float>> trips_row = get_triplets_row<zono_float>(H_rm, k);
318 Inequality ineq(
static_cast<int>(H_rm.cols()));
319 for (
const auto& trip : trips_row)
321 ineq.
add_term(trip.col(), trip.value());
326 ineqs.push_back(ineq);
339 throw std::invalid_argument(
"Pontryagin difference: n dimensions must match.");
344 return std::unique_ptr<HybZono>(Z1.
clone());
347 if (Z1.
nG == 0 && !exact)
348 return std::make_unique<EmptySet>(Z1.
n);
354 throw std::invalid_argument(
"Pontryagin difference: cannot compute exact set when subtrahend is a ConZono or HybZono");
364 std::unique_ptr<HybZono> Z_out (Z1.
clone());
368 const Eigen::Matrix<
zono_float, -1, -1> G2 = Z2.
G.toDense();
370 for (
int i=0; i<Z2.
nG; ++i)
372 std::unique_ptr<HybZono> Z_plus (Z_out->clone()), Z_minus (Z_out->clone());
373 Z_plus->c += G2.col(i);
374 Z_minus->c -= G2.col(i);
389 std::vector<Zono> Z2_leaves;
390 for (
auto& CZ : Z2_CZ_leaves)
392 Z2_leaves.push_back(*CZ.to_zono_approx());
396 std::vector<std::unique_ptr<HybZono>> leaf_diffs;
397 for (
auto& Z1_leaf : Z1_leaves)
399 std::unique_ptr<HybZono> Z_out;
400 for (
auto& Z2_leaf : Z2_leaves)
409 leaf_diffs.push_back(std::move(Z_out));
411 std::vector<HybZono*> leaf_diff_ptrs;
412 for (
auto& leaf_diff : leaf_diffs)
414 leaf_diff_ptrs.emplace_back(leaf_diff.get());
422 auto Z2_CZ =
dynamic_cast<const ConZono*
>(&Z2);
426 std::vector<std::unique_ptr<HybZono>> leaf_diffs;
427 for (
auto& Z1_leaf : Z1_leaves)
429 leaf_diffs.emplace_back(
pontry_diff(Z1_leaf, Z2_zono,
false));
431 std::vector<HybZono*> leaf_diff_ptrs;
432 for (
auto& leaf_diff : leaf_diffs)
434 leaf_diff_ptrs.emplace_back(leaf_diff.get());
442 std::vector<Zono> Z2_leaves;
443 for (
auto& CZ : Z2_CZ_leaves)
445 Z2_leaves.push_back(*CZ.to_zono_approx());
449 std::unique_ptr<HybZono> Z_out;
450 for (
auto& Z2_leaf : Z2_leaves)
464 auto Z2_CZ =
dynamic_cast<const ConZono*
>(&Z2);
468 const Eigen::SparseMatrix<zono_float> GA1 = vcat<zono_float>(Z1.
G, Z1.
A);
469 Eigen::SparseMatrix<zono_float> GA2 = Z2_zono.
G;
470 GA2.conservativeResize(Z2_zono.
n + Z1.
nC, Z2_zono.
nG);
472 Eigen::SparseMatrix<zono_float> M;
473 if (Z1.
n + Z1.
nC == Z1.
nG)
476 Eigen::SparseLU<Eigen::SparseMatrix<zono_float>> lu(GA1);
477 if (lu.info() != Eigen::Success)
479 throw std::runtime_error(
"Pontryagin difference: failed to peform LU decomposition. Most likely [G; A] is not full row rank");
486 Eigen::SimplicialLDLT<Eigen::SparseMatrix<zono_float>> ldlt(GA1*GA1.transpose());
487 if (ldlt.info() != Eigen::Success)
489 throw std::runtime_error(
"Pontryagin difference: failed to perform LDLT decomposition. Most likely [G; A] is not full row rank");
491 const Eigen::SparseMatrix<zono_float> ldlt_sol = ldlt.solve(GA2);
492 M = GA1.transpose()*ldlt_sol;
495 std::vector<Eigen::Triplet<zono_float>> triplets;
496 triplets.reserve(Z1.
nG);
498 for (
int i=0; i < Z1.
nG; ++i)
502 const zono_float d = 1-(e.transpose()*M).cwiseAbs().sum();
505 return std::make_unique<EmptySet>(Z1.
n);
507 triplets.emplace_back(i, i, d);
509 Eigen::SparseMatrix<zono_float> D (Z1.
nG, Z1.
nG);
510 D.setFromSortedTriplets(triplets.begin(), triplets.end());
512 return std::make_unique<ConZono>(Z1.
G*D, Z1.
c - Z2_zono.
c, Z1.
A*D, Z1.
b,
false);
516inline std::unique_ptr<HybZono>
union_of_many(
const std::vector<HybZono*>& Zs_in,
const bool preserve_sharpness,
const bool expose_indicators)
519 std::vector<HybZono*> Zs;
521 if (!Z->is_empty_set()) {
529 throw std::invalid_argument(
"Union: empty input vector.");
533 const int n = Zs[0]->n;
534 for (
const auto & Z : Zs)
538 throw std::invalid_argument(
"Union: inconsistent dimensions.");
543 for (
const auto & Z : Zs)
545 if (!Z->zero_one_form)
552 std::vector<Eigen::Triplet<zono_float>> tripvec;
553 int rows = 0, cols = 0;
554 std::vector<int> idx_sum_to_1;
555 Eigen::SparseMatrix<zono_float> Gc, Gb, Ac, Ab;
558 if (preserve_sharpness)
566 for (
const auto & Z : Zs)
569 get_triplets_offset<zono_float>(Z->Ac, tripvec, rows, cols);
573 for (
int i=0; i<Z->nGc; i++)
575 tripvec.emplace_back(rows+i, cols+i, one);
577 for (
int i=0; i<Z->nG; i++)
579 tripvec.emplace_back(rows+i, cols+Z->nGc+i, one);
584 cols += Z->nGc + Z->nG;
586 Ac.resize(rows+1, cols);
587 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
593 for (
const auto & Z : Zs)
596 get_triplets_offset<zono_float>(Z->Ab, tripvec, rows, cols);
599 for (
int i=0; i<Z->nC; i++)
601 tripvec.emplace_back(rows+i, cols+Z->nGb, -Z->b(i));
606 for (
int i=0; i<Z->nGb; i++)
608 tripvec.emplace_back(rows+Z->nGc+i, cols+i, one);
612 for (
int i=0; i<Z->nG; i++)
614 tripvec.emplace_back(rows+i, cols+Z->nGb, -one);
622 idx_sum_to_1.push_back(cols-1);
625 for (
int & it : idx_sum_to_1)
627 tripvec.emplace_back(rows, it, one);
630 Ab.resize(rows, cols);
631 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
636 b(Ab.rows()-1) = 1.0;
640 if (expose_indicators)
641 n_out +=
static_cast<int>(Zs.size());
646 for (
const auto & Z : Zs)
648 get_triplets_offset<zono_float>(Z->Gc, tripvec, 0, cols);
649 cols += 2*Z->nGc + Z->nGb;
651 Gc.resize(n_out, cols);
652 Gc.setFromTriplets(tripvec.begin(), tripvec.end());
657 for (
const auto & Z : Zs)
659 get_triplets_offset<zono_float>(Z->Gb, tripvec, 0, cols);
661 for (
int i=0; i<Z->n; i++)
663 tripvec.emplace_back(i, cols, Z->c(i));
667 for (
int i=n; i<n_out; ++i)
669 tripvec.emplace_back(i, idx_sum_to_1[i-n], one);
671 Gb.resize(n_out, cols);
672 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
686 for (
const auto & Z : Zs)
689 for (
int i=0; i<Z->nGc; i++)
691 tripvec.emplace_back(rows, cols+i, one);
693 tripvec.emplace_back(rows, cols+Z->nGc,
static_cast<zono_float>(Z->nG));
699 get_triplets_offset<zono_float>(Z->Ac, tripvec, rows, cols);
705 Ac.resize(rows+1, cols);
706 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
712 for (
const auto & Z : Zs)
715 for (
int i=0; i<Z->nGb; i++)
717 tripvec.emplace_back(rows, cols+i, one);
719 tripvec.emplace_back(rows, cols+Z->nGb,
static_cast<zono_float>(-Z->nG));
725 get_triplets_offset<zono_float>(Z->Ab, tripvec, rows, cols);
728 for (
int i=0; i<Z->nC; i++)
730 tripvec.emplace_back(rows+i, cols+Z->nGb, -Z->b(i));
738 idx_sum_to_1.push_back(cols-1);
741 for (
int & it : idx_sum_to_1)
743 tripvec.emplace_back(rows, it, one);
746 Ab.resize(rows, cols);
747 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
752 b(Ab.rows()-1) = 1.0;
756 if (expose_indicators)
757 n_out +=
static_cast<int>(Zs.size());
762 for (
const auto & Z : Zs)
764 get_triplets_offset<zono_float>(Z->Gc, tripvec, 0, cols);
767 Gc.resize(n_out, cols);
768 Gc.setFromTriplets(tripvec.begin(), tripvec.end());
773 for (
const auto & Z : Zs)
775 get_triplets_offset<zono_float>(Z->Gb, tripvec, 0, cols);
777 for (
int i=0; i<Z->n; i++)
779 tripvec.emplace_back(i, cols, Z->c(i));
783 for (
int i=n; i<n_out; ++i)
785 tripvec.emplace_back(i, idx_sum_to_1[i-n], one);
787 Gb.resize(n_out, cols);
788 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
796 bool sharp = preserve_sharpness;
798 while (sharp && i < Zs.size())
800 sharp = Zs[i]->sharp;
805 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b,
true, sharp);
812 return std::make_unique<EmptySet>(Z1.
n + Z2.
n);
822 std::vector<Eigen::Triplet<zono_float>> tripvec;
825 Eigen::SparseMatrix<zono_float> Gc (Z1.
n + Z2.
n, Z1.
nGc + Z2.
nGc);
826 get_triplets_offset<zono_float>(Z1.
Gc, tripvec, 0, 0);
827 get_triplets_offset<zono_float>(Z2.
Gc, tripvec, Z1.
n, Z1.
nGc);
828 Gc.setFromTriplets(tripvec.begin(), tripvec.end());
831 Eigen::SparseMatrix<zono_float> Gb (Z1.
n + Z2.
n, Z1.
nGb + Z2.
nGb);
832 get_triplets_offset<zono_float>(Z1.
Gb, tripvec, 0, 0);
833 get_triplets_offset<zono_float>(Z2.
Gb, tripvec, Z1.
n, Z1.
nGb);
834 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
837 c.segment(0, Z1.
n) = Z1.
c;
838 c.segment(Z1.
n, Z2.
n) = Z2.
c;
841 Eigen::SparseMatrix<zono_float> Ac (Z1.
nC + Z2.
nC, Z1.
nGc + Z2.
nGc);
842 get_triplets_offset<zono_float>(Z1.
Ac, tripvec, 0, 0);
843 get_triplets_offset<zono_float>(Z2.
Ac, tripvec, Z1.
nC, Z1.
nGc);
844 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
847 Eigen::SparseMatrix<zono_float> Ab (Z1.
nC + Z2.
nC, Z1.
nGb + Z2.
nGb);
848 get_triplets_offset<zono_float>(Z1.
Ab, tripvec, 0, 0);
849 get_triplets_offset<zono_float>(Z2.
Ab, tripvec, Z1.
nC, Z1.
nGb);
850 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
853 b.segment(0, Z1.
nC) = Z1.
b;
854 b.segment(Z1.
nC, Z2.
nC) = Z2.
b;
858 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b, Z1.
zero_one_form);
860 return std::make_unique<ConZono>(Gc, c, Ac, b, Z1.
zero_one_form);
864 return std::make_unique<Point>(c);
867inline std::unique_ptr<HybZono>
constrain(
HybZono& Z,
const std::vector<Inequality> &ineqs,
const Eigen::SparseMatrix<zono_float>& R)
871 return std::make_unique<EmptySet>(Z.
n);
875 const Eigen::SparseMatrix<zono_float> * R_ptr =
nullptr;
876 Eigen::SparseMatrix<zono_float> R_def;
877 if (R.rows() == 0 && R.cols() == 0)
879 R_def.resize(Z.
n, Z.
n);
889 for (
const auto& ineq : ineqs)
891 if (R_ptr->rows() != ineq.get_n_dims())
892 throw std::invalid_argument(
"Inequality does not have the same number of dimensions as set");
900 std::vector<Eigen::Triplet<zono_float>> triplets_Ac, triplets_Ab;
901 Eigen::Vector<
zono_float, -1> b_new (ineqs.size());
902 Eigen::Index n_cons = 0, n_slack = 0;
903 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> RGc = (*R_ptr)*Z.
Gc;
904 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> RGb = (*R_ptr)*Z.
Gb;
907 for (
const auto& ineq : ineqs)
910 switch (ineq.get_ineq_type())
919 rhs = ineq.get_rhs();
924 const auto ineq_type = ineq.get_ineq_type();
926 for (
const auto& [idx, coeff] : ineq.get_terms())
928 const auto trips_Gc = get_triplets_row<zono_float>(RGc, idx);
929 for (
const auto& trip : trips_Gc)
932 triplets_Ac.emplace_back(
static_cast<int>(n_cons),
static_cast<int>(trip.col()), val);
937 const auto trips_Gb = get_triplets_row<zono_float>(RGb, idx);
938 for (
const auto& trip : trips_Gb)
941 triplets_Ab.emplace_back(
static_cast<int>(n_cons),
static_cast<int>(trip.col()), val);
952 b_new(n_cons) = rhs + db;
955 if (ineq_type!=
EQUAL)
957 triplets_Ac.emplace_back(
static_cast<int>(n_cons), Z.
nGc +
static_cast<int>(n_slack), gamma);
965 Eigen::SparseMatrix<zono_float> Ac_cons (
static_cast<Eigen::Index
>(ineqs.size()), Z.
nGc + n_slack);
966 Eigen::SparseMatrix<zono_float> Ab_cons (
static_cast<Eigen::Index
>(ineqs.size()), Z.
nGb);
967 Ac_cons.setFromTriplets(triplets_Ac.begin(), triplets_Ac.end());
968 Ab_cons.setFromTriplets(triplets_Ab.begin(), triplets_Ab.end());
971 Eigen::SparseMatrix<zono_float> Z_Ac = Z.
Ac;
972 Z_Ac.conservativeResize(Z.
nC, Z.
nGc + n_slack);
973 Eigen::SparseMatrix<zono_float> Ac = vcat(Z_Ac, Ac_cons);
974 Eigen::SparseMatrix<zono_float> Ab = vcat(Z.
Ab, Ab_cons);
975 Eigen::Vector<
zono_float, -1> b (Z.
nC +
static_cast<Eigen::Index
>(ineqs.size()));
976 b.segment(0, Z.
nC) = Z.
b;
977 b.segment(Z.
nC,
static_cast<Eigen::Index
>(ineqs.size())) = b_new;
979 Eigen::SparseMatrix<zono_float> Z_Gc = Z.
Gc;
980 Z_Gc.conservativeResize(Z.
n, Z.
nGc + n_slack);
984 return std::make_unique<HybZono>(Z_Gc, Z.
Gb, Z.
c, Ac, Ab, b,
true);
986 return std::make_unique<ConZono>(Z_Gc, Z.
c, Ac, b,
true);
990 OptSolution* solution,
const int n_leaves,
const int contractor_iter)
999 throw std::runtime_error(
"HybZono complement: set is empty.");
1001 std::vector<std::unique_ptr<HybZono>>
complements;
1006 std::unique_ptr<HybZono>
Z_out;
1011 Z_out.reset(comp->clone());
1029 const auto GT = this->
G.transpose();
1030 const auto AT = this->
A.transpose();
1038 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator
it(
GTAT,
row);
it; ++
it)
1048 std::stringstream
ss;
1049 ss <<
"ConZono complement: row " <<
row <<
" of [G^T A^T] has no non-zero elements.";
1050 throw std::runtime_error(
ss.str());
1064 u1.setConstant(1 +
delta_m/2);
1066 if (
Zf1->is_0_1_form())
Zf1->convert_form();
1069 l2.segment(0, 2*this->
nG).setConstant(-(m + 3*
delta_m/2 + 1));
1070 l2.segment(2*this->
nG, 2*this->
nG).setConstant(-2);
1072 u2.segment(0, 2*this->
nG).setConstant(delta_m/2);
1073 u2.segment(2*this->
nG, 2*this->
nG).setZero();
1075 if (
Zf2->is_0_1_form())
Zf2->convert_form();
1080 Eigen::SparseMatrix<zono_float>
Gc =
m*this->
G;
1081 Gc.conservativeResize(this->
n, 9*this->
nG + this->
n + this->
nC + 1);
1084 Eigen::SparseMatrix<zono_float>
Gb (this->
n, 2*this->
nG);
1092 std::vector<Eigen::Triplet<zono_float>>
triplets;
1098 for (
int i=0;
i<this->
nG; ++
i)
1100 triplets.emplace_back(
i,
i,
m);
1102 for (
int i=0;
i<this->
nG; ++
i)
1104 triplets.emplace_back(
i, this->nG, -
delta_m/two);
1106 for (
int i=0;
i<this->
nG; ++
i)
1108 triplets.emplace_back(this->nG+
i,
i, -
m);
1110 for (
int i=0;
i<this->
nG; ++
i)
1112 triplets.emplace_back(this->nG+
i, this->nG, -
delta_m/two);
1114 Eigen::SparseMatrix<zono_float>
AcPF (2*this->nG, 3*this->nG + 1 + this->
nC + this->
n);
1122 for (
int i=0;
i<this->
nG; ++
i)
1126 for (
int i=0;
i<this->
nG; ++
i)
1128 triplets.emplace_back(this->nG,
n_offset+
i, p5);
1131 for (
int i=0;
i<this->
nG; ++
i)
1135 for (
int i=0;
i<this->
nG; ++
i)
1137 triplets.emplace_back(this->nG,
n_offset+
i, p5);
1139 Eigen::SparseMatrix<zono_float>
AcDF (this->nG+1, 3*this->nG + 1 + this->nC + this->
n);
1147 for (
int i=0;
i<this->
nG; ++
i)
1149 triplets.emplace_back(
i,
i, -
m);
1151 for (
int i=0;
i<this->
nG; ++
i)
1153 triplets.emplace_back(
i, this->nG,
delta_m/two);
1155 for (
int i=0;
i<this->
nG; ++
i)
1157 triplets.emplace_back(this->nG+
i,
i,
m);
1159 for (
int i=0;
i<this->
nG; ++
i)
1161 triplets.emplace_back(this->nG+
i, this->nG,
delta_m/two);
1164 for (
int i=0;
i<this->
nG; ++
i)
1166 triplets.emplace_back(2*this->nG+
i,
n_offset+
i, one);
1169 for (
int i=0;
i<this->
nG; ++
i)
1171 triplets.emplace_back(3*this->nG+
i,
n_offset+
i, one);
1173 Eigen::SparseMatrix<zono_float>
AcCS (4*this->nG, 3*this->nG + 1 + this->nC + this->
n);
1181 for (
int i=0;
i<this->
nG; ++
i)
1183 triplets.emplace_back(
i,
i,
m);
1185 for (
int i=0;
i<this->
nG; ++
i)
1187 triplets.emplace_back(this->nG+
i, this->nG+
i,
m);
1189 for (
int i=0;
i<this->
nG; ++
i)
1191 triplets.emplace_back(2*this->nG+
i,
i, -one);
1193 for (
int i=0;
i<this->
nG; ++
i)
1195 triplets.emplace_back(3*this->nG+
i, this->nG+
i, -one);
1197 Eigen::SparseMatrix<zono_float>
AbCS (4*this->nG, 2*this->nG);
1212 n_offset = this->nG + 1 + this->
n + this->nC + 2*this->
nG;
1222 Eigen::SparseMatrix<zono_float>
Ac (7*this->nG + this->nC + 1, 9*this->nG + this->
n + this->nC + 1);
1231 Eigen::SparseMatrix<zono_float>
Ab (7*this->nG + this->nC + 1, 2*this->nG);
1238 Eigen::Vector<
zono_float, -1>
b (7*this->nG + this->nC + 1);
1239 b.segment(0, this->nC) = this->
b;
1240 b.segment(this->nC, 2*this->nG) =
Zf1->c;
1241 b.segment(this->nC + 2*this->nG, this->nG + 1) =
bDF;
1242 b.segment(this->nC + 2*this->nG + this->nG + 1, 4*this->nG) =
Zf2->c;
1245 return std::make_unique<HybZono>(
Gc,
Gb,
c,
Ac,
Ab,
b,
false,
false);
1253 return std::unique_ptr<HybZono>(Z1.
clone());
1257 auto Z2_comp = Z2.
complement(delta_m, remove_redundancy, settings, solution, n_leaves, contractor_iter);
1269 throw std::invalid_argument(
"Zono union: empty input vector.");
1273 int n_dims = Zs[0].n;
1274 const int n_zonos =
static_cast<int>(Zs.size());
1282 throw std::invalid_argument(
"Zono union: inconsistent dimensions.");
1286 if (!Z.zero_one_form)
1297 std::vector<Eigen::Matrix<
zono_float, 1, -1>> M_vec;
1298 std::vector<Eigen::Matrix<
zono_float, -1, 1>> S_vec;
1299 Eigen::Matrix<
zono_float, 1, -1> M_row (n_zonos);
1303 for (
int i=0; i<n_zonos; i++)
1306 Gd = Zs[i].G.toDense();
1307 for (
int j=0; j<n_gens; j++)
1310 auto generator_equal = [&](
const Eigen::Matrix<
zono_float, -1, 1> &s) ->
bool
1312 return (s - Gd.col(j)).norm() <
zono_eps;
1315 if (
auto it_S = std::find_if(S_vec.begin(), S_vec.end(), generator_equal); it_S == S_vec.end())
1317 S_vec.emplace_back(Gd.col(j));
1320 M_vec.push_back(M_row);
1324 const int idx =
static_cast<int>(std::distance(S_vec.begin(), it_S));
1330 const int nG =
static_cast<int>(S_vec.size());
1333 Eigen::Matrix<
zono_float, -1, -1> S (n_dims, nG);
1334 Eigen::Matrix<
zono_float, -1, -1> M (nG, n_zonos);
1335 for (
int i=0; i<nG; i++)
1337 S.col(i) = S_vec[i];
1338 M.row(i) = M_vec[i];
1344 std::vector<Eigen::Triplet<zono_float>> tripvec;
1348 if (expose_indicators)
1349 n_out +=
static_cast<int>(n_zonos);
1352 Eigen::SparseMatrix<zono_float> Gc = S.sparseView();
1353 Gc.conservativeResize(n_out, 2*nG);
1357 for (
int i=0; i<n_zonos; ++i)
1359 for (
int j=0; j<n_dims; ++j)
1361 tripvec.emplace_back(j, i, Zs[i].c(j));
1364 for (
int i=n_dims; i<n_out; ++i)
1366 tripvec.emplace_back(i, i-n_dims, one);
1368 Eigen::SparseMatrix<zono_float> Gb (n_out, n_zonos);
1369 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
1378 Eigen::SparseMatrix<zono_float> Ac (1+nG, 2*nG);
1379 Eigen::SparseMatrix<zono_float> I_ng (nG, nG);
1381 get_triplets_offset<zono_float>(I_ng, tripvec, 1, 0);
1382 Eigen::Vector<
zono_float, -1> sum_M = M.rowwise().sum();
1383 for (
int i=0; i<nG; i++)
1385 tripvec.emplace_back(1+i, nG+i, sum_M(i));
1387 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
1391 Eigen::SparseMatrix<zono_float> Ab (1+nG, n_zonos);
1393 for (
int i=0; i<n_zonos; i++)
1395 tripvec.emplace_back(0, i, one);
1397 Eigen::SparseMatrix<zono_float> mM_sp = -M.sparseView();
1398 get_triplets_offset<zono_float>(mM_sp, tripvec, 1, 0);
1399 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
1408 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b,
true,
true);
1411inline std::unique_ptr<HybZono>
vrep_2_hybzono(
const std::vector<Eigen::Matrix<zono_float, -1, -1>> &Vpolys,
const bool expose_indicators)
1416 throw std::invalid_argument(
"set_from_vrep: Vpolys must have at least one polytope.");
1420 const int n_polys =
static_cast<int>(Vpolys.size());
1421 const int n_dims =
static_cast<int>(Vpolys[0].cols());
1425 for (
const auto & Vpoly : Vpolys)
1427 if (Vpoly.cols() != n_dims)
1429 throw std::invalid_argument(
"set_from_vrep: all polytopes must have the same number of dimensions.");
1435 std::vector<Eigen::Matrix<
zono_float, 1, -1>> V_vec, M_vec;
1436 Eigen::Matrix<
zono_float, 1, -1> M_row (n_polys);
1439 for (
int i=0; i<n_polys; i++)
1441 n_verts =
static_cast<int>(Vpolys[i].rows());
1442 for (
int j=0; j<n_verts; j++)
1445 auto vertex_equal = [&](
const Eigen::Matrix<
zono_float, 1, -1> &v) ->
bool
1447 return (v - Vpolys[i].row(j)).norm() <
zono_eps;
1450 if (
auto it_V = std::find_if(V_vec.begin(), V_vec.end(), vertex_equal); it_V == V_vec.end())
1452 V_vec.emplace_back(Vpolys[i].row(j));
1455 M_vec.push_back(M_row);
1459 const int idx =
static_cast<int>(std::distance(V_vec.begin(), it_V));
1465 const int nV =
static_cast<int>(V_vec.size());
1468 Eigen::Matrix<
zono_float, -1, -1> V (n_dims, nV);
1469 Eigen::Matrix<
zono_float, -1, -1> M (nV, n_polys);
1470 for (
int i=0; i<nV; i++)
1472 V.col(i) = V_vec[i];
1473 M.row(i) = M_vec[i];
1479 std::vector<Eigen::Triplet<zono_float>> tripvec;
1483 if (expose_indicators)
1484 n_out +=
static_cast<int>(n_polys);
1487 Eigen::SparseMatrix<zono_float> Gc = V.sparseView();
1488 Gc.conservativeResize(n_out, 2*nV);
1492 for (
int i=n_dims; i<n_out; ++i)
1494 tripvec.emplace_back(i, i-n_dims, one);
1496 Eigen::SparseMatrix<zono_float> Gb (n_out, n_polys);
1497 Gb.setFromSortedTriplets(tripvec.begin(), tripvec.end());
1507 Eigen::SparseMatrix<zono_float> Ac (2+nV, 2*nV);
1508 Eigen::SparseMatrix<zono_float> I_nv (nV, nV);
1510 for (
int i=0; i<nV; i++)
1512 tripvec.emplace_back(0, i, one);
1514 get_triplets_offset<zono_float>(I_nv, tripvec, 2, 0);
1515 Eigen::Vector<
zono_float, -1> sum_M = M.rowwise().sum();
1516 for (
int i=0; i<nV; i++)
1518 tripvec.emplace_back(2+i, nV+i, sum_M(i));
1520 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
1525 Eigen::SparseMatrix<zono_float> Ab (2+nV, n_polys);
1527 for (
int i=0; i<n_polys; i++)
1529 tripvec.emplace_back(1, i, one);
1531 Eigen::SparseMatrix<zono_float> mM_sp = -M.sparseView();
1532 get_triplets_offset<zono_float>(mM_sp, tripvec, 2, 0);
1533 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
1544 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b,
true,
true);
1547inline std::unique_ptr<ConZono>
vrep_2_conzono(
const Eigen::Matrix<zono_float, -1, -1> &Vpoly)
1550 const int n_dims =
static_cast<int>(Vpoly.cols());
1551 const int n_verts =
static_cast<int>(Vpoly.rows());
1554 const Eigen::SparseMatrix<zono_float> G = Vpoly.transpose().sparseView();
1559 std::vector<Eigen::Triplet<zono_float>> tripvec;
1560 Eigen::SparseMatrix<zono_float> A (1, n_verts);
1561 for (
int i=0; i<n_verts; i++)
1563 tripvec.emplace_back(0, i, one);
1565 A.setFromTriplets(tripvec.begin(), tripvec.end());
1571 return std::make_unique<ConZono>(G, c, A, b,
true);
1578 std::vector<Eigen::Triplet<zono_float>> triplets;
1579 Eigen::SparseMatrix<zono_float> G (
static_cast<Eigen::Index
>(box.
size()),
static_cast<Eigen::Index
>(box.
size()));
1580 for (
int i=0; i<static_cast<int>(box.
size()); i++)
1582 triplets.emplace_back(i, i, box[i].width()/two);
1584 G.setFromSortedTriplets(triplets.begin(), triplets.end());
1590 return std::make_unique<Zono>(G, c,
false);
1597 if (n_sides % 2 != 0 || n_sides < 4)
1599 throw std::invalid_argument(
"make_regular_zono_2D: number of sides must be even and >= 4.");
1605 throw std::invalid_argument(
"make_regular_zono_2D: radius must be positive.");
1609 const int n_gens = n_sides/2;
1611 const zono_float R = outer_approx ? radius/std::cos(dphi/2) : radius;
1614 const int n_gens_2 = n_gens/2;
1616 const zono_float l_side = 2*R*std::sin(dphi/2);
1617 Eigen::Matrix<
zono_float, -1, -1> G(2, n_gens);
1618 for (
int i = 0; i < n_gens; i++)
1620 G(0, i) = l_side*std::cos(phi);
1621 G(1, i) = l_side*std::sin(phi);
1626 return std::make_unique<Zono>(p5*G.sparseView(), c,
false);
1639 return Z_CR->bounding_box(settings, solution);
1645 throw std::invalid_argument(
"Bounding box: empty set");
1657 const Eigen::SparseMatrix<zono_float> P (this->
nG, this->
nG);
1658 Eigen::Vector<
zono_float, -1> q = -this->
G.transpose()*
d;
1663 for (
int i=0;
i<this->
n;
i++)
1670 q = -this->
G.transpose()*
d;
1675 throw std::invalid_argument(
"Bounding box: Z is empty");
1684 q = -this->
G.transpose()*
d;
1687 sol = this->
mi_opt(P, q, 0, this->
A, this->
b, settings);
1689 throw std::invalid_argument(
"Bounding box: Z is empty");
1704 if (this->
n != d.size())
1706 throw std::invalid_argument(
"Support: inconsistent dimensions.");
1713 return Zc->support(d, settings, solution);
1717 Eigen::SparseMatrix<zono_float> P (this->
nG, this->
nG);
1718 Eigen::Vector<
zono_float, -1> q = -this->
G.transpose()*
d;
1725 throw std::invalid_argument(
"Support: infeasible");
1727 return d.dot(this->
G*sol.
z +
this->c);
1731 OptSolution* solution,
const int n_leaves,
const int contractor_iter)
const
1738 std::vector<ConZono>
leaves;
1745 if (remove_redundancy)
1749 leaf.remove_redundancy(contractor_iter);
1760 if (this->
nC == 0)
return;
1768 x_lb.setConstant(-1);
1769 x_ub.setConstant(1);
1771 x_lb.setConstant(-std::numeric_limits<zono_float>::infinity());
1772 x_ub.setConstant(std::numeric_limits<zono_float>::infinity());
1774 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> A_rm = this->
A;
1775 for (
int i=0;
i<this->
nC; ++
i)
1777 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator
it_j(A_rm,
i);
it_j; ++
it_j)
1781 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator
it_k(A_rm,
i);
it_k; ++
it_k)
1783 if (
it_j.col() ==
it_k.col())
continue;
1786 R[
it_j.col()].intersect_assign(R[
it_j.col()],
y.as_view());
1792 for (
int j=0;
j<this->
nG; ++
j)
1795 throw std::runtime_error(
"ConZono constraint reduction: set is empty");
1799 Eigen::SparseMatrix<zono_float>
Q (this->nG + this->nC, this->nG + this->nC);
1801 Eigen::SparseMatrix<zono_float>
I_nG (this->nG, this->nG);
1803 const Eigen::SparseMatrix<zono_float>
Phi = this->
G.transpose()*this->
G +
I_nG;
1805 std::vector<Eigen::Triplet<zono_float>>
triplets;
1812 Eigen::SimplicialLDLT<Eigen::SparseMatrix<zono_float>>
Q_ldlt (
Q);
1813 if (
Q_ldlt.info() != Eigen::Success)
1814 throw std::runtime_error(
"ConZono constraint reduction: Q matrix factorization failed, most likely A is not full row rank.");
1817 std::vector<std::pair<int, zono_float>>
haus_vec;
1822 Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> P(size);
1830 P.indices()[
i] =
i-1;
1839 for (
int j=0;
j<this->
nG; ++
j)
1842 const zono_float
r_j = std::max<zono_float>(zero, std::max<zono_float>(std::abs(R[
j].to_interval().lb), std::abs(R[
j].to_interval().ub)) - one);
1855 for (
int i=0;
i<this->nG + this->
nC; ++
i)
1857 triplets.emplace_back(
i,
i, one);
1860 triplets.emplace_back(this->nG + this->nC,
j, one);
1863 for (
int i=0;
i<this->nG + this->
nC; ++
i)
1865 triplets.emplace_back(
i, this->nG + this->nC,
Qinv_e_j(
i));
1867 Eigen::SparseMatrix<zono_float>
M (this->nG + this->nC + 1, this->nG + this->nC + 1);
1871 Eigen::Vector<
zono_float, -1> rhs (this->nG + this->nC + 1);
1873 rhs(this->nG + this->nC) =
r_j;
1880 const Eigen::SparseMatrix<zono_float>
M_perm =
P_L*
M*
P_R.inverse();
1886 const Eigen::Vector<
zono_float, -1>
d =
y.segment(0, this->nG);
1892 std::sort(
haus_vec.begin(),
haus_vec.end(), [](
const auto &
a,
const auto &
b) { return a.second < b.second; });
1894 Eigen::SparseMatrix<zono_float>
Ea (this->nG, this->nC);
1900 for (Eigen::SparseMatrix<zono_float>::InnerIterator
it(this->
A,
j);
it; ++
it)
1904 triplets.emplace_back(
j,
static_cast<int>(
it.row()), one/
it.value());
1905 Ea.insert(
j,
it.row()) = 1/
it.value();
1917 throw std::runtime_error(
"ConZono: constraint reduction cannot find valid constraint to remove");
1920 const Eigen::SparseMatrix<zono_float>
Lambda_G =
G*
Ea;
1921 const Eigen::SparseMatrix<zono_float>
Lambda_A =
A*
Ea;
1922 Eigen::SparseMatrix<zono_float>
Gp = this->
G - Lambda_G*this->
A;
1924 Eigen::SparseMatrix<zono_float>
Ap = this->A -
Lambda_A*this->
A;
1935 triplets.emplace_back(
j,
j-1, one);
1937 Eigen::SparseMatrix<zono_float>
dG (this->nG, this->nG - 1);
1948 triplets.emplace_back(
i-1,
i, one);
1950 Eigen::SparseMatrix<zono_float>
dA (this->nC - 1, this->nC);
1962 return std::make_unique<Point>(this->
c);
1970 const Eigen::BDCSVD<Eigen::Matrix<
zono_float, -1, -1>, Eigen::ComputeFullV | Eigen::ComputeFullU>
svd (this->
A.toDense());
1973 const int n = this->
nG;
1974 const int r =
static_cast<int>(svd.rank());
1980 const Eigen::Vector<
zono_float, -1> b_tilde =
svd.matrixU().transpose()*this->
b;
Constrained zonotope class for ZonoOpt library.
Empty Set class for ZonoOpt library.
Hybrid zonotope class for ZonoOpt library.
Point class for ZonoOpt library.
Utilities for sparse matrix operations in ZonoOpt library.
Zonotope class for ZonoOpt library.
Box (i.e., interval vector) class.
Definition Intervals.hpp:718
Eigen::Vector< zono_float, -1 > center() const
get center of box
Definition Intervals.hpp:891
size_t size() const
get size of Box object
Definition Intervals.hpp:830
Constrained zonotope class.
Definition ConZono.hpp:33
void set(const Eigen::SparseMatrix< zono_float > &G, const Eigen::Vector< zono_float, -1 > &c, const Eigen::SparseMatrix< zono_float > &A, const Eigen::Vector< zono_float, -1 > &b, bool zero_one_form=false)
Reset constrained zonotope object with the given parameters.
Definition ConZono.hpp:150
virtual void constraint_reduction()
Execute constraint reduction algorithm from Scott et. al. 2016.
Definition PolymorphicFunctions.hpp:1757
std::unique_ptr< HybZono > do_complement(zono_float delta_m, bool, const OptSettings &, OptSolution *, int, int) override
Definition PolymorphicFunctions.hpp:1021
void convert_form() override
Converts the set representation between -1-1 and 0-1 forms.
Definition ConZono.hpp:179
virtual std::unique_ptr< Zono > to_zono_approx() const
Compute outer approximation of constrained zonotope as zonotope using SVD.
Definition PolymorphicFunctions.hpp:1957
Empty Set class.
Definition EmptySet.hpp:26
Hybrid zonotope class.
Definition HybZono.hpp:44
virtual bool is_0_1_form() const
Returns true if factors are in range [0,1], false if they are in range [-1,1].
Definition HybZono.hpp:199
int nC
number of constraints
Definition HybZono.hpp:482
bool is_empty(const OptSettings &settings=OptSettings(), OptSolution *solution=nullptr) const
Returns true if the set is provably empty, false otherwise.
Definition HybZono.hpp:351
int n
set dimension
Definition HybZono.hpp:470
OptSolution mi_opt(const Eigen::SparseMatrix< zono_float > &P, const Eigen::Vector< zono_float, -1 > &q, zono_float c, const Eigen::SparseMatrix< zono_float > &A, const Eigen::Vector< zono_float, -1 > &b, const OptSettings &settings=OptSettings(), OptSolution *solution=nullptr) const
Definition HybZono.hpp:987
bool is_hybzono() const
Polymorphic type checking: true if set is a hybrid zonotope.
Definition PolymorphicFunctions.hpp:56
bool zero_one_form
flag to indicate whether the set is in 0-1 or -1-1 form
Definition HybZono.hpp:485
Eigen::SparseMatrix< zono_float > Gc
continuous generator matrix
Definition HybZono.hpp:449
virtual void convert_form()
Converts the set representation between -1-1 and 0-1 forms.
Definition HybZono.hpp:741
Eigen::SparseMatrix< zono_float > Gb
binary generator matrix
Definition HybZono.hpp:452
int nG
total number of factors. nG = nGc + nGb
Definition HybZono.hpp:473
bool is_conzono() const
Polymorphic type checking: true if set is a constrained zonotope.
Definition PolymorphicFunctions.hpp:47
virtual Box do_bounding_box(const OptSettings &settings, OptSolution *solution)
Definition PolymorphicFunctions.hpp:1633
virtual zono_float do_support(const Eigen::Vector< zono_float, -1 > &d, const OptSettings &settings, OptSolution *solution)
Definition PolymorphicFunctions.hpp:1700
bool is_point() const
Polymorphic type checking: true if set is a point.
Definition PolymorphicFunctions.hpp:34
virtual HybZono * clone() const
Clone method for polymorphic behavior.
Definition HybZono.hpp:96
void set(const Eigen::SparseMatrix< zono_float > &Gc, const Eigen::SparseMatrix< zono_float > &Gb, const Eigen::Vector< zono_float, -1 > &c, const Eigen::SparseMatrix< zono_float > &Ac, const Eigen::SparseMatrix< zono_float > &Ab, const Eigen::Vector< zono_float, -1 > &b, bool zero_one_form=false, bool sharp=false)
Reset hybrid zonotope object with the given parameters.
Definition HybZono.hpp:713
virtual std::unique_ptr< ConZono > convex_relaxation() const
Returns convex relaxation of the hybrid zonotope.
Definition PolymorphicFunctions.hpp:1630
bool sharp
flag to indicate whether the set is known to be sharp (i.e., convex relaxation = convex hull)
Definition HybZono.hpp:488
Eigen::Vector< zono_float, -1 > c
center vector
Definition HybZono.hpp:464
int nGb
number of binary factors
Definition HybZono.hpp:479
bool is_zono() const
Polymorphic type checking: true if set is a zonotope.
Definition PolymorphicFunctions.hpp:40
Eigen::SparseMatrix< zono_float > A
constraint matrix A = [Ac, Ab]
Definition HybZono.hpp:455
Eigen::Vector< zono_float, -1 > b
constraint vector
Definition HybZono.hpp:467
virtual std::unique_ptr< HybZono > do_complement(zono_float, bool remove_redundancy, const OptSettings &settings, OptSolution *solution, int n_leaves, int contractor_iter)
Definition PolymorphicFunctions.hpp:989
friend std::unique_ptr< HybZono > intersection(const HybZono &Z1, HybZono &Z2, const Eigen::SparseMatrix< zono_float > &R)
Computes the generalized intersection of sets Z1 and Z2 over the matrix R.
Definition PolymorphicFunctions.hpp:198
bool is_empty_set() const
Polymorphic type checking: true if set is empty set object.
Definition PolymorphicFunctions.hpp:64
std::vector< ConZono > get_leaves(bool remove_redundancy=true, const OptSettings &settings=OptSettings(), OptSolution *solution=nullptr, int n_leaves=std::numeric_limits< int >::max(), int contractor_iter=100) const
Computes individual constrained zonotopes whose union is the hybrid zonotope object.
Definition PolymorphicFunctions.hpp:1730
Eigen::SparseMatrix< zono_float > Ab
binary constraint matrix
Definition HybZono.hpp:461
Eigen::SparseMatrix< zono_float > Ac
continuous constraint matrix
Definition HybZono.hpp:458
Eigen::SparseMatrix< zono_float > G
generator matrix G = [Gc, Gb]
Definition HybZono.hpp:446
int nGc
number of continuous factors
Definition HybZono.hpp:476
virtual std::unique_ptr< HybZono > complement(const zono_float delta_m=100, const bool remove_redundancy=true, const OptSettings &settings=OptSettings(), OptSolution *solution=nullptr, const int n_leaves=std::numeric_limits< int >::max(), const int contractor_iter=100)
Computes the complement of the set Z.
Definition HybZono.hpp:258
Inequality class.
Definition Inequality.hpp:50
void set_ineq_type(const IneqType type)
Sets the direction of the inequality or sets it to be an equality.
Definition Inequality.hpp:99
void set_rhs(const zono_float rhs)
Set the right hand side of the inequality.
Definition Inequality.hpp:89
void add_term(const int idx, const zono_float coeff)
Adds a term to the inequality.
Definition Inequality.hpp:76
Point class.
Definition Point.hpp:28
Zonotope class.
Definition Zono.hpp:33
#define zono_float
Defines the floating-point type used in ZonoOpt.
Definition ZonoOpt.hpp:43
#define zono_eps
Defines the precision used for floating point comparisons in ZonoOpt.
Definition ZonoOpt.hpp:51
std::unique_ptr< HybZono > cartesian_product(const HybZono &Z1, HybZono &Z2)
Computes the Cartesian product of two sets Z1 and Z2.
Definition PolymorphicFunctions.hpp:808
std::unique_ptr< HybZono > set_diff(const HybZono &Z1, HybZono &Z2, zono_float delta_m=100, bool remove_redundancy=true, const OptSettings &settings=OptSettings(), OptSolution *solution=nullptr, int n_leaves=std::numeric_limits< int >::max(), int contractor_iter=100)
Set difference Z1 \ Z2.
Definition PolymorphicFunctions.hpp:1248
std::unique_ptr< HybZono > union_of_many(const std::vector< HybZono * > &Zs, bool preserve_sharpness=false, bool expose_indicators=false)
Computes union of several sets.
Definition PolymorphicFunctions.hpp:516
std::unique_ptr< HybZono > minkowski_sum(const HybZono &Z1, HybZono &Z2)
Computes Minkowski sum of two sets Z1 and Z2.
Definition PolymorphicFunctions.hpp:143
std::unique_ptr< HybZono > project_onto_dims(const HybZono &Z, const std::vector< int > &dims)
Projects set Z onto the dimensions specified in dims.
Definition PolymorphicFunctions.hpp:114
std::unique_ptr< HybZono > affine_map(const HybZono &Z, const Eigen::SparseMatrix< zono_float > &R, const Eigen::Vector< zono_float, -1 > &s=Eigen::Vector< zono_float, -1 >())
Returns affine map R*Z + s of set Z.
Definition PolymorphicFunctions.hpp:71
std::unique_ptr< HybZono > intersection(const HybZono &Z1, HybZono &Z2, const Eigen::SparseMatrix< zono_float > &R=Eigen::SparseMatrix< zono_float >())
Computes the generalized intersection of sets Z1 and Z2 over the matrix R.
Definition PolymorphicFunctions.hpp:198
std::unique_ptr< HybZono > halfspace_intersection(HybZono &Z, const Eigen::SparseMatrix< zono_float > &H, const Eigen::Vector< zono_float, -1 > &f, const Eigen::SparseMatrix< zono_float > &R=Eigen::SparseMatrix< zono_float >())
Computes the intersection generalized intersection of set Z with halfspace H*x <= f over matrix R.
Definition PolymorphicFunctions.hpp:304
std::unique_ptr< HybZono > intersection_over_dims(const HybZono &Z1, HybZono &Z2, const std::vector< int > &dims)
Computes the generalized intersection of sets Z1 and Z2 over the specified dimensions.
Definition PolymorphicFunctions.hpp:273
std::unique_ptr< HybZono > pontry_diff(HybZono &Z1, HybZono &Z2, bool exact=false)
Computes the Pontryagin difference Z1 - Z2.
Definition PolymorphicFunctions.hpp:334
std::unique_ptr< HybZono > constrain(HybZono &Z, const std::vector< Inequality > &ineqs, const Eigen::SparseMatrix< zono_float > &R=Eigen::SparseMatrix< zono_float >())
Applies inequalities to set.
Definition PolymorphicFunctions.hpp:867
std::unique_ptr< HybZono > vrep_2_hybzono(const std::vector< Eigen::Matrix< zono_float, -1, -1 > > &Vpolys, bool expose_indicators=false)
Computes a hybrid zonotope from a union of vertex representation polytopes.
Definition PolymorphicFunctions.hpp:1411
std::unique_ptr< HybZono > zono_union_2_hybzono(std::vector< Zono > &Zs, bool expose_indicators=false)
Computes a hybrid zonotope from a union of zonotopes.
Definition PolymorphicFunctions.hpp:1264
std::unique_ptr< Zono > interval_2_zono(const Box &box)
Builds a zonotope from a Box object.
Definition PolymorphicFunctions.hpp:1575
std::unique_ptr< Zono > make_regular_zono_2D(const zono_float radius, const int n_sides, const bool outer_approx, const Eigen::Vector< zono_float, 2 > &c)
Builds a 2D regular zonotope with a given radius and number of sides.
Definition PolymorphicFunctions.hpp:1594
std::unique_ptr< ConZono > vrep_2_conzono(const Eigen::Matrix< zono_float, -1, -1 > &Vpoly)
Builds a constrained zonotope from a vertex representation polytope.
Definition PolymorphicFunctions.hpp:1547
@ LESS_OR_EQUAL
Definition Inequality.hpp:39
@ GREATER_OR_EQUAL
Definition Inequality.hpp:40
@ GREATER
Definition Inequality.hpp:43
@ EQUAL
Definition Inequality.hpp:41
@ LESS
Definition Inequality.hpp:42
Interval class.
Definition Intervals.hpp:372
Settings for optimization routines in ZonoOpt library.
Definition SolverDataStructures.hpp:26
Solution data structure for optimization routines in ZonoOpt library.
Definition SolverDataStructures.hpp:153
Eigen::Vector< zono_float, -1 > z
solution vector
Definition SolverDataStructures.hpp:157