ZonoOpt v2.1.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 <string>
16#include <vector>
17#include <set>
18#include <Eigen/Dense>
19#include <Eigen/Sparse>
20#include <cmath>
21#include <boost/numeric/interval.hpp>
22
23namespace ZonoOpt
24{
25 namespace detail
26 {
27 // need this to get inverse hyperbolics to compile with MSVC
28 template<class T>
29 struct rounded_transc_fixed : boost::numeric::interval_lib::rounded_transc_std<T> {
30 static T asinh_down(const T& x) { using std::asinh; return asinh(x); }
31 static T asinh_up (const T& x) { using std::asinh; return asinh(x); }
32 static T acosh_down(const T& x) { using std::acosh; return acosh(x); }
33 static T acosh_up (const T& x) { using std::acosh; return acosh(x); }
34 static T atanh_down(const T& x) { using std::atanh; return atanh(x); }
35 static T atanh_up (const T& x) { using std::atanh; return atanh(x); }
36 };
37 }
38
39 using namespace detail;
40
41
48 {
49 public:
50 // constructor
51
55 Interval() : _val(zero, zero) {}
56
62 Interval(const zono_float y_min, const zono_float y_max) : _val(y_min, y_max) {}
63
68 Interval* clone() const
69 {
70 return new Interval(*this);
71 }
72
73 // get methods
74
80 zono_float lb() const { return _val.lower(); }
81
87 zono_float ub() const { return _val.upper(); }
88
89 // operators
90
96 Interval operator+(const Interval& other) const
97 {
98 return Interval(this->_val + other._val);
99 }
100
107 Interval operator+(const zono_float alpha) const
108 {
109 return Interval(this->_val + alpha);
110 }
111
117 Interval operator-(const Interval& other) const
118 {
119 return Interval(this->_val - other._val);
120 }
121
128 Interval operator-(const zono_float alpha) const
129 {
130 return Interval(this->_val - alpha);
131 }
132
138 Interval operator*(const Interval& other) const
139 {
140 return Interval(this->_val * other._val);
141 }
142
149 Interval operator*(const zono_float alpha) const
150 {
151 return Interval(this->_val * alpha);
152 }
153
159 Interval operator/(const Interval& other) const
160 {
161 return Interval(this->_val / other._val);
162 }
163
170 Interval operator/(const zono_float alpha) const
171 {
172 return Interval(this->_val / alpha);
173 }
174
179 Interval inv() const
180 {
181 return Interval(boost::numeric::interval_lib::multiplicative_inverse(_val));
182 }
183
189 Interval intersect(const Interval& other) const
190 {
191 return Interval(boost::numeric::intersect(_val, other._val));
192 }
193
199 bool contains(const zono_float x) const
200 {
201 return x >= this->lb() - zono_eps && x <= this->ub() + zono_eps;
202 }
203
208 bool is_single_valued() const
209 {
210 return this->width() < zono_eps;
211 }
212
217 bool is_empty() const
218 {
219 return boost::numeric::empty(_val);
220 }
221
227 {
228 return boost::numeric::median(_val);
229 }
230
236 {
237 return _val.upper() - _val.lower();
238 }
239
247 {
248 const zono_float r = this->width() / two;
249 return Interval(-r, r);
250 }
251
252
257 Interval abs() const
258 {
259 return Interval(boost::numeric::abs(_val));
260 }
261
267 {
268 return Interval(boost::numeric::sqrt(_val));
269 }
270
277 Interval pow(const int n) const
278 {
279 return Interval(boost::numeric::pow(_val, n));
280 }
281
287 Interval nth_root(const int n) const
288 {
289 return Interval(boost::numeric::nth_root(_val, n));
290 }
291
296 Interval exp() const
297 {
298 return Interval(boost::numeric::exp(_val));
299 }
300
305 Interval log() const
306 {
307 return Interval(boost::numeric::log(_val));
308 }
309
314 Interval sin() const
315 {
316 return Interval(boost::numeric::sin(_val));
317 }
318
323 Interval cos() const
324 {
325 return Interval(boost::numeric::cos(_val));
326 }
327
332 Interval tan() const
333 {
334 return Interval(boost::numeric::tan(_val));
335 }
336
342 {
343 return Interval(boost::numeric::asin(_val));
344 }
345
351 {
352 return Interval(boost::numeric::acos(_val));
353 }
354
360 {
361 return Interval(boost::numeric::atan(_val));
362 }
363
369 {
370 return Interval(boost::numeric::sinh(_val));
371 }
372
378 {
379 return Interval(boost::numeric::cosh(_val));
380 }
381
387 {
388 return Interval(boost::numeric::tanh(_val));
389 }
390
396 {
397 return Interval(boost::numeric::asinh(_val));
398 }
399
405 {
406 return Interval(boost::numeric::acosh(_val));
407 }
408
414 {
415 return Interval(boost::numeric::atanh(_val));
416 }
417
422 std::string print() const
423 {
424 return "Interval: [" + std::to_string(lb()) + ", " + std::to_string(ub()) + "]";
425 }
426
433 friend std::ostream& operator<<(std::ostream& os, const Interval& interval)
434 {
435 os << interval.print();
436 return os;
437 }
438
439
440 private:
441
442 typedef boost::numeric::interval_lib::policies<
443 boost::numeric::interval_lib::save_state<rounded_transc_fixed<zono_float>>,
444 boost::numeric::interval_lib::checking_base<zono_float>
445 > interval_policy;
446
447 boost::numeric::interval<zono_float, interval_policy> _val;
448
449 explicit Interval(const boost::numeric::interval<zono_float, interval_policy>& val) : _val(val) {}
450 };
451
452
456 class Box
457 {
458 public:
459 // constructors
460
464 Box() = default;
465
470 explicit Box(const size_t size);
471
476 explicit Box(const std::vector<Interval>& vals);
477
482 explicit Box(const Eigen::Vector<Interval, -1>& vals);
483
489 Box(const Eigen::Vector<zono_float, -1>& x_lb, const Eigen::Vector<zono_float, -1>& x_ub);
490
491 // virtual destructor
495 virtual ~Box() = default;
496
497 // copy assignment
503 Box& operator=(const Box& other);
504
505 // copy constructor
510 Box(const Box& other);
511
512 // element-wise assignment, access
513
519 Interval get_element(int i) const;
520
521
527 void set_element(int i, const Interval& val);
528
533 size_t size() const;
534
535 // project onto box
536
541 virtual void project(Eigen::Ref<Eigen::Vector<zono_float, -1>> x) const;
542
547 virtual Box* clone() const;
548
549 // access bounds
554 const Eigen::Vector<zono_float, -1>& lower() const { return x_lb; }
555
560 const Eigen::Vector<zono_float, -1>& upper() const { return x_ub; }
561
562 // width of box
569 zono_float width() const;
570
577 Box radius() const;
578
583 Eigen::Vector<zono_float, -1> center() const;
584
585 // operator overloading
586
592 Box operator+(const Box& other) const;
593
599 Box operator-(const Box& other) const;
600
606 Box operator*(const Box& other) const;
607
613 Box operator*(zono_float alpha) const;
614
620 Box operator/(const Box& other) const;
621
622 // interval contractors
623
635 bool contract(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A, const Eigen::Vector<zono_float, -1>& b,
636 int iter);
637
651 bool contract_subset(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A_rm,
652 const Eigen::Vector<zono_float, -1>& b, int iter,
653 const Eigen::SparseMatrix<zono_float>& A, const std::set<int>& inds,
654 int tree_search_depth);
655
661 Box linear_map(const Eigen::Matrix<zono_float, -1, -1>& A) const;
662
668 Box linear_map(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A) const;
669
675 Interval dot(const Eigen::Vector<zono_float, -1>& x) const;
676
681 void permute(const Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic>& P);
682
687 std::string print() const;
688
695 friend std::ostream& operator<<(std::ostream& os, const Box& box);
696
697 protected:
698 // members
700 Eigen::Vector<zono_float, -1> x_lb;
701
703 Eigen::Vector<zono_float, -1> x_ub;
704
705 private:
706 // back end for contraction operator
707
716 virtual bool contract_helper(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A,
717 const Eigen::Vector<zono_float, -1>& b, const int iter,
718 const std::set<int>& constraints);
719
727 bool contract_forward(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A,
728 const Eigen::Vector<zono_float, -1>& b, const std::set<int>& constraints);
729
736 void contract_backward(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A,
737 const Eigen::Vector<zono_float, -1>& b, const std::set<int>& constraints);
738
749 static void get_vars_cons(const Eigen::SparseMatrix<zono_float>& A,
750 const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A_rm,
751 std::set<int>& constraints, std::set<int>& vars, const std::set<int>& new_vars,
752 int depth, int max_depth);
753
754 private:
755 friend class MI_Box;
756 };
757
758 // mixed-integer box (some bounds are fixed)
765 class MI_Box final : public Box
766 {
767 public:
768 // constructors
769
773 MI_Box() = default;
774
782 MI_Box(const Eigen::Vector<zono_float, -1>& x_lb, const Eigen::Vector<zono_float, -1>& x_ub,
783 const std::pair<int, int>& idx_b, bool zero_one_form);
784
785 // clone operation
786 Box* clone() const override;
787
788 // project
789 void project(Eigen::Ref<Eigen::Vector<zono_float, -1>> x) const override;
790
791 // get binary indices
796 const std::pair<int, int>& binary_indices() const { return idx_b; }
797
798 protected:
799 bool contract_helper(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A,
800 const Eigen::Vector<zono_float, -1>& b, const int iter,
801 const std::set<int>& constraints) override;
802
803 private:
805 std::pair<int, int> idx_b;
806 zono_float bin_low = zero, bin_high = one;
807 };
808
809
815 {
816 public:
820 IntervalMatrix() : rows_(0), cols_(0)
821 {
822 }
823
830 IntervalMatrix(size_t rows, size_t cols, const std::vector<Eigen::Triplet<Interval>>& triplets);
831
837 IntervalMatrix(const Eigen::SparseMatrix<zono_float>& mat_lb,
838 const Eigen::SparseMatrix<zono_float>& mat_ub);
839
845 IntervalMatrix(const Eigen::Matrix<zono_float, -1, -1>& mat_lb,
846 const Eigen::Matrix<zono_float, -1, -1>& mat_ub);
847
853 IntervalMatrix(const Eigen::Matrix<Interval, -1, -1>& mat);
854
861 Eigen::SparseMatrix<zono_float> center() const;
862
869 Eigen::SparseMatrix<zono_float> diam() const;
870
877 IntervalMatrix radius() const;
878
885 zono_float width() const;
886
892 Box operator*(const Eigen::Vector<zono_float, -1>& v) const;
893
899 Box operator*(const Box& box) const;
900
906 IntervalMatrix operator*(const Eigen::SparseMatrix<zono_float, Eigen::RowMajor>& A) const;
907
913 IntervalMatrix operator*(const IntervalMatrix& other) const;
914
920 IntervalMatrix operator+(const IntervalMatrix& other) const;
921
927 IntervalMatrix operator-(const IntervalMatrix& other) const;
928
933 size_t rows() const { return rows_; }
934
939 size_t cols() const { return cols_; }
940
945 std::string print() const;
946
953 friend std::ostream& operator<<(std::ostream& os, const IntervalMatrix& interval_matrix);
954
955 private:
956 size_t rows_, cols_;
957 std::vector<std::vector<std::pair<size_t, Interval>>> mat_; // rows->cols->vals
958 };
959} // namespace ZonoOpt
960
961#endif
Box (i.e., interval vector) class.
Definition Intervals.hpp:457
Interval dot(const Eigen::Vector< zono_float, -1 > &x) const
Linear map with vector.
Definition Intervals.cpp:257
std::string print() const
Print method.
Definition Intervals.cpp:278
Box linear_map(const Eigen::Matrix< zono_float, -1, -1 > &A) const
Linear map of box based on interval arithmetic.
Definition Intervals.cpp:215
Eigen::Vector< zono_float, -1 > x_ub
vector of upper bounds
Definition Intervals.hpp:703
Eigen::Vector< zono_float, -1 > x_lb
vector of lower bounds
Definition Intervals.hpp:700
Box operator/(const Box &other) const
Elementwise division.
Definition Intervals.cpp:167
Box & operator=(const Box &other)
Copy assignment.
Definition Intervals.cpp:45
Box()=default
Default constructor.
virtual void project(Eigen::Ref< Eigen::Vector< zono_float, -1 > > x) const
Projects vector onto the Box.
Definition Intervals.cpp:79
const Eigen::Vector< zono_float, -1 > & upper() const
Get upper bounds.
Definition Intervals.hpp:560
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.cpp:196
Eigen::Vector< zono_float, -1 > center() const
Get center of box.
Definition Intervals.cpp:101
void permute(const Eigen::PermutationMatrix< Eigen::Dynamic, Eigen::Dynamic > &P)
Permutes in place using permutation matrix, i.e., [x] <- P*[x].
Definition Intervals.cpp:272
size_t size() const
Get size of Box object.
Definition Intervals.cpp:74
friend std::ostream & operator<<(std::ostream &os, const Box &box)
print to ostream
Definition Intervals.cpp:289
Box operator-(const Box &other) const
Elementwise subtraction.
Definition Intervals.cpp:133
Box radius() const
Get radius of box.
Definition Intervals.cpp:111
void set_element(int i, const Interval &val)
Element-wise assignment.
Definition Intervals.cpp:68
Interval get_element(int i) const
Element-wise access.
Definition Intervals.cpp:61
virtual Box * clone() const
Clone operation.
Definition Intervals.cpp:86
Box operator*(const Box &other) const
Elementwise multiplication.
Definition Intervals.cpp:145
zono_float width() const
Get width of box.
Definition Intervals.cpp:91
bool contract(const Eigen::SparseMatrix< zono_float, Eigen::RowMajor > &A, const Eigen::Vector< zono_float, -1 > &b, int iter)
Interval contractor.
Definition Intervals.cpp:179
virtual ~Box()=default
Virtual destructor.
const Eigen::Vector< zono_float, -1 > & lower() const
Get lower bounds.
Definition Intervals.hpp:554
Box operator+(const Box &other) const
Elementwise addition.
Definition Intervals.cpp:121
Class for interval matrices (i.e., every element of the matrix is an interval)
Definition Intervals.hpp:815
size_t rows() const
Get number of rows.
Definition Intervals.hpp:933
Eigen::SparseMatrix< zono_float > diam() const
Get diameter matrix.
Definition Intervals.cpp:764
std::string print() const
Print method.
Definition Intervals.cpp:806
zono_float width() const
Get width of interval matrix.
Definition Intervals.cpp:793
IntervalMatrix operator+(const IntervalMatrix &other) const
IntervalMatrix addition.
Definition Intervals.cpp:704
Eigen::SparseMatrix< zono_float > center() const
Get center matrix.
Definition Intervals.cpp:748
friend std::ostream & operator<<(std::ostream &os, const IntervalMatrix &interval_matrix)
print to ostream
Definition Intervals.cpp:823
Box operator*(const Eigen::Vector< zono_float, -1 > &v) const
IntervalMatrix multiplication with vector.
Definition Intervals.cpp:611
IntervalMatrix operator-(const IntervalMatrix &other) const
IntervalMatrix subtraction.
Definition Intervals.cpp:726
size_t cols() const
Get number of columns.
Definition Intervals.hpp:939
IntervalMatrix radius() const
Get radius matrix.
Definition Intervals.cpp:780
IntervalMatrix()
IntervalMatrix default constructor.
Definition Intervals.hpp:820
Interval class.
Definition Intervals.hpp:48
zono_float lb() const
Get lower bound.
Definition Intervals.hpp:80
bool is_single_valued() const
Checks whether interval is single-valued (i.e., width is 0 within numerical tolerance)
Definition Intervals.hpp:208
std::string print() const
Print method for interval.
Definition Intervals.hpp:422
Interval arctanh() const
Compute interval containing arctanh(x) for all x in interval.
Definition Intervals.hpp:413
Interval()
Default constructor.
Definition Intervals.hpp:55
Interval intersect(const Interval &other) const
Interval intersection.
Definition Intervals.hpp:189
Interval tanh() const
Compute interval containing tanh(x) for all x in interval.
Definition Intervals.hpp:386
Interval arctan() const
Compute interval containing arctan(x) for all x in interval.
Definition Intervals.hpp:359
Interval log() const
Compute interval containing log(x) (base e) for all x in interval.
Definition Intervals.hpp:305
Interval sinh() const
Compute interval containing sinh(x) for all x in interval.
Definition Intervals.hpp:368
Interval exp() const
Compute interval containing exp(x) for all x in interval.
Definition Intervals.hpp:296
Interval operator+(const Interval &other) const
Interval addition.
Definition Intervals.hpp:96
Interval sqrt() const
Get square root of interval.
Definition Intervals.hpp:266
Interval arcsin() const
Compute interval containing arcsin(x) for all x in interval.
Definition Intervals.hpp:341
Interval operator-(const zono_float alpha) const
Interval subtraction with scalar.
Definition Intervals.hpp:128
Interval pow(const int n) const
Interval power.
Definition Intervals.hpp:277
Interval arcsinh() const
Compute interval containing arcsinh(x) for all x in interval.
Definition Intervals.hpp:395
Interval operator*(const zono_float alpha) const
Interval multiplication with scalar.
Definition Intervals.hpp:149
Interval operator*(const Interval &other) const
Interval multiplication.
Definition Intervals.hpp:138
Interval abs() const
Get absolute value of interval.
Definition Intervals.hpp:257
Interval radius() const
Get radius of interval.
Definition Intervals.hpp:246
Interval arccosh() const
Compute interval containing arccosh(x) for all x in interval.
Definition Intervals.hpp:404
friend std::ostream & operator<<(std::ostream &os, const Interval &interval)
Print to ostream.
Definition Intervals.hpp:433
Interval tan() const
Compute interval containing tan(x) for all x in interval.
Definition Intervals.hpp:332
Interval inv() const
Interval inverse.
Definition Intervals.hpp:179
zono_float width() const
Get width of interval.
Definition Intervals.hpp:235
Interval operator-(const Interval &other) const
Interval subtraction.
Definition Intervals.hpp:117
Interval operator/(const Interval &other) const
Interval division.
Definition Intervals.hpp:159
zono_float ub() const
Get upper bound.
Definition Intervals.hpp:87
zono_float center() const
Get center of interval.
Definition Intervals.hpp:226
Interval operator/(const zono_float alpha) const
Interval division with scalar.
Definition Intervals.hpp:170
Interval sin() const
Compute interval containing sin(x) for all x in interval.
Definition Intervals.hpp:314
bool is_empty() const
Checks whether interval is empty.
Definition Intervals.hpp:217
Interval nth_root(const int n) const
Interval nth root.
Definition Intervals.hpp:287
Interval cos() const
Compute interval containing cos(x) for all x in interval.
Definition Intervals.hpp:323
Interval operator+(const zono_float alpha) const
Interval addition with scalar.
Definition Intervals.hpp:107
Interval cosh() const
Compute interval containing cosh(x) for all x in interval.
Definition Intervals.hpp:377
Interval * clone() const
Clone Interval object.
Definition Intervals.hpp:68
bool contains(const zono_float x) const
Checks whether interval contains a value.
Definition Intervals.hpp:199
Interval(const zono_float y_min, const zono_float y_max)
Interval constructor.
Definition Intervals.hpp:62
Interval arccos() const
Compute interval containing arccos(x) for all x in interval.
Definition Intervals.hpp:350
Mixed-integer box.
Definition Intervals.hpp:766
Box * clone() const override
Clone operation.
Definition Intervals.cpp:415
MI_Box()=default
default constructor
bool contract_helper(const Eigen::SparseMatrix< zono_float, Eigen::RowMajor > &A, const Eigen::Vector< zono_float, -1 > &b, const int iter, const std::set< int > &constraints) override
Back-end for contractor.
Definition Intervals.cpp:441
const std::pair< int, int > & binary_indices() const
Get binary indices.
Definition Intervals.hpp:796
void project(Eigen::Ref< Eigen::Vector< zono_float, -1 > > x) const override
Projects vector onto the Box.
Definition Intervals.cpp:420
#define zono_float
Defines the floating-point type used in ZonoOpt.
Definition ZonoOpt.hpp:45
#define zono_eps
Defines the precision used for floating point comparisons in ZonoOpt.
Definition ZonoOpt.hpp:53
Definition ZonoOpt.hpp:58