ZonoOpt v1.0.0
Loading...
Searching...
No Matches
Intervals.hpp
Go to the documentation of this file.
1#ifndef ZONOOPT_INTERVAL_UTILITIES_HPP_
2#define ZONOOPT_INTERVAL_UTILITIES_HPP_
3
15#include <limits>
16#include <string>
17#include <vector>
18#include <set>
19#include <cmath>
20#include <cassert>
21#include <Eigen/Dense>
22#include <Eigen/Sparse>
23
24/*
25Reference:
26"Applied Interval Analysis"
27Luc Jaulin, Michel Kieffer, Olivier Didrit, Eric Walter
28*/
29
30namespace ZonoOpt {
31
32 using namespace detail;
33
34 // forward declarations
35 struct Interval;
36 struct IntervalView;
37
38
46 template <typename Derived>
48 {
53 zono_float& y_min() { return static_cast<Derived*>(this)->get_y_min(); }
54
59 zono_float& y_max() { return static_cast<Derived*>(this)->get_y_max(); }
60
65 const zono_float& y_min() const { return static_cast<const Derived*>(this)->get_y_min(); }
66
71 const zono_float& y_max() const { return static_cast<const Derived*>(this)->get_y_max(); }
72
78 void set(const zono_float min, const zono_float max)
79 {
80 y_min() = min;
81 y_max() = max;
82 }
83
89 void add_assign(const Derived& x1, const Derived& x2)
90 {
91 y_min() = x1.y_min() + x2.y_min();
92 y_max() = x1.y_max() + x2.y_max();
93 }
94
100 void subtract_assign(const Derived& x1, const Derived& x2)
101 {
102 y_min() = x1.y_min() - x2.y_max();
103 y_max() = x1.y_max() - x2.y_min();
104 }
105
111 void multiply_assign(const Derived& x1, const Derived& x2)
112 {
113 zono_float a = x1.y_min() * x2.y_min();
114 zono_float b = x1.y_min() * x2.y_max();
115 zono_float c = x1.y_max() * x2.y_min();
116 zono_float d = x1.y_max() * x2.y_max();
117
118 y_min() = std::min({a, b, c, d});
119 y_max() = std::max({a, b, c, d});
120 }
121
128 {
129 if (alpha >= 0)
130 {
131 y_min() = x1.y_min() * alpha;
132 y_max() = x1.y_max() * alpha;
133 }
134 else
135 {
136 y_min() = x1.y_max() * alpha;
137 y_max() = x1.y_min() * alpha;
138 }
139 }
140
144 void inverse()
145 {
146 auto& min = y_min();
147 auto& max = y_max();
148
149 if (std::abs(min) < zono_eps && std::abs(max) < zono_eps)
150 {
151 min = std::numeric_limits<zono_float>::infinity();
152 max = -std::numeric_limits<zono_float>::infinity();
153 }
154 else if (min > 0 || max < 0)
155 {
156 min = one / max;
157 max = one / min;
158 }
159 else if (std::abs(min) < zono_eps && max > 0)
160 {
161 min = one / max;
162 max = std::numeric_limits<zono_float>::infinity();
163 }
164 else if (min < 0 && std::abs(max) < zono_eps)
165 {
166 max = one / min;
167 min = -std::numeric_limits<zono_float>::infinity();
168 }
169 else
170 {
171 min = -std::numeric_limits<zono_float>::infinity();
172 max = std::numeric_limits<zono_float>::infinity();
173 }
174 }
175
181 void divide_assign(const Derived& x1, const Derived& x2)
182 {
183 Derived inv = x2;
184 inv.inverse();
185 multiply_assign(x1, inv);
186 }
187
193 void intersect_assign(const Derived& x1, const Derived& x2)
194 {
195 y_min() = std::max(x1.y_min(), x2.y_min());
196 y_max() = std::min(x1.y_max(), x2.y_max());
197 }
198
203 bool is_empty() const
204 {
205 return y_min() - y_max() > zono_eps;
206 }
207
214 {
215 return y >= y_min() - zono_eps && y <= y_max() + zono_eps;
216 }
217
222 bool is_single_valued() const
223 {
224 return std::abs(y_max() - y_min()) < zono_eps;
225 }
226
232 {
233 return std::abs(y_max() - y_min());
234 }
235
240 void sin_assign(const Derived& x)
241 {
242 if (x.y_max() - x.y_min() >= two*pi)
243 {
244 y_max() = one;
245 y_min() = -one;
246 }
247 else
248 {
249 // shift domain to [-pi, pi]
250 zono_float u = x.y_max(); // init
251 zono_float l = x.y_min(); // init
252 while (u > pi)
253 {
254 u -= two*pi;
255 l -= two*pi;
256 }
257 while (l < -pi)
258 {
259 u += two*pi;
260 l += two*pi;
261 }
262
263 // get bounds
264 y_max() = ((l < pi/two && pi/two < u) || (l < -3*pi/two && -3*pi/two < u)) ? one : std::max(std::sin(u), std::sin(l));
265 y_min() = ((l < -pi/two && -pi/two < u) || (l < 3*pi/two && 3*pi/two < u)) ? -one : std::min(std::sin(u), std::sin(l));
266 }
267 }
268
273 void cos_assign(const Derived& x)
274 {
276 x_sin.set(x.y_min() + pi/two, x.y_max() + pi/two);
278 }
279
284 void tan_assign(const Derived& x)
285 {
286 if (x.y_max() - x.y_min() >= pi)
287 {
288 y_max() = std::numeric_limits<zono_float>::infinity();
289 y_min() = -std::numeric_limits<zono_float>::infinity();
290 }
291 else
292 {
293 // shift domain to [-pi, pi]
294 zono_float u = x.y_max(); // init
295 zono_float l = x.y_min(); // init
296 while (u > pi)
297 {
298 u -= two*pi;
299 l -= two*pi;
300 }
301 while (l < -pi)
302 {
303 u += two*pi;
304 l += two*pi;
305 }
306
307 // get bounds
308 if ((l < -pi/two && -pi/two < u) || (l < pi/two && pi/two < u))
309 {
310 y_max() = std::numeric_limits<zono_float>::infinity();
311 y_min() = -std::numeric_limits<zono_float>::infinity();
312 }
313 else
314 {
315 y_max() = std::tan(u);
316 y_min() = std::tan(l);
317 }
318 }
319 }
320
325 void arcsin_assign(const Derived& x)
326 {
327 assert(x.y_min() >= -one && x.y_min() <= one);
328 assert(x.y_max() >= -one && x.y_max() <= one);
329 y_min() = std::asin(x.y_min());
330 y_max() = std::asin(x.y_max());
331 }
332
337 void arccos_assign(const Derived& x)
338 {
339 assert(x.y_min() >= -one && x.y_min() <= one);
340 assert(x.y_max() >= -one && x.y_max() <= one);
341 y_min() = std::acos(x.y_max());
342 y_max() = std::acos(x.y_min());
343 }
344
349 void arctan_assign(const Derived& x)
350 {
351 y_min() = std::atan(x.y_min());
352 y_max() = std::atan(x.y_max());
353 }
354
359 void exp_assign(const Derived& x)
360 {
361 y_min() = std::exp(x.y_min());
362 y_max() = std::exp(x.y_max());
363 }
364 };
365
371 struct Interval : IntervalBase<Interval>
372 {
373 // members
376
379
380 // constructor
384 Interval() : lb(0), ub(0) {}
385
392
398 {
399 return new Interval(*this);
400 }
401
402 // get methods
403
408 zono_float& get_y_min() { return lb; }
409
414 zono_float& get_y_max() { return ub; }
415
420 const zono_float& get_y_min() const { return lb; }
421
426 const zono_float& get_y_max() const { return ub; }
427
428 // operators
429
436 {
438 result.add_assign(*this, other);
439 return result;
440 }
441
448 {
451 return result;
452 }
453
460 {
463 return result;
464 }
465
472 {
475 return result;
476 }
477
482 Interval inv() const
483 {
484 Interval result = *this;
485 result.inverse();
486 return result;
487 }
488
495 {
497 result.divide_assign(*this, other);
498 return result;
499 }
500
507 {
510 return result;
511 }
512
518 {
519 return (ub + lb) / two;
520 }
521
522 // as interval view
528
529 // print methods
534 std::string print() const
535 {
536 return "Interval: [" + std::to_string(lb) + ", " + std::to_string(ub) + "]";
537 }
538
545 friend std::ostream& operator<<(std::ostream& os, const Interval& interval)
546 {
547 os << interval.print();
548 return os;
549 }
550
555 Interval sin() const
556 {
558 result.sin_assign(*this);
559 return result;
560 }
561
566 Interval cos() const
567 {
569 result.cos_assign(*this);
570 return result;
571 }
572
577 Interval tan() const
578 {
580 result.tan_assign(*this);
581 return result;
582 }
583
589 {
591 result.arcsin_assign(*this);
592 return result;
593 }
594
600 {
602 result.arccos_assign(*this);
603 return result;
604 }
605
611 {
613 result.arctan_assign(*this);
614 return result;
615 }
616
621 Interval exp() const
622 {
624 result.exp_assign(*this);
625 return result;
626 }
627 };
628
634 struct IntervalView : IntervalBase<IntervalView>
635 {
636 // members
637
639 zono_float* lb_ptr = nullptr;
640
642 zono_float* ub_ptr = nullptr;
643
644 // constructor
645
652
653 // assignment
654
661 template <typename Derived>
663 {
664 y_min() = other.y_min();
665 y_max() = other.y_max();
666 return *this;
667 }
668
669 // to Interval
674 Interval to_interval() const;
675
676 // methods
677
683
689
694 const zono_float& get_y_min() const { return *lb_ptr; }
695
700 const zono_float& get_y_max() const { return *ub_ptr; }
701 };
702
703 // implementations
705 {
706 return Interval(*lb_ptr, *ub_ptr);
707 }
708
710 {
711 return IntervalView(&lb, &ub);
712 }
713
717 class Box
718 {
719 public:
720
721 // constructors
722
726 Box() = default;
727
732 explicit Box(const size_t size)
733 {
734 x_lb.resize(static_cast<Eigen::Index>(size));
735 x_ub.resize(static_cast<Eigen::Index>(size));
736 }
737
742 explicit Box(const std::vector<Interval>& vals)
743 {
744 x_lb.resize(static_cast<Eigen::Index>(vals.size()));
745 x_ub.resize(static_cast<Eigen::Index>(vals.size()));
746
747 for (Eigen::Index i=0; i<static_cast<Eigen::Index>(vals.size()); i++)
748 {
749 this->x_lb(i) = vals[i].y_min();
750 this->x_ub(i) = vals[i].y_max();
751 }
752 }
753
759 Box(const Eigen::Vector<zono_float, -1>& x_lb, const Eigen::Vector<zono_float, -1>& x_ub)
760 {
761 if (x_lb.size() != x_ub.size())
762 throw std::invalid_argument("x_l and x_u must have the same size");
763 this->x_lb = x_lb;
764 this->x_ub = x_ub;
765 }
766
767 // virtual destructor
771 virtual ~Box() = default;
772
773 // copy assignment
779 Box& operator=(const Box& other)
780 {
781 if (this != &other)
782 {
783 this->x_lb = other.x_lb;
784 this->x_ub = other.x_ub;
785 }
786 return *this;
787 }
788
789 // copy constructor
794 Box(const Box& other)
795 {
796 this->x_lb = other.x_lb;
797 this->x_ub = other.x_ub;
798 }
799
800 // element-wise assignment, access
801
807 IntervalView operator[](const size_t i)
808 {
809 if (i >= static_cast<size_t>(x_lb.size()))
810 throw std::out_of_range("Index out of range");
811 return IntervalView(&x_lb(static_cast<Eigen::Index>(i)), &x_ub(static_cast<Eigen::Index>(i)));
812 }
813
819 Interval operator[](const size_t i) const
820 {
821 if (i >= static_cast<size_t>(x_lb.size()))
822 throw std::out_of_range("Index out of range");
823 return Interval(x_lb(static_cast<Eigen::Index>(i)), x_ub(static_cast<Eigen::Index>(i)));
824 }
825
830 size_t size() const
831 {
832 return x_lb.size();
833 }
834
835 // project onto box
836
841 virtual void project(Eigen::Ref<Eigen::Vector<zono_float, -1>> x) const
842 {
843 if (x.size() != x_lb.size())
844 throw std::invalid_argument("x must have the same size as the Box");
845 x = x.cwiseMax(x_lb).cwiseMin(x_ub);
846 }
847
852 virtual Box* clone() const
853 {
854 return new Box(*this);
855 }
856
857 // access bounds
862 const Eigen::Vector<zono_float, -1>& lower() const { return x_lb; }
863
868 const Eigen::Vector<zono_float, -1>& upper() const { return x_ub; }
869
870 // width of box
878 {
879 zono_float w = 0;
880 for (Eigen::Index i=0; i<x_lb.size(); i++)
881 {
882 w += x_ub(i) - x_lb(i);
883 }
884 return w;
885 }
886
891 Eigen::Vector<zono_float, -1> center() const
892 {
893 Eigen::Vector<zono_float, -1> c (this->size());
894 for (Eigen::Index i=0; i<static_cast<Eigen::Index>(this->size()); i++)
895 {
896 c(i) = (*this)[i].center();
897 }
898 return c;
899 }
900
901 // operator overloading
902
908 Box operator+(const Box& other) const
909 {
910 if (this->size() != other.size())
911 throw std::invalid_argument("Box addition: inconsistent dimensions");
912 Box out = *this;
913 for (size_t i=0; i<this->size(); ++i)
914 {
915 out[i] = (*this)[i] + other[i];
916 }
917 return out;
918 }
919
925 Box operator-(const Box& other) const
926 {
927 if (this->size() != other.size())
928 throw std::invalid_argument("Box subtraction: inconsistent dimensions");
929 Box out = *this;
930 for (size_t i=0; i<this->size(); ++i)
931 {
932 out[i] = (*this)[i] - other[i];
933 }
934 return out;
935 }
936
942 Box operator*(const Box& other) const
943 {
944 if (this->size() != other.size())
945 throw std::invalid_argument("Box multiplication: inconsistent dimensions");
946 Box out = *this;
947 for (size_t i=0; i<this->size(); ++i)
948 {
949 out[i] = (*this)[i] * other[i];
950 }
951 return out;
952 }
953
960 {
961 Box out = *this;
962 for (size_t i=0; i<this->size(); ++i)
963 {
964 out[i] = (*this)[i]*alpha;
965 }
966 return out;
967 }
968
974 Box operator/(const Box& other) const
975 {
976 if (this->size() != other.size())
977 throw std::invalid_argument("Box division: inconsistent dimensions");
978 Box out = *this;
979 for (size_t i=0; i<this->size(); ++i)
980 {
981 out[i] = (*this)[i] / other[i];
982 }
983 return out;
984 }
985
986 // interval contractors
987
999 bool contract(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A, const Eigen::Vector<zono_float, -1>& b, const int iter)
1000 {
1001 if (iter <= 0)
1002 throw std::invalid_argument("iter must be positive");
1003
1004 // contract over all constraints
1005 std::set<int> constraints;
1006 for (int i=0; i<A.rows(); i++)
1007 {
1008 constraints.insert(i);
1009 }
1010
1011 // run contractor
1012 return contract_helper(A, b, iter, constraints);
1013 }
1014
1028 bool contract_subset(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A_rm, const Eigen::Vector<zono_float, -1>& b, int iter,
1029 const Eigen::SparseMatrix<zono_float>& A, const std::set<int>& inds, int tree_search_depth)
1030 {
1031 if (iter <= 0)
1032 throw std::invalid_argument("iter must be positive");
1033 if (A_rm.rows() != A.rows() || A_rm.cols() != A.cols())
1034 throw std::invalid_argument("A_rm must equal A");
1035
1036 // get affected constraints
1037 std::set<int> all_constraints, all_vars;
1038
1039 get_vars_cons(A, A_rm, all_constraints, all_vars, inds, 0, tree_search_depth);
1040
1041 // run contractor
1042 return contract_helper(A_rm, b, iter, all_constraints);
1043 }
1044
1050 Box linear_map(const Eigen::Matrix<zono_float, -1, -1>& A) const
1051 {
1052 // input handling
1053 if (A.cols() != x_lb.size())
1054 throw std::invalid_argument("Matrix A must have the same number of columns as the size of the Box");
1055
1056 // declare
1057 Box y(A.rows());
1058
1059 // linear map
1060 for (int i=0; i<A.rows(); i++)
1061 {
1062 y[i] = Interval(0, 0);
1063 for (int j=0; j<A.cols(); j++)
1064 {
1065 y[i].add_assign(y[i], ((*this)[j]*A(i, j)).as_view());
1066 }
1067 }
1068 return y;
1069 }
1070
1076 Box linear_map(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A) const
1077 {
1078 // input handling
1079 if (A.cols() != x_lb.size())
1080 throw std::invalid_argument("Matrix A must have the same number of columns as the size of the Box");
1081
1082 // declare
1083 Box y (A.rows());
1084
1085 // linear map
1086 for (int i=0; i<A.rows(); i++)
1087 {
1088 y[i] = Interval(0, 0);
1089 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A, i); it; ++it)
1090 {
1091 y[i].add_assign(y[i], ((*this)[it.col()]*it.value()).as_view());
1092 }
1093 }
1094 return y;
1095 }
1096
1102 Interval dot(const Eigen::Vector<zono_float, -1>& x) const
1103 {
1104 // input handling
1105 if (x.size() != x_lb.size())
1106 throw std::invalid_argument("Vector x must have the same size as the Box");
1107
1108 // declare
1109 Interval y(0, 0);
1110
1111 // linear map
1112 for (int i=0; i<this->x_lb.size(); i++)
1113 y.add_assign(y, ((*this)[i]*x(i)));
1114 return y;
1115 }
1116
1121 void permute(const Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic>& P)
1122 {
1123 this->x_lb = P*this->x_lb;
1124 this->x_ub = P*this->x_ub;
1125 }
1126
1131 std::string print() const
1132 {
1133 std::stringstream ss;
1134 ss << "Box: " << std::endl;
1135 for (Eigen::Index i=0; i<x_lb.size(); i++)
1136 {
1137 ss << " " << (*this)[i] << std::endl;
1138 }
1139 return ss.str();
1140 }
1141
1148 friend std::ostream& operator<<(std::ostream& os, const Box& box)
1149 {
1150 os << box.print();
1151 return os;
1152 }
1153
1154 protected:
1155
1156 // members
1158 Eigen::Vector<zono_float, -1> x_lb;
1159
1161 Eigen::Vector<zono_float, -1> x_ub;
1162
1163 private:
1164
1165 // back end for contraction operator
1166
1175 bool contract_helper(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A, const Eigen::Vector<zono_float, -1>& b, const int iter,
1176 const std::set<int>& constraints)
1177 {
1178 for (int i=0; i<iter; i++)
1179 {
1180 // loop through constraints
1181 for (const int k : constraints)
1182 {
1183 // forward propagate
1184 Interval y(0, 0);
1185 std::vector<int> cols; // keeping track of columns
1186 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A, k); it; ++it)
1187 {
1188 y.add_assign(y, (*this)[it.col()].to_interval()*it.value());
1189 cols.push_back(static_cast<int>(it.col()));
1190 }
1191
1192 // check validity
1193 if (!y.contains(b(k)))
1194 return false;
1195 else
1196 y = Interval(b(k), b(k));
1197
1198 // backward propagate
1199 for (const int col : cols)
1200 {
1201 Interval x = y; // init
1202 zono_float a_col=one;
1203 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A, k); it; ++it)
1204 {
1205 if (it.col() != col)
1206 {
1207 x.add_assign(x, (*this)[it.col()].to_interval()*(-it.value()));
1208 }
1209 else
1210 {
1211 a_col = it.value();
1212 }
1213 }
1214
1215 // update interval
1216 (*this)[col].intersect_assign((*this)[col], (x * (one/a_col)).as_view());
1217 }
1218 }
1219 }
1220
1221 return true; // constraints valid
1222 }
1223
1234 void get_vars_cons(const Eigen::SparseMatrix<zono_float>& A, const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A_rm,
1235 std::set<int>& constraints, std::set<int>& vars, const std::set<int>& new_vars, int depth, int max_depth)
1236 {
1237 // immediately copy over constraints and vars
1238 vars.insert(new_vars.begin(), new_vars.end());
1239
1240 // find new constraints
1241 std::set<int> new_constraints;
1242 for (const int i : new_vars)
1243 {
1244 for (Eigen::SparseMatrix<zono_float>::InnerIterator it(A, i); it; ++it)
1245 {
1246 if (!constraints.count(static_cast<int>(it.row())))
1247 {
1248 new_constraints.insert(static_cast<int>(it.row()));
1249 }
1250 }
1251 }
1252
1253 // find new vars
1254 std::set<int> new_new_vars;
1255 for (const int i : new_constraints)
1256 {
1257 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A_rm, i); it; ++it)
1258 {
1259 if (!vars.count(static_cast<int>(it.col())))
1260 {
1261 new_new_vars.insert(static_cast<int>(it.col()));
1262 }
1263 }
1264 }
1265
1266 // add new constraints to set
1267 constraints.insert(new_constraints.begin(), new_constraints.end());
1268
1269 // recurse if able
1270 depth++;
1271 if (depth < max_depth && new_new_vars.empty())
1272 get_vars_cons(A, A_rm, constraints, vars, new_new_vars, depth, max_depth);
1273 }
1274 };
1275
1276} // namespace ZonoOpt
1277
1278
1279#endif
Box (i.e., interval vector) class.
Definition Intervals.hpp:718
Box(const std::vector< Interval > &vals)
Constructor using vector of intervals.
Definition Intervals.hpp:742
Interval dot(const Eigen::Vector< zono_float, -1 > &x) const
Linear map with vector.
Definition Intervals.hpp:1102
std::string print() const
Print method.
Definition Intervals.hpp:1131
Interval operator[](const size_t i) const
Element-wise access.
Definition Intervals.hpp:819
Box linear_map(const Eigen::Matrix< zono_float, -1, -1 > &A) const
Linear map of box based on interval arithmetic.
Definition Intervals.hpp:1050
Eigen::Vector< zono_float, -1 > x_ub
vector of upper bounds
Definition Intervals.hpp:1161
Eigen::Vector< zono_float, -1 > x_lb
vector of lower bounds
Definition Intervals.hpp:1158
Box(const size_t size)
Default construct with size specified.
Definition Intervals.hpp:732
virtual Box * clone() const
Clone operation.
Definition Intervals.hpp:852
Box operator/(const Box &other) const
elementwise division
Definition Intervals.hpp:974
Box & operator=(const Box &other)
Copy assignment.
Definition Intervals.hpp:779
Box()=default
Default constructor.
const Eigen::Vector< zono_float, -1 > & upper() const
Get upper bounds.
Definition Intervals.hpp:868
bool contract_subset(const Eigen::SparseMatrix< zono_float, Eigen::RowMajor > &A_rm, const Eigen::Vector< zono_float, -1 > &b, int iter, const Eigen::SparseMatrix< zono_float > &A, const std::set< int > &inds, int tree_search_depth)
Interval contractor over a subset of the dimensions of the box.
Definition Intervals.hpp:1028
Eigen::Vector< zono_float, -1 > center() const
get center of box
Definition Intervals.hpp:891
bool contract(const Eigen::SparseMatrix< zono_float, Eigen::RowMajor > &A, const Eigen::Vector< zono_float, -1 > &b, const int iter)
Interval contractor.
Definition Intervals.hpp:999
virtual void project(Eigen::Ref< Eigen::Vector< zono_float, -1 > > x) const
Projects vector onto the Box.
Definition Intervals.hpp:841
void permute(const Eigen::PermutationMatrix< Eigen::Dynamic, Eigen::Dynamic > &P)
Permutes in place using permutation matrix, i.e., [x] <- P*[x].
Definition Intervals.hpp:1121
Box operator*(zono_float alpha) const
elementwise multiplication with scalar
Definition Intervals.hpp:959
size_t size() const
get size of Box object
Definition Intervals.hpp:830
friend std::ostream & operator<<(std::ostream &os, const Box &box)
print to ostream
Definition Intervals.hpp:1148
Box(const Eigen::Vector< zono_float, -1 > &x_lb, const Eigen::Vector< zono_float, -1 > &x_ub)
Constructor from intervals of lower and upper bounds.
Definition Intervals.hpp:759
IntervalView operator[](const size_t i)
Element-wise access, used for assignment.
Definition Intervals.hpp:807
Box operator-(const Box &other) const
elementwise subtraction
Definition Intervals.hpp:925
Box operator*(const Box &other) const
elementwise multiplication
Definition Intervals.hpp:942
zono_float width() const
Get width of box.
Definition Intervals.hpp:877
virtual ~Box()=default
Virtual destructor.
const Eigen::Vector< zono_float, -1 > & lower() const
Get lower bounds.
Definition Intervals.hpp:862
Box operator+(const Box &other) const
elementwise addition
Definition Intervals.hpp:908
Box linear_map(const Eigen::SparseMatrix< zono_float, Eigen::RowMajor > &A) const
Linear map of box based on interval arithmetic.
Definition Intervals.hpp:1076
Box(const Box &other)
Copy constructor.
Definition Intervals.hpp:794
#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
Definition ADMM.hpp:41
Base class for Interval and IntervalView.
Definition Intervals.hpp:48
void add_assign(const Derived &x1, const Derived &x2)
sets interval to x1 + x2
Definition Intervals.hpp:89
void arccos_assign(const Derived &x)
compute interval containing arccos(x) over x
Definition Intervals.hpp:337
void cos_assign(const Derived &x)
compute interval containing cos(x) over x
Definition Intervals.hpp:273
void inverse()
sets interval to its inverse
Definition Intervals.hpp:144
void subtract_assign(const Derived &x1, const Derived &x2)
sets interval to x1 - x2
Definition Intervals.hpp:100
void divide_assign(const Derived &x1, const Derived &x2)
sets interval to x1 / x2
Definition Intervals.hpp:181
void arctan_assign(const Derived &x)
compute interval containing arctan(x) over x
Definition Intervals.hpp:349
void set(const zono_float min, const zono_float max)
Sets interval bounds.
Definition Intervals.hpp:78
zono_float & y_max()
Returns reference to interval upper bound.
Definition Intervals.hpp:59
void sin_assign(const Derived &x)
compute interval containing sin(x) over x
Definition Intervals.hpp:240
void intersect_assign(const Derived &x1, const Derived &x2)
sets interval to intersection of x1 and x2
Definition Intervals.hpp:193
void exp_assign(const Derived &x)
compute interval containing exp(x) over x
Definition Intervals.hpp:359
void multiply_assign(const Derived &x1, const Derived &x2)
sets interval to x1 * x2
Definition Intervals.hpp:111
zono_float & y_min()
Returns reference to interval lower bound.
Definition Intervals.hpp:53
void tan_assign(const Derived &x)
compute interval containing tan(x) over x
Definition Intervals.hpp:284
void arcsin_assign(const Derived &x)
compute interval containing arcsin(x) over x
Definition Intervals.hpp:325
bool is_single_valued() const
checks whether interval is single-valued (i.e., width is 0 within numerical tolerance)
Definition Intervals.hpp:222
zono_float width() const
get width of interval (ub - lb)
Definition Intervals.hpp:231
const zono_float & y_min() const
Returns const reference to interval lower bound.
Definition Intervals.hpp:65
void multiply_assign(const Derived &x1, zono_float alpha)
sets interval to alpha * x1
Definition Intervals.hpp:127
bool contains(zono_float y) const
checks whether interval contains a value
Definition Intervals.hpp:213
bool is_empty() const
checks whether interval is empty
Definition Intervals.hpp:203
const zono_float & y_max() const
Returns const reference to interval upper bound.
Definition Intervals.hpp:71
IntervalView class.
Definition Intervals.hpp:635
zono_float & get_y_min()
get reference to lower bound
Definition Intervals.hpp:682
IntervalView & operator=(const IntervalBase< Derived > &other)
Assignment operator.
Definition Intervals.hpp:662
const zono_float & get_y_max() const
get const reference to upper bound
Definition Intervals.hpp:700
zono_float & get_y_max()
get reference to upper bound
Definition Intervals.hpp:688
Interval to_interval() const
convert to Interval class
Definition Intervals.hpp:704
const zono_float & get_y_min() const
get const reference to lower bound
Definition Intervals.hpp:694
zono_float * lb_ptr
pointer to lower bound
Definition Intervals.hpp:639
IntervalView(zono_float *y_min, zono_float *y_max)
constructor for IntervalView
Definition Intervals.hpp:651
zono_float * ub_ptr
pointer to upper bound
Definition Intervals.hpp:642
Interval class.
Definition Intervals.hpp:372
Interval(zono_float y_min, zono_float y_max)
Interval constructor.
Definition Intervals.hpp:391
const zono_float & get_y_max() const
get const reference to upper bound
Definition Intervals.hpp:426
std::string print() const
print method for Interval
Definition Intervals.hpp:534
zono_float & get_y_max()
get reference to upper bound
Definition Intervals.hpp:414
Interval()
default constructor
Definition Intervals.hpp:384
Interval intersect(const Interval &other) const
interval intersection
Definition Intervals.hpp:506
Interval arctan() const
compute interval containing arctan(x) for all x in interval
Definition Intervals.hpp:610
Interval exp() const
compute interval containing exp(x) for all x in interval
Definition Intervals.hpp:621
Interval operator+(const Interval &other) const
interval addition
Definition Intervals.hpp:435
Interval arcsin() const
compute interval containing arcsin(x) for all x in interval
Definition Intervals.hpp:588
Interval operator*(zono_float alpha) const
interval multiplication with scalar
Definition Intervals.hpp:471
zono_float lb
lower bound
Definition Intervals.hpp:375
Interval operator*(const Interval &other) const
interval multiplication
Definition Intervals.hpp:459
IntervalView as_view()
IntervalView interface for Interval.
Definition Intervals.hpp:709
const zono_float & get_y_min() const
get const reference to lower bound
Definition Intervals.hpp:420
friend std::ostream & operator<<(std::ostream &os, const Interval &interval)
print to ostream
Definition Intervals.hpp:545
Interval tan() const
compute interval containing tan(x) for all x in interval
Definition Intervals.hpp:577
Interval inv() const
interval inverse
Definition Intervals.hpp:482
Interval operator-(const Interval &other) const
interval subtraction
Definition Intervals.hpp:447
Interval operator/(const Interval &other) const
interval division
Definition Intervals.hpp:494
zono_float center() const
get center of interval
Definition Intervals.hpp:517
zono_float ub
upper bound
Definition Intervals.hpp:378
zono_float & get_y_min()
get reference to lower bound
Definition Intervals.hpp:408
Interval sin() const
compute interval containing sin(x) for all x in interval
Definition Intervals.hpp:555
Interval cos() const
compute interval containing cos(x) for all x in interval
Definition Intervals.hpp:566
Interval * clone() const
Clone Interval object.
Definition Intervals.hpp:397
Interval arccos() const
compute interval containing arccos(x) for all x in interval
Definition Intervals.hpp:599