1#ifndef ZONOOPT_POLYMORPHIC_FUNCTIONS_HPP_
2#define ZONOOPT_POLYMORPHIC_FUNCTIONS_HPP_
31using namespace detail;
36 return dynamic_cast<const Point*
>(
this) !=
nullptr;
41 return (
dynamic_cast<const Zono*
>(
this) !=
nullptr) && (
dynamic_cast<const Point*
>(
this) ==
nullptr);
46 return (
dynamic_cast<const ConZono*
>(
this) !=
nullptr) && (
dynamic_cast<const Zono*
>(
this) ==
nullptr);
51 return (
dynamic_cast<const HybZono*
>(
this) !=
nullptr) && (
dynamic_cast<const ConZono*
>(
this) ==
nullptr) &&
52 dynamic_cast<const EmptySet*
>(
this) ==
nullptr;
57 return dynamic_cast<const EmptySet*
>(
this) !=
nullptr;
62 const Eigen::SparseMatrix<zono_float>& R,
const Eigen::Vector<zono_float, -1>& s)
66 const Eigen::Vector<
zono_float, -1> * s_ptr =
nullptr;
69 s_def.resize(R.rows());
78 if (R.cols() != Z.
n || R.rows() != s_ptr->size())
80 throw std::invalid_argument(
"Linear_map: invalid input dimensions.");
85 return std::make_unique<EmptySet>(R.rows());
89 Eigen::SparseMatrix<zono_float> Gc = R*Z.
Gc;
90 Eigen::SparseMatrix<zono_float> Gb = R*Z.
Gb;
101 return std::make_unique<Point>(c);
107 for (
const int dim : dims)
109 if (dim < 0 || dim >= Z.
n)
111 throw std::invalid_argument(
"Project onto dims: invalid dimension.");
117 return std::make_unique<EmptySet>(dims.size());
121 Eigen::SparseMatrix<zono_float> R (dims.size(), Z.
n);
122 std::vector<Eigen::Triplet<zono_float>> tripvec;
123 for (
int i=0; i<dims.size(); i++)
125 tripvec.emplace_back(i, dims[i], 1);
127 R.setFromTriplets(tripvec.begin(), tripvec.end());
138 throw std::invalid_argument(
"Minkowski sum: n dimensions must match.");
143 return std::make_unique<EmptySet>(Z1.
n);
146 return std::unique_ptr<HybZono>(Z2.
clone());
149 return std::unique_ptr<HybZono>(Z1.
clone());
158 std::vector<Eigen::Triplet<zono_float>> tripvec;
160 Eigen::SparseMatrix<zono_float> Gc = hcat<zono_float>(Z1.
Gc, Z2.
Gc);
161 Eigen::SparseMatrix<zono_float> Gb = hcat<zono_float>(Z1.
Gb, Z2.
Gb);
164 Eigen::SparseMatrix<zono_float> Ac (Z1.
nC + Z2.
nC, Z1.
nGc + Z2.
nGc);
165 get_triplets_offset<zono_float>(Z1.
Ac, tripvec, 0, 0);
166 get_triplets_offset<zono_float>(Z2.
Ac, tripvec, Z1.
nC, Z1.
nGc);
167 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
170 Eigen::SparseMatrix<zono_float> Ab (Z1.
nC + Z2.
nC, Z1.
nGb + Z2.
nGb);
171 get_triplets_offset<zono_float>(Z1.
Ab, tripvec, 0, 0);
172 get_triplets_offset<zono_float>(Z2.
Ab, tripvec, Z1.
nC, Z1.
nGb);
173 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
176 b.segment(0, Z1.
nC) = Z1.
b;
177 b.segment(Z1.
nC, Z2.
nC) = Z2.
b;
181 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b, Z1.
zero_one_form);
183 return std::make_unique<ConZono>(Gc, c, Ac, b, Z1.
zero_one_form);
191 const Eigen::SparseMatrix<zono_float> * R_ptr =
nullptr;
192 Eigen::SparseMatrix<zono_float> R_def;
193 if (R.rows() == 0 && R.cols() == 0)
195 R_def.resize(Z1.
n, Z1.
n);
205 if (R_ptr->rows() != Z2.
n || R_ptr->cols() != Z1.
n)
207 throw std::invalid_argument(
"Intersection: inconsistent input dimensions.");
212 return std::make_unique<EmptySet>(Z1.
n);
222 Eigen::SparseMatrix<zono_float> Gc = Z1.
Gc;
223 Gc.conservativeResize(Z1.
n, Z1.
nGc + Z2.
nGc);
225 Eigen::SparseMatrix<zono_float> Gb = Z1.
Gb;
226 Gb.conservativeResize(Z1.
n, Z1.
nGb + Z2.
nGb);
230 std::vector<Eigen::Triplet<zono_float>> tripvec;
231 Eigen::SparseMatrix<zono_float> Ac (Z1.
nC + Z2.
nC + R_ptr->rows(), Z1.
nGc + Z2.
nGc);
232 get_triplets_offset<zono_float>(Z1.
Ac, tripvec, 0, 0);
233 get_triplets_offset<zono_float>(Z2.
Ac, tripvec, Z1.
nC, Z1.
nGc);
234 Eigen::SparseMatrix<zono_float> RZ1Gc = (*R_ptr)*Z1.
Gc;
235 get_triplets_offset<zono_float>(RZ1Gc, tripvec, Z1.
nC + Z2.
nC, 0);
236 Eigen::SparseMatrix<zono_float> mZ2Gc = -Z2.
Gc;
237 get_triplets_offset<zono_float>(mZ2Gc, tripvec, Z1.
nC + Z2.
nC, Z1.
nGc);
238 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
241 Eigen::SparseMatrix<zono_float> Ab (Z1.
nC + Z2.
nC + R_ptr->rows(), Z1.
nGb + Z2.
nGb);
242 get_triplets_offset<zono_float>(Z1.
Ab, tripvec, 0, 0);
243 get_triplets_offset<zono_float>(Z2.
Ab, tripvec, Z1.
nC, Z1.
nGb);
244 Eigen::SparseMatrix<zono_float> RZ1Gb = (*R_ptr)*Z1.
Gb;
245 get_triplets_offset<zono_float>(RZ1Gb, tripvec, Z1.
nC + Z2.
nC, 0);
246 Eigen::SparseMatrix<zono_float> mZ2Gb = -Z2.
Gb;
247 get_triplets_offset<zono_float>(mZ2Gb, tripvec, Z1.
nC + Z2.
nC, Z1.
nGb);
248 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
252 b.segment(0, Z1.
nC) = Z1.
b;
253 b.segment(Z1.
nC, Z2.
nC) = Z2.
b;
254 b.segment(Z1.
nC + Z2.
nC, R_ptr->rows()) = Z2.
c - (*R_ptr)*Z1.
c;
258 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b, Z1.
zero_one_form);
260 return std::make_unique<ConZono>(Gc, c, Ac, b, Z1.
zero_one_form);
264 HybZono& Z2,
const std::vector<int>& dims)
267 if (Z2.
n != dims.size())
269 throw std::invalid_argument(
"Intersection over dims: Z2.n must equal number of dimensions.");
273 for (
const int dim : dims)
275 if (dim < 0 || dim >= Z1.
n)
277 throw std::invalid_argument(
"Intersection over dims: invalid dimension.");
282 Eigen::SparseMatrix<zono_float> R (dims.size(), Z1.
n);
283 std::vector<Eigen::Triplet<zono_float>> tripvec;
284 for (
int i=0; i<dims.size(); i++)
286 tripvec.emplace_back(i, dims[i], 1);
288 R.setFromTriplets(tripvec.begin(), tripvec.end());
295 const Eigen::Vector<zono_float, -1>& f,
const Eigen::SparseMatrix<zono_float>& R)
300 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> H_rm = H;
301 std::vector<Inequality> ineqs;
302 for (
int k=0; k<H_rm.rows(); ++k)
305 std::vector<Eigen::Triplet<zono_float>> trips_row = get_triplets_row<zono_float>(H_rm, k);
309 for (
const auto& trip : trips_row)
311 ineq.
add_term(trip.col(), trip.value());
316 ineqs.push_back(ineq);
329 throw std::invalid_argument(
"Pontryagin difference: n dimensions must match.");
334 return std::unique_ptr<HybZono>(Z1.
clone());
337 if (Z1.
nG == 0 && !exact)
338 return std::make_unique<EmptySet>(Z1.
n);
344 throw std::invalid_argument(
"Pontryagin difference: cannot compute exact set when subtrahend is a ConZono or HybZono");
354 std::unique_ptr<HybZono> Z_out (Z1.
clone());
358 const Eigen::Matrix<
zono_float, -1, -1> G2 = Z2.
G.toDense();
360 for (
int i=0; i<Z2.
nG; ++i)
362 std::unique_ptr<HybZono> Z_plus (Z_out->clone()), Z_minus (Z_out->clone());
363 Z_plus->c += G2.col(i);
364 Z_minus->c -= G2.col(i);
379 std::vector<Zono> Z2_leaves;
380 for (
auto& CZ : Z2_CZ_leaves)
382 Z2_leaves.push_back(*CZ.to_zono_approx());
386 std::vector<std::unique_ptr<HybZono>> leaf_diffs;
387 for (
auto& Z1_leaf : Z1_leaves)
389 std::unique_ptr<HybZono> Z_out;
390 for (
auto& Z2_leaf : Z2_leaves)
399 leaf_diffs.push_back(std::move(Z_out));
401 std::vector<HybZono*> leaf_diff_ptrs;
402 for (
auto& leaf_diff : leaf_diffs)
404 leaf_diff_ptrs.emplace_back(leaf_diff.get());
412 auto Z2_CZ =
dynamic_cast<const ConZono*
>(&Z2);
416 std::vector<std::unique_ptr<HybZono>> leaf_diffs;
417 for (
auto& Z1_leaf : Z1_leaves)
419 leaf_diffs.emplace_back(
pontry_diff(Z1_leaf, Z2_zono,
false));
421 std::vector<HybZono*> leaf_diff_ptrs;
422 for (
auto& leaf_diff : leaf_diffs)
424 leaf_diff_ptrs.emplace_back(leaf_diff.get());
432 std::vector<Zono> Z2_leaves;
433 for (
auto& CZ : Z2_CZ_leaves)
435 Z2_leaves.push_back(*CZ.to_zono_approx());
439 std::unique_ptr<HybZono> Z_out;
440 for (
auto& Z2_leaf : Z2_leaves)
454 auto Z2_CZ =
dynamic_cast<const ConZono*
>(&Z2);
458 const Eigen::SparseMatrix<zono_float> GA1 = vcat<zono_float>(Z1.
G, Z1.
A);
459 Eigen::SparseMatrix<zono_float> GA2 = Z2_zono.
G;
460 GA2.conservativeResize(Z2_zono.
n + Z1.
nC, Z2_zono.
nG);
462 Eigen::SparseMatrix<zono_float> M;
463 if (Z1.
n + Z1.
nC == Z1.
nG)
466 Eigen::SparseLU<Eigen::SparseMatrix<zono_float>> lu(GA1);
467 if (lu.info() != Eigen::Success)
469 throw std::runtime_error(
"Pontryagin difference: failed to peform LU decomposition. Most likely [G; A] is not full row rank");
476 Eigen::SimplicialLDLT<Eigen::SparseMatrix<zono_float>> ldlt(GA1*GA1.transpose());
477 if (ldlt.info() != Eigen::Success)
479 throw std::runtime_error(
"Pontryagin difference: failed to perform LDLT decomposition. Most likely [G; A] is not full row rank");
481 const Eigen::SparseMatrix<zono_float> ldlt_sol = ldlt.solve(GA2);
482 M = GA1.transpose()*ldlt_sol;
485 std::vector<Eigen::Triplet<zono_float>> triplets;
486 triplets.reserve(Z1.
nG);
488 for (
int i=0; i < Z1.
nG; ++i)
492 const zono_float d = 1-(e.transpose()*M).cwiseAbs().sum();
495 return std::make_unique<EmptySet>(Z1.
n);
497 triplets.emplace_back(i, i, d);
499 Eigen::SparseMatrix<zono_float> D (Z1.
nG, Z1.
nG);
500 D.setFromSortedTriplets(triplets.begin(), triplets.end());
502 return std::make_unique<ConZono>(Z1.
G*D, Z1.
c - Z2_zono.
c, Z1.
A*D, Z1.
b,
false);
506inline std::unique_ptr<HybZono>
union_of_many(
const std::vector<HybZono*>& Zs_in,
const bool preserve_sharpness,
const bool expose_indicators)
509 std::vector<HybZono*> Zs;
511 if (!Z->is_empty_set()) {
519 throw std::invalid_argument(
"Union: empty input vector.");
523 const int n = Zs[0]->n;
524 for (
const auto & Z : Zs)
528 throw std::invalid_argument(
"Union: inconsistent dimensions.");
533 for (
const auto & Z : Zs)
535 if (!Z->zero_one_form)
542 std::vector<Eigen::Triplet<zono_float>> tripvec;
543 int rows = 0, cols = 0;
544 std::vector<int> idx_sum_to_1;
545 Eigen::SparseMatrix<zono_float> Gc, Gb, Ac, Ab;
548 if (preserve_sharpness)
556 for (
const auto & Z : Zs)
559 get_triplets_offset<zono_float>(Z->Ac, tripvec, rows, cols);
563 for (
int i=0; i<Z->nGc; i++)
565 tripvec.emplace_back(rows+i, cols+i, 1);
567 for (
int i=0; i<Z->nG; i++)
569 tripvec.emplace_back(rows+i, cols+Z->nGc+i, 1);
574 cols += Z->nGc + Z->nG;
576 Ac.resize(rows+1, cols);
577 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
583 for (
const auto & Z : Zs)
586 get_triplets_offset<zono_float>(Z->Ab, tripvec, rows, cols);
589 for (
int i=0; i<Z->nC; i++)
591 tripvec.emplace_back(rows+i, cols+Z->nGb, -Z->b(i));
596 for (
int i=0; i<Z->nGb; i++)
598 tripvec.emplace_back(rows+Z->nGc+i, cols+i, 1);
602 for (
int i=0; i<Z->nG; i++)
604 tripvec.emplace_back(rows+i, cols+Z->nGb, -1);
612 idx_sum_to_1.push_back(cols-1);
615 for (
int & it : idx_sum_to_1)
617 tripvec.emplace_back(rows, it, 1);
620 Ab.resize(rows, cols);
621 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
626 b(Ab.rows()-1) = 1.0;
630 if (expose_indicators)
631 n_out +=
static_cast<int>(Zs.size());
636 for (
const auto & Z : Zs)
638 get_triplets_offset<zono_float>(Z->Gc, tripvec, 0, cols);
639 cols += 2*Z->nGc + Z->nGb;
641 Gc.resize(n_out, cols);
642 Gc.setFromTriplets(tripvec.begin(), tripvec.end());
647 for (
const auto & Z : Zs)
649 get_triplets_offset<zono_float>(Z->Gb, tripvec, 0, cols);
651 for (
int i=0; i<Z->n; i++)
653 tripvec.emplace_back(i, cols, Z->c(i));
657 for (
int i=n; i<n_out; ++i)
659 tripvec.emplace_back(i, idx_sum_to_1[i-n], 1.0);
661 Gb.resize(n_out, cols);
662 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
676 for (
const auto & Z : Zs)
679 for (
int i=0; i<Z->nGc; i++)
681 tripvec.emplace_back(rows, cols+i, 1);
683 tripvec.emplace_back(rows, cols+Z->nGc,
static_cast<zono_float>(Z->nG));
689 get_triplets_offset<zono_float>(Z->Ac, tripvec, rows, cols);
695 Ac.resize(rows+1, cols);
696 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
702 for (
const auto & Z : Zs)
705 for (
int i=0; i<Z->nGb; i++)
707 tripvec.emplace_back(rows, cols+i, 1);
709 tripvec.emplace_back(rows, cols+Z->nGb,
static_cast<zono_float>(-Z->nG));
715 get_triplets_offset<zono_float>(Z->Ab, tripvec, rows, cols);
718 for (
int i=0; i<Z->nC; i++)
720 tripvec.emplace_back(rows+i, cols+Z->nGb, -Z->b(i));
728 idx_sum_to_1.push_back(cols-1);
731 for (
int & it : idx_sum_to_1)
733 tripvec.emplace_back(rows, it, 1);
736 Ab.resize(rows, cols);
737 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
742 b(Ab.rows()-1) = 1.0;
746 if (expose_indicators)
747 n_out +=
static_cast<int>(Zs.size());
752 for (
const auto & Z : Zs)
754 get_triplets_offset<zono_float>(Z->Gc, tripvec, 0, cols);
757 Gc.resize(n_out, cols);
758 Gc.setFromTriplets(tripvec.begin(), tripvec.end());
763 for (
const auto & Z : Zs)
765 get_triplets_offset<zono_float>(Z->Gb, tripvec, 0, cols);
767 for (
int i=0; i<Z->n; i++)
769 tripvec.emplace_back(i, cols, Z->c(i));
773 for (
int i=n; i<n_out; ++i)
775 tripvec.emplace_back(i, idx_sum_to_1[i-n], 1.0);
777 Gb.resize(n_out, cols);
778 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
786 bool sharp = preserve_sharpness;
788 while (sharp && i < Zs.size())
790 sharp = Zs[i]->sharp;
795 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b,
true, sharp);
802 return std::make_unique<EmptySet>(Z1.
n + Z2.
n);
812 std::vector<Eigen::Triplet<zono_float>> tripvec;
815 Eigen::SparseMatrix<zono_float> Gc (Z1.
n + Z2.
n, Z1.
nGc + Z2.
nGc);
816 get_triplets_offset<zono_float>(Z1.
Gc, tripvec, 0, 0);
817 get_triplets_offset<zono_float>(Z2.
Gc, tripvec, Z1.
n, Z1.
nGc);
818 Gc.setFromTriplets(tripvec.begin(), tripvec.end());
821 Eigen::SparseMatrix<zono_float> Gb (Z1.
n + Z2.
n, Z1.
nGb + Z2.
nGb);
822 get_triplets_offset<zono_float>(Z1.
Gb, tripvec, 0, 0);
823 get_triplets_offset<zono_float>(Z2.
Gb, tripvec, Z1.
n, Z1.
nGb);
824 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
827 c.segment(0, Z1.
n) = Z1.
c;
828 c.segment(Z1.
n, Z2.
n) = Z2.
c;
831 Eigen::SparseMatrix<zono_float> Ac (Z1.
nC + Z2.
nC, Z1.
nGc + Z2.
nGc);
832 get_triplets_offset<zono_float>(Z1.
Ac, tripvec, 0, 0);
833 get_triplets_offset<zono_float>(Z2.
Ac, tripvec, Z1.
nC, Z1.
nGc);
834 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
837 Eigen::SparseMatrix<zono_float> Ab (Z1.
nC + Z2.
nC, Z1.
nGb + Z2.
nGb);
838 get_triplets_offset<zono_float>(Z1.
Ab, tripvec, 0, 0);
839 get_triplets_offset<zono_float>(Z2.
Ab, tripvec, Z1.
nC, Z1.
nGb);
840 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
843 b.segment(0, Z1.
nC) = Z1.
b;
844 b.segment(Z1.
nC, Z2.
nC) = Z2.
b;
848 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b, Z1.
zero_one_form);
850 return std::make_unique<ConZono>(Gc, c, Ac, b, Z1.
zero_one_form);
854 return std::make_unique<Point>(c);
857inline std::unique_ptr<HybZono>
constrain(
HybZono& Z,
const std::vector<Inequality> &ineqs,
const Eigen::SparseMatrix<zono_float>& R)
861 return std::make_unique<EmptySet>(Z.
n);
865 const Eigen::SparseMatrix<zono_float> * R_ptr =
nullptr;
866 Eigen::SparseMatrix<zono_float> R_def;
867 if (R.rows() == 0 && R.cols() == 0)
869 R_def.resize(Z.
n, Z.
n);
879 for (
const auto& ineq : ineqs)
881 if (R_ptr->rows() != ineq.get_n_dims())
882 throw std::invalid_argument(
"Inequality does not have the same number of dimensions as set");
890 std::vector<Eigen::Triplet<zono_float>> triplets_Ac, triplets_Ab;
891 Eigen::Vector<
zono_float, -1> b_new (ineqs.size());
892 Eigen::Index n_cons = 0, n_slack = 0;
893 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> RGc = (*R_ptr)*Z.
Gc;
894 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> RGb = (*R_ptr)*Z.
Gb;
897 for (
const auto& ineq : ineqs)
900 switch (ineq.get_ineq_type())
909 rhs = ineq.get_rhs();
914 const auto ineq_type = ineq.get_ineq_type();
916 for (
const auto& [idx, coeff] : ineq.get_terms())
918 const auto trips_Gc = get_triplets_row<zono_float>(RGc, idx);
919 for (
const auto& trip : trips_Gc)
922 triplets_Ac.emplace_back(n_cons, trip.col(), val);
927 const auto trips_Gb = get_triplets_row<zono_float>(RGb, idx);
928 for (
const auto& trip : trips_Gb)
931 triplets_Ab.emplace_back(n_cons, trip.col(), val);
942 b_new(n_cons) = rhs + db;
945 if (ineq_type!=
EQUAL)
947 triplets_Ac.emplace_back(n_cons, Z.
nGc + n_slack, gamma);
955 Eigen::SparseMatrix<zono_float> Ac_cons (
static_cast<Eigen::Index
>(ineqs.size()), Z.
nGc + n_slack);
956 Eigen::SparseMatrix<zono_float> Ab_cons (
static_cast<Eigen::Index
>(ineqs.size()), Z.
nGb);
957 Ac_cons.setFromTriplets(triplets_Ac.begin(), triplets_Ac.end());
958 Ab_cons.setFromTriplets(triplets_Ab.begin(), triplets_Ab.end());
961 Eigen::SparseMatrix<zono_float> Z_Ac = Z.
Ac;
962 Z_Ac.conservativeResize(Z.
nC, Z.
nGc + n_slack);
963 Eigen::SparseMatrix<zono_float> Ac = vcat(Z_Ac, Ac_cons);
964 Eigen::SparseMatrix<zono_float> Ab = vcat(Z.
Ab, Ab_cons);
965 Eigen::Vector<
zono_float, -1> b (Z.
nC +
static_cast<Eigen::Index
>(ineqs.size()));
966 b.segment(0, Z.
nC) = Z.
b;
967 b.segment(Z.
nC,
static_cast<Eigen::Index
>(ineqs.size())) = b_new;
969 Eigen::SparseMatrix<zono_float> Z_Gc = Z.
Gc;
970 Z_Gc.conservativeResize(Z.
n, Z.
nGc + n_slack);
974 return std::make_unique<HybZono>(Z_Gc, Z.
Gb, Z.
c, Ac, Ab, b,
true);
976 return std::make_unique<ConZono>(Z_Gc, Z.
c, Ac, b,
true);
980 OptSolution* solution,
const int n_leaves,
const int contractor_iter)
989 throw std::runtime_error(
"HybZono complement: set is empty.");
996 std::unique_ptr<HybZono>
Z_out;
1001 Z_out.reset(comp->clone());
1012 OptSolution* solution,
const int n_leaves,
const int contractor_iter)
1020 const auto GT = this->
G.transpose();
1021 const auto AT = this->
A.transpose();
1029 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator
it(
GTAT,
row);
it; ++
it)
1039 std::stringstream
ss;
1040 ss <<
"ConZono complement: row " <<
row <<
" of [G^T A^T] has no non-zero elements.";
1041 throw std::runtime_error(
ss.str());
1055 u1.setConstant(1 +
delta_m/2);
1057 if (
Zf1->is_0_1_form())
Zf1->convert_form();
1060 l2.segment(0, 2*this->
nG).setConstant(-(m + 3*
delta_m/2 + 1));
1061 l2.segment(2*this->
nG, 2*this->
nG).setConstant(-2);
1063 u2.segment(0, 2*this->
nG).setConstant(delta_m/2);
1064 u2.segment(2*this->
nG, 2*this->
nG).setZero();
1066 if (
Zf2->is_0_1_form())
Zf2->convert_form();
1071 Eigen::SparseMatrix<zono_float>
Gc =
m*this->
G;
1072 Gc.conservativeResize(this->
n, 9*this->
nG + this->
n + this->
nC + 1);
1075 Eigen::SparseMatrix<zono_float>
Gb (this->
n, 2*this->
nG);
1083 std::vector<Eigen::Triplet<zono_float>>
triplets;
1089 for (
int i=0;
i<this->
nG; ++
i)
1091 triplets.emplace_back(
i,
i,
m);
1093 for (
int i=0;
i<this->
nG; ++
i)
1095 triplets.emplace_back(
i, this->nG, -
delta_m/2);
1097 for (
int i=0;
i<this->
nG; ++
i)
1099 triplets.emplace_back(this->nG+
i,
i, -
m);
1101 for (
int i=0;
i<this->
nG; ++
i)
1103 triplets.emplace_back(this->nG+
i, this->nG, -
delta_m/2);
1105 Eigen::SparseMatrix<zono_float>
AcPF (2*this->nG, 3*this->nG + 1 + this->
nC + this->
n);
1113 for (
int i=0;
i<this->
nG; ++
i)
1117 for (
int i=0;
i<this->
nG; ++
i)
1119 triplets.emplace_back(this->nG,
n_offset+
i, 0.5);
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, 0.5);
1130 Eigen::SparseMatrix<zono_float>
AcDF (this->nG+1, 3*this->nG + 1 + this->nC + this->
n);
1138 for (
int i=0;
i<this->
nG; ++
i)
1140 triplets.emplace_back(
i,
i, -
m);
1142 for (
int i=0;
i<this->
nG; ++
i)
1144 triplets.emplace_back(
i, this->nG,
delta_m/2);
1146 for (
int i=0;
i<this->
nG; ++
i)
1148 triplets.emplace_back(this->nG+
i,
i,
m);
1150 for (
int i=0;
i<this->
nG; ++
i)
1152 triplets.emplace_back(this->nG+
i, this->nG,
delta_m/2);
1155 for (
int i=0;
i<this->
nG; ++
i)
1157 triplets.emplace_back(2*this->nG+
i,
n_offset+
i, 1);
1160 for (
int i=0;
i<this->
nG; ++
i)
1162 triplets.emplace_back(3*this->nG+
i,
n_offset+
i, 1);
1164 Eigen::SparseMatrix<zono_float>
AcCS (4*this->nG, 3*this->nG + 1 + this->nC + this->
n);
1172 for (
int i=0;
i<this->
nG; ++
i)
1174 triplets.emplace_back(
i,
i,
m);
1176 for (
int i=0;
i<this->
nG; ++
i)
1178 triplets.emplace_back(this->nG+
i, this->nG+
i,
m);
1180 for (
int i=0;
i<this->
nG; ++
i)
1182 triplets.emplace_back(2*this->nG+
i,
i, -1);
1184 for (
int i=0;
i<this->
nG; ++
i)
1186 triplets.emplace_back(3*this->nG+
i, this->nG+
i, -1);
1188 Eigen::SparseMatrix<zono_float>
AbCS (4*this->nG, 2*this->nG);
1203 n_offset = this->nG + 1 + this->
n + this->nC + 2*this->
nG;
1213 Eigen::SparseMatrix<zono_float>
Ac (7*this->nG + this->nC + 1, 9*this->nG + this->
n + this->nC + 1);
1222 Eigen::SparseMatrix<zono_float>
Ab (7*this->nG + this->nC + 1, 2*this->nG);
1229 Eigen::Vector<
zono_float, -1>
b (7*this->nG + this->nC + 1);
1230 b.segment(0, this->nC) = this->
b;
1231 b.segment(this->nC, 2*this->nG) =
Zf1->c;
1232 b.segment(this->nC + 2*this->nG, this->nG + 1) =
bDF;
1233 b.segment(this->nC + 2*this->nG + this->nG + 1, 4*this->nG) =
Zf2->c;
1236 return std::make_unique<HybZono>(
Gc,
Gb,
c,
Ac,
Ab,
b,
false,
false);
1244 return std::unique_ptr<HybZono>(Z1.
clone());
1248 auto Z2_comp = Z2.
complement(delta_m, remove_redundancy, settings, solution, n_leaves, contractor_iter);
1260 throw std::invalid_argument(
"Zono union: empty input vector.");
1264 int n_dims = Zs[0].n;
1265 const int n_zonos = Zs.size();
1273 throw std::invalid_argument(
"Zono union: inconsistent dimensions.");
1277 if (!Z.zero_one_form)
1288 std::vector<Eigen::Matrix<
zono_float, 1, -1>> M_vec;
1289 std::vector<Eigen::Matrix<
zono_float, -1, 1>> S_vec;
1290 Eigen::Matrix<
zono_float, 1, -1> M_row (n_zonos);
1294 for (
int i=0; i<n_zonos; i++)
1297 Gd = Zs[i].G.toDense();
1298 for (
int j=0; j<n_gens; j++)
1301 auto generator_equal = [&](
const Eigen::Matrix<
zono_float, -1, 1> &s) ->
bool
1303 return (s - Gd.col(j)).norm() <
zono_eps;
1306 if (
auto it_S = std::find_if(S_vec.begin(), S_vec.end(), generator_equal); it_S == S_vec.end())
1308 S_vec.emplace_back(Gd.col(j));
1311 M_vec.push_back(M_row);
1315 int idx = std::distance(S_vec.begin(), it_S);
1321 int nG = S_vec.size();
1324 Eigen::Matrix<
zono_float, -1, -1> S (n_dims, nG);
1325 Eigen::Matrix<
zono_float, -1, -1> M (nG, n_zonos);
1326 for (
int i=0; i<nG; i++)
1328 S.col(i) = S_vec[i];
1329 M.row(i) = M_vec[i];
1335 std::vector<Eigen::Triplet<zono_float>> tripvec;
1339 if (expose_indicators)
1340 n_out +=
static_cast<int>(n_zonos);
1343 Eigen::SparseMatrix<zono_float> Gc = S.sparseView();
1344 Gc.conservativeResize(n_out, 2*nG);
1348 for (
int i=0; i<n_zonos; ++i)
1350 for (
int j=0; j<n_dims; ++j)
1352 tripvec.emplace_back(j, i, Zs[i].c(j));
1355 for (
int i=n_dims; i<n_out; ++i)
1357 tripvec.emplace_back(i, i-n_dims, 1.0);
1359 Eigen::SparseMatrix<zono_float> Gb (n_out, n_zonos);
1360 Gb.setFromTriplets(tripvec.begin(), tripvec.end());
1369 Eigen::SparseMatrix<zono_float> Ac (1+nG, 2*nG);
1370 Eigen::SparseMatrix<zono_float> I_ng (nG, nG);
1372 get_triplets_offset<zono_float>(I_ng, tripvec, 1, 0);
1373 Eigen::Vector<
zono_float, -1> sum_M = M.rowwise().sum();
1374 for (
int i=0; i<nG; i++)
1376 tripvec.emplace_back(1+i, nG+i, sum_M(i));
1378 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
1382 Eigen::SparseMatrix<zono_float> Ab (1+nG, n_zonos);
1384 for (
int i=0; i<n_zonos; i++)
1386 tripvec.emplace_back(0, i, 1);
1388 Eigen::SparseMatrix<zono_float> mM_sp = -M.sparseView();
1389 get_triplets_offset<zono_float>(mM_sp, tripvec, 1, 0);
1390 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
1399 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b,
true,
true);
1402inline std::unique_ptr<HybZono>
vrep_2_hybzono(
const std::vector<Eigen::Matrix<zono_float, -1, -1>> &Vpolys,
const bool expose_indicators)
1407 throw std::invalid_argument(
"set_from_vrep: Vpolys must have at least one polytope.");
1411 const int n_polys = Vpolys.size();
1412 const int n_dims = Vpolys[0].cols();
1416 for (
const auto & Vpoly : Vpolys)
1418 if (Vpoly.cols() != n_dims)
1420 throw std::invalid_argument(
"set_from_vrep: all polytopes must have the same number of dimensions.");
1426 std::vector<Eigen::Matrix<
zono_float, 1, -1>> V_vec, M_vec;
1427 Eigen::Matrix<
zono_float, 1, -1> M_row (n_polys);
1430 for (
int i=0; i<n_polys; i++)
1432 n_verts = Vpolys[i].rows();
1433 for (
int j=0; j<n_verts; j++)
1436 auto vertex_equal = [&](
const Eigen::Matrix<
zono_float, 1, -1> &v) ->
bool
1438 return (v - Vpolys[i].row(j)).norm() <
zono_eps;
1441 if (
auto it_V = std::find_if(V_vec.begin(), V_vec.end(), vertex_equal); it_V == V_vec.end())
1443 V_vec.emplace_back(Vpolys[i].row(j));
1446 M_vec.push_back(M_row);
1450 int idx = std::distance(V_vec.begin(), it_V);
1456 int nV = V_vec.size();
1459 Eigen::Matrix<
zono_float, -1, -1> V (n_dims, nV);
1460 Eigen::Matrix<
zono_float, -1, -1> M (nV, n_polys);
1461 for (
int i=0; i<V_vec.size(); i++)
1463 V.col(i) = V_vec[i];
1464 M.row(i) = M_vec[i];
1470 std::vector<Eigen::Triplet<zono_float>> tripvec;
1474 if (expose_indicators)
1475 n_out +=
static_cast<int>(n_polys);
1478 Eigen::SparseMatrix<zono_float> Gc = V.sparseView();
1479 Gc.conservativeResize(n_out, 2*nV);
1483 for (
int i=n_dims; i<n_out; ++i)
1485 tripvec.emplace_back(i, i-n_dims, 1.0);
1487 Eigen::SparseMatrix<zono_float> Gb (n_out, n_polys);
1488 Gb.setFromSortedTriplets(tripvec.begin(), tripvec.end());
1498 Eigen::SparseMatrix<zono_float> Ac (2+nV, 2*nV);
1499 Eigen::SparseMatrix<zono_float> I_nv (nV, nV);
1501 for (
int i=0; i<nV; i++)
1503 tripvec.emplace_back(0, i, 1);
1505 get_triplets_offset<zono_float>(I_nv, tripvec, 2, 0);
1506 Eigen::Vector<
zono_float, -1> sum_M = M.rowwise().sum();
1507 for (
int i=0; i<nV; i++)
1509 tripvec.emplace_back(2+i, nV+i, sum_M(i));
1511 Ac.setFromTriplets(tripvec.begin(), tripvec.end());
1516 Eigen::SparseMatrix<zono_float> Ab (2+nV, n_polys);
1518 for (
int i=0; i<n_polys; i++)
1520 tripvec.emplace_back(1, i, 1);
1522 Eigen::SparseMatrix<zono_float> mM_sp = -M.sparseView();
1523 get_triplets_offset<zono_float>(mM_sp, tripvec, 2, 0);
1524 Ab.setFromTriplets(tripvec.begin(), tripvec.end());
1535 return std::make_unique<HybZono>(Gc, Gb, c, Ac, Ab, b,
true,
true);
1538inline std::unique_ptr<ConZono>
vrep_2_conzono(
const Eigen::Matrix<zono_float, -1, -1> &Vpoly)
1541 const int n_dims = Vpoly.cols();
1542 const int n_verts = Vpoly.rows();
1545 const Eigen::SparseMatrix<zono_float> G = Vpoly.transpose().sparseView();
1550 std::vector<Eigen::Triplet<zono_float>> tripvec;
1551 Eigen::SparseMatrix<zono_float> A (1, n_verts);
1552 for (
int i=0; i<n_verts; i++)
1554 tripvec.emplace_back(0, i, 1);
1556 A.setFromTriplets(tripvec.begin(), tripvec.end());
1562 return std::make_unique<ConZono>(G, c, A, b,
true);
1569 std::vector<Eigen::Triplet<zono_float>> triplets;
1570 Eigen::SparseMatrix<zono_float> G (
static_cast<Eigen::Index
>(box.
size()),
static_cast<Eigen::Index
>(box.
size()));
1571 for (
int i=0; i<box.
size(); i++)
1573 triplets.emplace_back(i, i, box[i].width()/2);
1575 G.setFromSortedTriplets(triplets.begin(), triplets.end());
1581 return std::make_unique<Zono>(G, c,
false);
1588 if (n_sides % 2 != 0 || n_sides < 4)
1590 throw std::invalid_argument(
"make_regular_zono_2D: number of sides must be even and >= 4.");
1596 throw std::invalid_argument(
"make_regular_zono_2D: radius must be positive.");
1600 const int n_gens = n_sides/2;
1601 constexpr zono_float pi = 3.14159265358979323846;
1603 const zono_float R = outer_approx ? radius/std::cos(dphi/2) : radius;
1607 const zono_float l_side = 2*R*std::sin(dphi/2);
1608 Eigen::Matrix<
zono_float, -1, -1> G(2, n_gens);
1609 for (
int i = 0; i < n_gens; i++)
1611 G(0, i) = l_side*std::cos(phi);
1612 G(1, i) = l_side*std::sin(phi);
1617 return std::make_unique<Zono>(0.5*G.sparseView(), c,
false);
1630 return Z_CR->bounding_box(settings, solution);
1636 throw std::invalid_argument(
"Bounding box: empty set");
1648 const Eigen::SparseMatrix<zono_float> P (this->
nG, this->
nG);
1649 Eigen::Vector<
zono_float, -1> q = -this->
G.transpose()*
d;
1654 for (
int i=0;
i<this->
n;
i++)
1661 q = -this->
G.transpose()*
d;
1666 throw std::invalid_argument(
"Bounding box: Z is empty");
1675 q = -this->
G.transpose()*
d;
1678 sol = this->
mi_opt(P, q, 0, this->
A, this->
b, settings);
1680 throw std::invalid_argument(
"Bounding box: Z is empty");
1695 if (this->
n != d.size())
1697 throw std::invalid_argument(
"Support: inconsistent dimensions.");
1704 return Zc->support(d, settings, solution);
1708 Eigen::SparseMatrix<zono_float> P (this->
nG, this->
nG);
1709 Eigen::Vector<
zono_float, -1> q = -this->
G.transpose()*
d;
1716 throw std::invalid_argument(
"Support: infeasible");
1718 return d.dot(this->
G*sol.
z +
this->c);
1722 OptSolution* solution,
const int n_leaves,
const int contractor_iter)
const
1729 std::vector<ConZono>
leaves;
1736 if (remove_redundancy)
1740 leaf.remove_redundancy(contractor_iter);
1751 if (this->
nC == 0)
return;
1759 x_lb.setConstant(-1);
1760 x_ub.setConstant(1);
1762 x_lb.setConstant(-std::numeric_limits<zono_float>::infinity());
1763 x_ub.setConstant(std::numeric_limits<zono_float>::infinity());
1765 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> A_rm = this->
A;
1766 for (
int i=0;
i<this->
nC; ++
i)
1768 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator
it_j(A_rm,
i);
it_j; ++
it_j)
1772 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator
it_k(A_rm,
i);
it_k; ++
it_k)
1774 if (
it_j.col() ==
it_k.col())
continue;
1777 R[
it_j.col()].intersect_assign(R[
it_j.col()],
y.as_view());
1783 for (
int j=0;
j<this->
nG; ++
j)
1786 throw std::runtime_error(
"ConZono constraint reduction: set is empty");
1790 Eigen::SparseMatrix<zono_float>
Q (this->nG + this->nC, this->nG + this->nC);
1792 Eigen::SparseMatrix<zono_float>
I_nG (this->nG, this->nG);
1794 const Eigen::SparseMatrix<zono_float>
Phi = this->
G.transpose()*this->
G +
I_nG;
1796 std::vector<Eigen::Triplet<zono_float>>
triplets;
1803 Eigen::SimplicialLDLT<Eigen::SparseMatrix<zono_float>>
Q_ldlt (
Q);
1804 if (
Q_ldlt.info() != Eigen::Success)
1805 throw std::runtime_error(
"ConZono constraint reduction: Q matrix factorization failed, most likely A is not full row rank.");
1808 std::vector<std::pair<int, zono_float>>
haus_vec;
1813 Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> P(size);
1821 P.indices()[
i] =
i-1;
1830 for (
int j=0;
j<this->
nG; ++
j)
1833 const zono_float
r_j = std::max<zono_float>(0.0, std::max<zono_float>(std::abs(R[
j].to_interval().lb), std::abs(R[
j].to_interval().ub)) - 1.0);
1846 for (
int i=0;
i<this->nG + this->
nC; ++
i)
1848 triplets.emplace_back(
i,
i, 1);
1851 triplets.emplace_back(this->nG + this->nC,
j, 1);
1854 for (
int i=0;
i<this->nG + this->
nC; ++
i)
1856 triplets.emplace_back(
i, this->nG + this->nC,
Qinv_e_j(
i));
1858 Eigen::SparseMatrix<zono_float>
M (this->nG + this->nC + 1, this->nG + this->nC + 1);
1862 Eigen::Vector<
zono_float, -1> rhs (this->nG + this->nC + 1);
1864 rhs(this->nG + this->nC) =
r_j;
1871 const Eigen::SparseMatrix<zono_float>
M_perm =
P_L*
M*
P_R.inverse();
1877 const Eigen::Vector<
zono_float, -1>
d =
y.segment(0, this->nG);
1883 std::sort(
haus_vec.begin(),
haus_vec.end(), [](
const auto &
a,
const auto &
b) { return a.second < b.second; });
1885 Eigen::SparseMatrix<zono_float>
Ea (this->nG, this->nC);
1891 for (Eigen::SparseMatrix<zono_float>::InnerIterator
it(this->
A,
j);
it; ++
it)
1896 Ea.insert(
j,
it.row()) = 1/
it.value();
1908 throw std::runtime_error(
"ConZono: constraint reduction cannot find valid constraint to remove");
1911 const Eigen::SparseMatrix<zono_float>
Lambda_G =
G*
Ea;
1912 const Eigen::SparseMatrix<zono_float>
Lambda_A =
A*
Ea;
1913 Eigen::SparseMatrix<zono_float>
Gp = this->
G - Lambda_G*this->
A;
1915 Eigen::SparseMatrix<zono_float>
Ap = this->A -
Lambda_A*this->
A;
1926 triplets.emplace_back(
j,
j-1, 1);
1928 Eigen::SparseMatrix<zono_float>
dG (this->nG, this->nG - 1);
1939 triplets.emplace_back(
i-1,
i, 1);
1941 Eigen::SparseMatrix<zono_float>
dA (this->nC - 1, this->nC);
1953 return std::make_unique<Point>(this->
c);
1961 const Eigen::BDCSVD<Eigen::Matrix<
zono_float, -1, -1>, Eigen::ComputeFullV | Eigen::ComputeFullU>
svd (this->
A.toDense());
1964 const int n = this->
nG;
1965 const int r =
static_cast<int>(svd.rank());
1971 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:720
Eigen::Vector< zono_float, -1 > center() const
get center of box
Definition Intervals.hpp:893
size_t size() const
get size of Box object
Definition Intervals.hpp:832
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:1748
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:1948
std::unique_ptr< HybZono > do_complement(zono_float delta_m, bool remove_redundancy, const OptSettings &settings, OptSolution *solution, int n_leaves, int contractor_iter) override
Definition PolymorphicFunctions.hpp:1011
Empty Set class.
Definition EmptySet.hpp:25
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:988
bool is_hybzono() const
Polymorphic type checking: true if set is a hybrid zonotope.
Definition PolymorphicFunctions.hpp:49
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:742
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:44
virtual Box do_bounding_box(const OptSettings &settings, OptSolution *solution)
Definition PolymorphicFunctions.hpp:1624
virtual zono_float do_support(const Eigen::Vector< zono_float, -1 > &d, const OptSettings &settings, OptSolution *solution)
Definition PolymorphicFunctions.hpp:1691
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:714
virtual std::unique_ptr< ConZono > convex_relaxation() const
Returns convex relaxation of the hybrid zonotope.
Definition PolymorphicFunctions.hpp:1621
bool sharp
flag to indicate whether the set is known to be sharp (i.e., convex relaxation = convex hull)
Definition HybZono.hpp:488
virtual void remove_redundancy(int contractor_iter=100)
Removes redundant constraints and any unused generators.
Definition HybZono.hpp:771
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:39
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:979
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:188
bool is_empty_set() const
Polymorphic type checking: true if set is empty set object.
Definition PolymorphicFunctions.hpp:55
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:1721
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:798
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:1239
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:506
std::unique_ptr< HybZono > minkowski_sum(const HybZono &Z1, HybZono &Z2)
Computes Minkowski sum of two sets Z1 and Z2.
Definition PolymorphicFunctions.hpp:133
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:104
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:61
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:188
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:294
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:263
std::unique_ptr< HybZono > pontry_diff(HybZono &Z1, HybZono &Z2, bool exact=false)
Computes the Pontryagin difference Z1 - Z2.
Definition PolymorphicFunctions.hpp:324
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:857
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:1402
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:1255
std::unique_ptr< Zono > interval_2_zono(const Box &box)
Builds a zonotope from a Box object.
Definition PolymorphicFunctions.hpp:1566
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:1585
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:1538
@ 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:374
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