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
30#ifndef M_PI
31 #define M_PI 3.14159265358979323846
32#endif
33
34namespace ZonoOpt {
35
36 // forward declarations
37 struct Interval;
38 struct IntervalView;
39
40
48 template <typename Derived>
50 {
55 zono_float& y_min() { return static_cast<Derived*>(this)->get_y_min(); }
56
61 zono_float& y_max() { return static_cast<Derived*>(this)->get_y_max(); }
62
67 const zono_float& y_min() const { return static_cast<const Derived*>(this)->get_y_min(); }
68
73 const zono_float& y_max() const { return static_cast<const Derived*>(this)->get_y_max(); }
74
80 void set(const zono_float min, const zono_float max)
81 {
82 y_min() = min;
83 y_max() = max;
84 }
85
91 void add_assign(const Derived& x1, const Derived& x2)
92 {
93 y_min() = x1.y_min() + x2.y_min();
94 y_max() = x1.y_max() + x2.y_max();
95 }
96
102 void subtract_assign(const Derived& x1, const Derived& x2)
103 {
104 y_min() = x1.y_min() - x2.y_max();
105 y_max() = x1.y_max() - x2.y_min();
106 }
107
113 void multiply_assign(const Derived& x1, const Derived& x2)
114 {
115 zono_float a = x1.y_min() * x2.y_min();
116 zono_float b = x1.y_min() * x2.y_max();
117 zono_float c = x1.y_max() * x2.y_min();
118 zono_float d = x1.y_max() * x2.y_max();
119
120 y_min() = std::min({a, b, c, d});
121 y_max() = std::max({a, b, c, d});
122 }
123
130 {
131 if (alpha >= 0)
132 {
133 y_min() = x1.y_min() * alpha;
134 y_max() = x1.y_max() * alpha;
135 }
136 else
137 {
138 y_min() = x1.y_max() * alpha;
139 y_max() = x1.y_min() * alpha;
140 }
141 }
142
146 void inverse()
147 {
148 auto& min = y_min();
149 auto& max = y_max();
150
151 if (std::abs(min) < zono_eps && std::abs(max) < zono_eps)
152 {
153 min = std::numeric_limits<zono_float>::infinity();
154 max = -std::numeric_limits<zono_float>::infinity();
155 }
156 else if (min > 0 || max < 0)
157 {
158 min = 1.0 / max;
159 max = 1.0 / min;
160 }
161 else if (std::abs(min) < zono_eps && max > 0)
162 {
163 min = 1.0 / max;
164 max = std::numeric_limits<zono_float>::infinity();
165 }
166 else if (min < 0 && std::abs(max) < zono_eps)
167 {
168 max = 1.0 / min;
169 min = -std::numeric_limits<zono_float>::infinity();
170 }
171 else
172 {
173 min = -std::numeric_limits<zono_float>::infinity();
174 max = std::numeric_limits<zono_float>::infinity();
175 }
176 }
177
183 void divide_assign(const Derived& x1, const Derived& x2)
184 {
185 Derived inv = x2;
186 inv.inverse();
187 multiply_assign(x1, inv);
188 }
189
195 void intersect_assign(const Derived& x1, const Derived& x2)
196 {
197 y_min() = std::max(x1.y_min(), x2.y_min());
198 y_max() = std::min(x1.y_max(), x2.y_max());
199 }
200
205 bool is_empty() const
206 {
207 return y_min() - y_max() > zono_eps;
208 }
209
216 {
217 return y >= y_min() - zono_eps && y <= y_max() + zono_eps;
218 }
219
224 bool is_single_valued() const
225 {
226 return std::abs(y_max() - y_min()) < zono_eps;
227 }
228
234 {
235 return std::abs(y_max() - y_min());
236 }
237
242 void sin_assign(const Derived& x)
243 {
244 if (x.y_max() - x.y_min() >= 2*M_PI)
245 {
246 y_max() = 1;
247 y_min() = -1;
248 }
249 else
250 {
251 // shift domain to [-pi, pi]
252 zono_float u = x.y_max(); // init
253 zono_float l = x.y_min(); // init
254 while (u > M_PI)
255 {
256 u -= 2*M_PI;
257 l -= 2*M_PI;
258 }
259 while (l < -M_PI)
260 {
261 u += 2*M_PI;
262 l += 2*M_PI;
263 }
264
265 // get bounds
266 y_max() = ((l < M_PI/2 && M_PI/2 < u) || (l < -3*M_PI/2 && -3*M_PI/2 < u)) ? 1 : std::max(std::sin(u), std::sin(l));
267 y_min() = ((l < -M_PI/2 && -M_PI/2 < u) || (l < 3*M_PI/2 && 3*M_PI/2 < u)) ? -1 : std::min(std::sin(u), std::sin(l));
268 }
269 }
270
275 void cos_assign(const Derived& x)
276 {
278 x_sin.set(x.y_min() + M_PI/2, x.y_max() + M_PI/2);
280 }
281
286 void tan_assign(const Derived& x)
287 {
288 if (x.y_max() - x.y_min() >= M_PI)
289 {
290 y_max() = std::numeric_limits<zono_float>::infinity();
291 y_min() = -std::numeric_limits<zono_float>::infinity();
292 }
293 else
294 {
295 // shift domain to [-pi, pi]
296 zono_float u = x.y_max(); // init
297 zono_float l = x.y_min(); // init
298 while (u > M_PI)
299 {
300 u -= 2*M_PI;
301 l -= 2*M_PI;
302 }
303 while (l < -M_PI)
304 {
305 u += 2*M_PI;
306 l += 2*M_PI;
307 }
308
309 // get bounds
310 if ((l < -M_PI/2 && -M_PI/2 < u) || (l < M_PI/2 && M_PI/2 < u))
311 {
312 y_max() = std::numeric_limits<zono_float>::infinity();
313 y_min() = -std::numeric_limits<zono_float>::infinity();
314 }
315 else
316 {
317 y_max() = std::tan(u);
318 y_min() = std::tan(l);
319 }
320 }
321 }
322
327 void arcsin_assign(const Derived& x)
328 {
329 assert(x.y_min() >= -1 && x.y_min() <= 1);
330 assert(x.y_max() >= -1 && x.y_max() <= 1);
331 y_min() = std::asin(x.y_min());
332 y_max() = std::asin(x.y_max());
333 }
334
339 void arccos_assign(const Derived& x)
340 {
341 assert(x.y_min() >= -1 && x.y_min() <= 1);
342 assert(x.y_max() >= -1 && x.y_max() <= 1);
343 y_min() = std::acos(x.y_max());
344 y_max() = std::acos(x.y_min());
345 }
346
351 void arctan_assign(const Derived& x)
352 {
353 y_min() = std::atan(x.y_min());
354 y_max() = std::atan(x.y_max());
355 }
356
361 void exp_assign(const Derived& x)
362 {
363 y_min() = std::exp(x.y_min());
364 y_max() = std::exp(x.y_max());
365 }
366 };
367
373 struct Interval : IntervalBase<Interval>
374 {
375 // members
378
381
382 // constructor
386 Interval() : lb(0), ub(0) {}
387
394
400 {
401 return new Interval(*this);
402 }
403
404 // get methods
405
410 zono_float& get_y_min() { return lb; }
411
416 zono_float& get_y_max() { return ub; }
417
422 const zono_float& get_y_min() const { return lb; }
423
428 const zono_float& get_y_max() const { return ub; }
429
430 // operators
431
438 {
440 result.add_assign(*this, other);
441 return result;
442 }
443
450 {
453 return result;
454 }
455
462 {
465 return result;
466 }
467
474 {
477 return result;
478 }
479
484 Interval inv() const
485 {
486 Interval result = *this;
487 result.inverse();
488 return result;
489 }
490
497 {
499 result.divide_assign(*this, other);
500 return result;
501 }
502
509 {
512 return result;
513 }
514
520 {
521 return (ub + lb) / 2;
522 }
523
524 // as interval view
530
531 // print methods
536 std::string print() const
537 {
538 return "Interval: [" + std::to_string(lb) + ", " + std::to_string(ub) + "]";
539 }
540
547 friend std::ostream& operator<<(std::ostream& os, const Interval& interval)
548 {
549 os << interval.print();
550 return os;
551 }
552
557 Interval sin() const
558 {
560 result.sin_assign(*this);
561 return result;
562 }
563
568 Interval cos() const
569 {
571 result.cos_assign(*this);
572 return result;
573 }
574
579 Interval tan() const
580 {
582 result.tan_assign(*this);
583 return result;
584 }
585
591 {
593 result.arcsin_assign(*this);
594 return result;
595 }
596
602 {
604 result.arccos_assign(*this);
605 return result;
606 }
607
613 {
615 result.arctan_assign(*this);
616 return result;
617 }
618
623 Interval exp() const
624 {
626 result.exp_assign(*this);
627 return result;
628 }
629 };
630
636 struct IntervalView : IntervalBase<IntervalView>
637 {
638 // members
639
641 zono_float* lb_ptr = nullptr;
642
644 zono_float* ub_ptr = nullptr;
645
646 // constructor
647
654
655 // assignment
656
663 template <typename Derived>
665 {
666 y_min() = other.y_min();
667 y_max() = other.y_max();
668 return *this;
669 }
670
671 // to Interval
676 Interval to_interval() const;
677
678 // methods
679
685
691
696 const zono_float& get_y_min() const { return *lb_ptr; }
697
702 const zono_float& get_y_max() const { return *ub_ptr; }
703 };
704
705 // implementations
707 {
708 return Interval(*lb_ptr, *ub_ptr);
709 }
710
712 {
713 return IntervalView(&lb, &ub);
714 }
715
719 class Box
720 {
721 public:
722
723 // constructors
724
728 Box() = default;
729
734 explicit Box(const size_t size)
735 {
736 x_lb.resize(static_cast<Eigen::Index>(size));
737 x_ub.resize(static_cast<Eigen::Index>(size));
738 }
739
744 explicit Box(const std::vector<Interval>& vals)
745 {
746 x_lb.resize(static_cast<Eigen::Index>(vals.size()));
747 x_ub.resize(static_cast<Eigen::Index>(vals.size()));
748
749 for (Eigen::Index i=0; i<vals.size(); i++)
750 {
751 this->x_lb(i) = vals[i].y_min();
752 this->x_ub(i) = vals[i].y_max();
753 }
754 }
755
761 Box(const Eigen::Vector<zono_float, -1>& x_lb, const Eigen::Vector<zono_float, -1>& x_ub)
762 {
763 if (x_lb.size() != x_ub.size())
764 throw std::invalid_argument("x_l and x_u must have the same size");
765 this->x_lb = x_lb;
766 this->x_ub = x_ub;
767 }
768
769 // virtual destructor
773 virtual ~Box() = default;
774
775 // copy assignment
781 Box& operator=(const Box& other)
782 {
783 if (this != &other)
784 {
785 this->x_lb = other.x_lb;
786 this->x_ub = other.x_ub;
787 }
788 return *this;
789 }
790
791 // copy constructor
796 Box(const Box& other)
797 {
798 this->x_lb = other.x_lb;
799 this->x_ub = other.x_ub;
800 }
801
802 // element-wise assignment, access
803
809 IntervalView operator[](const size_t i)
810 {
811 if (i >= x_lb.size())
812 throw std::out_of_range("Index out of range");
813 return IntervalView(&x_lb(static_cast<Eigen::Index>(i)), &x_ub(static_cast<Eigen::Index>(i)));
814 }
815
821 Interval operator[](const size_t i) const
822 {
823 if (i >= x_lb.size())
824 throw std::out_of_range("Index out of range");
825 return Interval(x_lb(static_cast<Eigen::Index>(i)), x_ub(static_cast<Eigen::Index>(i)));
826 }
827
832 size_t size() const
833 {
834 return x_lb.size();
835 }
836
837 // project onto box
838
843 virtual void project(Eigen::Ref<Eigen::Vector<zono_float, -1>> x) const
844 {
845 if (x.size() != x_lb.size())
846 throw std::invalid_argument("x must have the same size as the Box");
847 x = x.cwiseMax(x_lb).cwiseMin(x_ub);
848 }
849
854 virtual Box* clone() const
855 {
856 return new Box(*this);
857 }
858
859 // access bounds
864 const Eigen::Vector<zono_float, -1>& lower() const { return x_lb; }
865
870 const Eigen::Vector<zono_float, -1>& upper() const { return x_ub; }
871
872 // width of box
880 {
881 zono_float w = 0;
882 for (Eigen::Index i=0; i<x_lb.size(); i++)
883 {
884 w += x_ub(i) - x_lb(i);
885 }
886 return w;
887 }
888
893 Eigen::Vector<zono_float, -1> center() const
894 {
895 Eigen::Vector<zono_float, -1> c (this->size());
896 for (Eigen::Index i=0; i<this->size(); i++)
897 {
898 c(i) = (*this)[i].center();
899 }
900 return c;
901 }
902
903 // operator overloading
904
910 Box operator+(const Box& other) const
911 {
912 if (this->size() != other.size())
913 throw std::invalid_argument("Box addition: inconsistent dimensions");
914 Box out = *this;
915 for (size_t i=0; i<this->size(); ++i)
916 {
917 out[i] = (*this)[i] + other[i];
918 }
919 return out;
920 }
921
927 Box operator-(const Box& other) const
928 {
929 if (this->size() != other.size())
930 throw std::invalid_argument("Box subtraction: inconsistent dimensions");
931 Box out = *this;
932 for (size_t i=0; i<this->size(); ++i)
933 {
934 out[i] = (*this)[i] - other[i];
935 }
936 return out;
937 }
938
944 Box operator*(const Box& other) const
945 {
946 if (this->size() != other.size())
947 throw std::invalid_argument("Box multiplication: inconsistent dimensions");
948 Box out = *this;
949 for (size_t i=0; i<this->size(); ++i)
950 {
951 out[i] = (*this)[i] * other[i];
952 }
953 return out;
954 }
955
962 {
963 Box out = *this;
964 for (size_t i=0; i<this->size(); ++i)
965 {
966 out[i] = (*this)[i]*alpha;
967 }
968 return out;
969 }
970
976 Box operator/(const Box& other) const
977 {
978 if (this->size() != other.size())
979 throw std::invalid_argument("Box division: inconsistent dimensions");
980 Box out = *this;
981 for (size_t i=0; i<this->size(); ++i)
982 {
983 out[i] = (*this)[i] / other[i];
984 }
985 return out;
986 }
987
988 // interval contractors
989
1001 bool contract(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A, const Eigen::Vector<zono_float, -1>& b, const int iter)
1002 {
1003 if (iter <= 0)
1004 throw std::invalid_argument("iter must be positive");
1005
1006 // contract over all constraints
1007 std::set<int> constraints;
1008 for (int i=0; i<A.rows(); i++)
1009 {
1010 constraints.insert(i);
1011 }
1012
1013 // run contractor
1014 return contract_helper(A, b, iter, constraints);
1015 }
1016
1030 bool contract_subset(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A_rm, const Eigen::Vector<zono_float, -1>& b, int iter,
1031 const Eigen::SparseMatrix<zono_float>& A, const std::set<int>& inds, int tree_search_depth)
1032 {
1033 if (iter <= 0)
1034 throw std::invalid_argument("iter must be positive");
1035 if (A_rm.rows() != A.rows() || A_rm.cols() != A.cols())
1036 throw std::invalid_argument("A_rm must equal A");
1037
1038 // get affected constraints
1039 std::set<int> all_constraints, all_vars;
1040
1041 get_vars_cons(A, A_rm, all_constraints, all_vars, inds, 0, tree_search_depth);
1042
1043 // run contractor
1044 return contract_helper(A_rm, b, iter, all_constraints);
1045 }
1046
1052 Box linear_map(const Eigen::Matrix<zono_float, -1, -1>& A) const
1053 {
1054 // input handling
1055 if (A.cols() != x_lb.size())
1056 throw std::invalid_argument("Matrix A must have the same number of columns as the size of the Box");
1057
1058 // declare
1059 Box y(A.rows());
1060
1061 // linear map
1062 for (int i=0; i<A.rows(); i++)
1063 {
1064 y[i] = Interval(0, 0);
1065 for (int j=0; j<A.cols(); j++)
1066 {
1067 y[i].add_assign(y[i], ((*this)[j]*A(i, j)).as_view());
1068 }
1069 }
1070 return y;
1071 }
1072
1078 Box linear_map(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A) const
1079 {
1080 // input handling
1081 if (A.cols() != x_lb.size())
1082 throw std::invalid_argument("Matrix A must have the same number of columns as the size of the Box");
1083
1084 // declare
1085 Box y (A.rows());
1086
1087 // linear map
1088 for (int i=0; i<A.rows(); i++)
1089 {
1090 y[i] = Interval(0, 0);
1091 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A, i); it; ++it)
1092 {
1093 y[i].add_assign(y[i], ((*this)[it.col()]*it.value()).as_view());
1094 }
1095 }
1096 return y;
1097 }
1098
1104 Interval dot(const Eigen::Vector<zono_float, -1>& x) const
1105 {
1106 // input handling
1107 if (x.size() != x_lb.size())
1108 throw std::invalid_argument("Vector x must have the same size as the Box");
1109
1110 // declare
1111 Interval y(0, 0);
1112
1113 // linear map
1114 for (int i=0; i<this->x_lb.size(); i++)
1115 y.add_assign(y, ((*this)[i]*x(i)));
1116 return y;
1117 }
1118
1123 void permute(const Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic>& P)
1124 {
1125 this->x_lb = P*this->x_lb;
1126 this->x_ub = P*this->x_ub;
1127 }
1128
1133 std::string print() const
1134 {
1135 std::stringstream ss;
1136 ss << "Box: " << std::endl;
1137 for (size_t i=0; i<x_lb.size(); i++)
1138 {
1139 ss << " " << (*this)[i] << std::endl;
1140 }
1141 return ss.str();
1142 }
1143
1150 friend std::ostream& operator<<(std::ostream& os, const Box& box)
1151 {
1152 os << box.print();
1153 return os;
1154 }
1155
1156 protected:
1157
1158 // members
1160 Eigen::Vector<zono_float, -1> x_lb;
1161
1163 Eigen::Vector<zono_float, -1> x_ub;
1164
1165 private:
1166
1167 // back end for contraction operator
1168
1177 bool contract_helper(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A, const Eigen::Vector<zono_float, -1>& b, const int iter,
1178 const std::set<int>& constraints)
1179 {
1180 for (int i=0; i<iter; i++)
1181 {
1182 // loop through constraints
1183 for (const int k : constraints)
1184 {
1185 // forward propagate
1186 Interval y(0, 0);
1187 std::vector<int> cols; // keeping track of columns
1188 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A, k); it; ++it)
1189 {
1190 y.add_assign(y, (*this)[it.col()].to_interval()*it.value());
1191 cols.push_back(static_cast<int>(it.col()));
1192 }
1193
1194 // check validity
1195 if (!y.contains(b(k)))
1196 return false;
1197 else
1198 y = Interval(b(k), b(k));
1199
1200 // backward propagate
1201 for (const int col : cols)
1202 {
1203 Interval x = y; // init
1204 zono_float a_col=1;
1205 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A, k); it; ++it)
1206 {
1207 if (it.col() != col)
1208 {
1209 x.add_assign(x, (*this)[it.col()].to_interval()*(-it.value()));
1210 }
1211 else
1212 {
1213 a_col = it.value();
1214 }
1215 }
1216
1217 // update interval
1218 (*this)[col].intersect_assign((*this)[col], (x * (1/a_col)).as_view());
1219 }
1220 }
1221 }
1222
1223 return true; // constraints valid
1224 }
1225
1236 void get_vars_cons(const Eigen::SparseMatrix<zono_float>& A, const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A_rm,
1237 std::set<int>& constraints, std::set<int>& vars, const std::set<int>& new_vars, int depth, int max_depth)
1238 {
1239 // immediately copy over constraints and vars
1240 vars.insert(new_vars.begin(), new_vars.end());
1241
1242 // find new constraints
1243 std::set<int> new_constraints;
1244 for (const int i : new_vars)
1245 {
1246 for (Eigen::SparseMatrix<zono_float>::InnerIterator it(A, i); it; ++it)
1247 {
1248 if (!constraints.count(static_cast<int>(it.row())))
1249 {
1250 new_constraints.insert(static_cast<int>(it.row()));
1251 }
1252 }
1253 }
1254
1255 // find new vars
1256 std::set<int> new_new_vars;
1257 for (const int i : new_constraints)
1258 {
1259 for (Eigen::SparseMatrix<zono_float, Eigen::RowMajor>::InnerIterator it(A_rm, i); it; ++it)
1260 {
1261 if (!vars.count(static_cast<int>(it.col())))
1262 {
1263 new_new_vars.insert(static_cast<int>(it.col()));
1264 }
1265 }
1266 }
1267
1268 // add new constraints to set
1269 constraints.insert(new_constraints.begin(), new_constraints.end());
1270
1271 // recurse if able
1272 depth++;
1273 if (depth < max_depth && new_new_vars.empty())
1274 get_vars_cons(A, A_rm, constraints, vars, new_new_vars, depth, max_depth);
1275 }
1276 };
1277
1278} // namespace ZonoOpt::detail
1279
1280
1281#endif
#define M_PI
Definition Intervals.hpp:31
Box (i.e., interval vector) class.
Definition Intervals.hpp:720
Box(const std::vector< Interval > &vals)
Constructor using vector of intervals.
Definition Intervals.hpp:744
Interval dot(const Eigen::Vector< zono_float, -1 > &x) const
Linear map with vector.
Definition Intervals.hpp:1104
std::string print() const
Print method.
Definition Intervals.hpp:1133
Interval operator[](const size_t i) const
Element-wise access.
Definition Intervals.hpp:821
Box linear_map(const Eigen::Matrix< zono_float, -1, -1 > &A) const
Linear map of box based on interval arithmetic.
Definition Intervals.hpp:1052
Eigen::Vector< zono_float, -1 > x_ub
vector of upper bounds
Definition Intervals.hpp:1163
Eigen::Vector< zono_float, -1 > x_lb
vector of lower bounds
Definition Intervals.hpp:1160
Box(const size_t size)
Default construct with size specified.
Definition Intervals.hpp:734
virtual Box * clone() const
Clone operation.
Definition Intervals.hpp:854
Box operator/(const Box &other) const
elementwise division
Definition Intervals.hpp:976
Box & operator=(const Box &other)
Copy assignment.
Definition Intervals.hpp:781
Box()=default
Default constructor.
const Eigen::Vector< zono_float, -1 > & upper() const
Get upper bounds.
Definition Intervals.hpp:870
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:1030
Eigen::Vector< zono_float, -1 > center() const
get center of box
Definition Intervals.hpp:893
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:1001
virtual void project(Eigen::Ref< Eigen::Vector< zono_float, -1 > > x) const
Projects vector onto the Box.
Definition Intervals.hpp:843
void permute(const Eigen::PermutationMatrix< Eigen::Dynamic, Eigen::Dynamic > &P)
Permutes in place using permutation matrix, i.e., [x] <- P*[x].
Definition Intervals.hpp:1123
Box operator*(zono_float alpha) const
elementwise multiplication with scalar
Definition Intervals.hpp:961
size_t size() const
get size of Box object
Definition Intervals.hpp:832
friend std::ostream & operator<<(std::ostream &os, const Box &box)
print to ostream
Definition Intervals.hpp:1150
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:761
IntervalView operator[](const size_t i)
Element-wise access, used for assignment.
Definition Intervals.hpp:809
Box operator-(const Box &other) const
elementwise subtraction
Definition Intervals.hpp:927
Box operator*(const Box &other) const
elementwise multiplication
Definition Intervals.hpp:944
zono_float width() const
Get width of box.
Definition Intervals.hpp:879
virtual ~Box()=default
Virtual destructor.
const Eigen::Vector< zono_float, -1 > & lower() const
Get lower bounds.
Definition Intervals.hpp:864
Box operator+(const Box &other) const
elementwise addition
Definition Intervals.hpp:910
Box linear_map(const Eigen::SparseMatrix< zono_float, Eigen::RowMajor > &A) const
Linear map of box based on interval arithmetic.
Definition Intervals.hpp:1078
Box(const Box &other)
Copy constructor.
Definition Intervals.hpp:796
#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:50
void add_assign(const Derived &x1, const Derived &x2)
sets interval to x1 + x2
Definition Intervals.hpp:91
void arccos_assign(const Derived &x)
compute interval containing arccos(x) over x
Definition Intervals.hpp:339
void cos_assign(const Derived &x)
compute interval containing cos(x) over x
Definition Intervals.hpp:275
void inverse()
sets interval to its inverse
Definition Intervals.hpp:146
void subtract_assign(const Derived &x1, const Derived &x2)
sets interval to x1 - x2
Definition Intervals.hpp:102
void divide_assign(const Derived &x1, const Derived &x2)
sets interval to x1 / x2
Definition Intervals.hpp:183
void arctan_assign(const Derived &x)
compute interval containing arctan(x) over x
Definition Intervals.hpp:351
void set(const zono_float min, const zono_float max)
Sets interval bounds.
Definition Intervals.hpp:80
zono_float & y_max()
Returns reference to interval upper bound.
Definition Intervals.hpp:61
void sin_assign(const Derived &x)
compute interval containing sin(x) over x
Definition Intervals.hpp:242
void intersect_assign(const Derived &x1, const Derived &x2)
sets interval to intersection of x1 and x2
Definition Intervals.hpp:195
void exp_assign(const Derived &x)
compute interval containing exp(x) over x
Definition Intervals.hpp:361
void multiply_assign(const Derived &x1, const Derived &x2)
sets interval to x1 * x2
Definition Intervals.hpp:113
zono_float & y_min()
Returns reference to interval lower bound.
Definition Intervals.hpp:55
void tan_assign(const Derived &x)
compute interval containing tan(x) over x
Definition Intervals.hpp:286
void arcsin_assign(const Derived &x)
compute interval containing arcsin(x) over x
Definition Intervals.hpp:327
bool is_single_valued() const
checks whether interval is single-valued (i.e., width is 0 within numerical tolerance)
Definition Intervals.hpp:224
zono_float width() const
get width of interval (ub - lb)
Definition Intervals.hpp:233
const zono_float & y_min() const
Returns const reference to interval lower bound.
Definition Intervals.hpp:67
void multiply_assign(const Derived &x1, zono_float alpha)
sets interval to alpha * x1
Definition Intervals.hpp:129
bool contains(zono_float y) const
checks whether interval contains a value
Definition Intervals.hpp:215
bool is_empty() const
checks whether interval is empty
Definition Intervals.hpp:205
const zono_float & y_max() const
Returns const reference to interval upper bound.
Definition Intervals.hpp:73
IntervalView class.
Definition Intervals.hpp:637
zono_float & get_y_min()
get reference to lower bound
Definition Intervals.hpp:684
IntervalView & operator=(const IntervalBase< Derived > &other)
Assignment operator.
Definition Intervals.hpp:664
const zono_float & get_y_max() const
get const reference to upper bound
Definition Intervals.hpp:702
zono_float & get_y_max()
get reference to upper bound
Definition Intervals.hpp:690
Interval to_interval() const
convert to Interval class
Definition Intervals.hpp:706
const zono_float & get_y_min() const
get const reference to lower bound
Definition Intervals.hpp:696
zono_float * lb_ptr
pointer to lower bound
Definition Intervals.hpp:641
IntervalView(zono_float *y_min, zono_float *y_max)
constructor for IntervalView
Definition Intervals.hpp:653
zono_float * ub_ptr
pointer to upper bound
Definition Intervals.hpp:644
Interval class.
Definition Intervals.hpp:374
Interval(zono_float y_min, zono_float y_max)
Interval constructor.
Definition Intervals.hpp:393
const zono_float & get_y_max() const
get const reference to upper bound
Definition Intervals.hpp:428
std::string print() const
print method for Interval
Definition Intervals.hpp:536
zono_float & get_y_max()
get reference to upper bound
Definition Intervals.hpp:416
Interval()
default constructor
Definition Intervals.hpp:386
Interval intersect(const Interval &other) const
interval intersection
Definition Intervals.hpp:508
Interval arctan() const
compute interval containing arctan(x) for all x in interval
Definition Intervals.hpp:612
Interval exp() const
compute interval containing exp(x) for all x in interval
Definition Intervals.hpp:623
Interval operator+(const Interval &other) const
interval addition
Definition Intervals.hpp:437
Interval arcsin() const
compute interval containing arcsin(x) for all x in interval
Definition Intervals.hpp:590
Interval operator*(zono_float alpha) const
interval multiplication with scalar
Definition Intervals.hpp:473
zono_float lb
lower bound
Definition Intervals.hpp:377
Interval operator*(const Interval &other) const
interval multiplication
Definition Intervals.hpp:461
IntervalView as_view()
IntervalView interface for Interval.
Definition Intervals.hpp:711
const zono_float & get_y_min() const
get const reference to lower bound
Definition Intervals.hpp:422
friend std::ostream & operator<<(std::ostream &os, const Interval &interval)
print to ostream
Definition Intervals.hpp:547
Interval tan() const
compute interval containing tan(x) for all x in interval
Definition Intervals.hpp:579
Interval inv() const
interval inverse
Definition Intervals.hpp:484
Interval operator-(const Interval &other) const
interval subtraction
Definition Intervals.hpp:449
Interval operator/(const Interval &other) const
interval division
Definition Intervals.hpp:496
zono_float center() const
get center of interval
Definition Intervals.hpp:519
zono_float ub
upper bound
Definition Intervals.hpp:380
zono_float & get_y_min()
get reference to lower bound
Definition Intervals.hpp:410
Interval sin() const
compute interval containing sin(x) for all x in interval
Definition Intervals.hpp:557
Interval cos() const
compute interval containing cos(x) for all x in interval
Definition Intervals.hpp:568
Interval * clone() const
Clone Interval object.
Definition Intervals.hpp:399
Interval arccos() const
compute interval containing arccos(x) for all x in interval
Definition Intervals.hpp:601