codac 1.5.6
Loading...
Searching...
No Matches
codac2_IntervalVector.h
Go to the documentation of this file.
1
17#ifndef __CODAC2_INTERVALVECTOR_H__
18#define __CODAC2_INTERVALVECTOR_H__
19
20#include <list>
21#include <type_traits>
22#include <codac_Interval.h>
24#include <ibex_LargestFirst.h>
25#include "codac2_Interval.h"
27#include "codac2_Vector.h"
28#include <codac2_eigen.h>
29
30namespace codac2
31{
32 template<int N>
33 class Vector_;
34
35 using Eigen::Dynamic;
36
37 template<int N=Dynamic>
38 class IntervalVector_ : public IntervalMatrix_<N,1>
39 {
40 public:
41
42 IntervalVector_()
43 : IntervalMatrix_<N,1>()
44 { }
45
46 explicit IntervalVector_(size_t n)
47 : IntervalMatrix_<N,1>(n,1)
48 {
49 assert(N == Dynamic || N == (int)n);
50 }
51
52 explicit IntervalVector_(size_t n, const Interval& x)
53 : IntervalMatrix_<N,1>(n,1,x)
54 {
55 assert(N == Dynamic || N == (int)n);
56 }
57
58 explicit IntervalVector_(const Interval& x)
59 : IntervalMatrix_<N,1>(N,1,x)
60 { }
61
62 template<int M>
63 explicit IntervalVector_(const Matrix_<M,1>& v)
64 : IntervalMatrix_<N,1>(v.size(),1)
65 {
66 static_assert(N == M || N == -1 || M == -1);
67 for(size_t i = 0 ; i < IntervalMatrix_<N,1>::size() ; i++)
68 (*this)[i] = Interval(v[i]);
69 }
70
71 explicit IntervalVector_(size_t n, const double bounds[][2])
72 : IntervalMatrix_<N,1>(n,1,bounds)
73 { }
74
75 explicit IntervalVector_(const double bounds[][2])
76 : IntervalVector_(this->size(), bounds)
77 { }
78
79 explicit IntervalVector_(const Vector_<N>& lb, const Vector_<N>& ub)
80 : IntervalMatrix_<N,1>(lb, ub)
81 { }
82
83 IntervalVector_(std::initializer_list<Interval> l)
84 : IntervalMatrix_<N,1>(l.size(),1)
85 {
86 assert(N == Dynamic || (int)l.size() == N);
87 size_t i = 0;
88 for(const auto& li : l)
89 (*this)[i++] = li;
90 // todo: use thias as faster? std::copy(l.begin(), l.end(), vec);
91 }
92
93 template<int M>
94 explicit IntervalVector_(const IntervalMatrix_<M,1>& x)
95 : IntervalMatrix_<M,1>(x)
96 {
97 assert(M == Dynamic || M == N);
98 }
99
100 // This constructor allows you to construct IntervalVector_ from Eigen expressions
101 template<typename OtherDerived>
102 IntervalVector_(const Eigen::MatrixBase<OtherDerived>& other)
103 : IntervalMatrix_<N,1>(other)
104 { }
105
106 // This method allows you to assign Eigen expressions to IntervalVector_
107 template<typename OtherDerived>
108 IntervalVector_& operator=(const Eigen::MatrixBase<OtherDerived>& other)
109 {
110 this->IntervalMatrix_<N,1>::operator=(other);
111 return *this;
112 }
113
114 void resize(size_t n)
115 {
116 this->IntervalMatrix_<N,1>::resize(n,1);
117 }
118
119 template<size_t N1,size_t N2>
120 IntervalVector_<N2-N1+1> subvector() const
121 {
122 assert(N1 >= 0 && N1 < N && N2 >= 0 && N2 < N && N1 <= N2);
123 return this->template block<N2-N1+1,1>(N1,0);
124 }
125
126 IntervalVector_<> subvector(size_t start_index, size_t end_index) const
127 {
128 assert(end_index >= 0 && start_index >= 0);
129 assert(end_index < this->size() && start_index <= end_index);
130
131 IntervalVector_<> s(end_index-start_index+1);
132 for(size_t i = 0 ; i < s.size() ; i++)
133 s[i] = (*this)[i+start_index];
134 return s;
135 }
136
137 template<size_t I,int M>
138 void put(const IntervalVector_<M>& x)
139 {
140 assert(I >= 0 && I < N && M+I <= N);
141 this->template block<M,1>(I,0) << x;
142 }
143
144 auto& operator+=(const IntervalVector_<N>& x)
145 {
146 (*this).noalias() += x;//.template cast<Interval>();
147 return *this;
148 }
149
150 auto& operator-=(const IntervalVector_<N>& x)
151 {
152 (*this).noalias() -= x;//.template cast<Interval>();
153 return *this;
154 }
155
156 std::list<IntervalVector_<N>> complementary() const
157 {
158 return IntervalVector_<N>(this->size()).diff(*this);
159 }
160
161 std::list<IntervalVector_<N>> diff(const IntervalVector_<N>& y, bool compactness = true) const
162 {
163 // This code originates from the ibex-lib
164 // See: ibex_TemplateVector.h
165 // Author: Gilles Chabert
166 // It has been revised with modern C++ and templated types
167
168 const size_t n = this->size();
169 assert(y.size() == n);
170
171 if(y == *this)
172 return { IntervalVector_<N>::empty_set(n) };
173
174 IntervalVector_<N> x = *this;
175 IntervalVector_<N> z = x & y;
176
177 if(z.is_empty())
178 return { x };
179
180 else
181 {
182 // Check if in one dimension y is flat and x not,
183 // in which case the diff returns also x directly
184 if(compactness)
185 for(size_t i = 0 ; i < n ; i++)
186 if(z[i].is_degenerated() && !x[i].is_degenerated())
187 return { x };
188 }
189
190 std::list<IntervalVector_<N>> l;
191
192 for(size_t var = 0 ; var < n ; var++)
193 {
194 Interval c1, c2;
195 x[var].diff(y[var], c1, c2, compactness);
196
197 if(!c1.is_empty())
198 {
199 IntervalVector_<N> v(n);
200 for(size_t i = 0 ; i < var ; i++)
201 v[i] = x[i];
202 v[var] = c1;
203 for(size_t i = var+1 ; i < n ; i++)
204 v[i] = x[i];
205 l.push_back(v);
206
207 if(!c2.is_empty())
208 {
209 IntervalVector_<N> w(n);
210 for(size_t i = 0 ; i < var ; i++)
211 w[i] = x[i];
212 w[var] = c2;
213 for(size_t i = var+1 ; i<n ; i++)
214 w[i] = x[i];
215 l.push_back(w);
216 }
217
218 x[var] = z[var];
219 }
220 }
221
222 return l;
223 }
224 };
225
226 template<int N>
227 std::ostream& operator<<(std::ostream& os, const IntervalVector_<N>& x)
228 {
229 if(x.is_empty()) return os << "empty vector";
230 os << "(";
231 for(size_t i = 0 ; i < x.size() ; i++)
232 os << x[i] << (i<x.size()-1 ? " ; " : "");
233 os << ")";
234 return os;
235 }
236
237 template<int N>
238 codac::IntervalVector to_codac1(const IntervalVector_<N>& x)
239 {
240 ibex::IntervalVector x_(x.size());
241 for(size_t i = 0 ; i < x.size() ; i++)
242 x_[i] = x[i];
243 return x_;
244 }
245
246 template<int N>
247 IntervalVector_<N> to_codac2(const codac::IntervalVector& x)
248 {
249 assert(x.size() == N);
250 IntervalVector_<N> x_(x.size());
251 for(size_t i = 0 ; i < x.size() ; i++)
252 x_[i] = x[i];
253 return x_;
254 }
255
256 class IntervalVector : public IntervalVector_<>
257 {
258 public:
259
260 explicit IntervalVector(size_t n)
261 : IntervalVector_<>(n)
262 { }
263
264 explicit IntervalVector(size_t n, const Interval& x)
265 : IntervalVector_<>(n, x)
266 { }
267
268 explicit IntervalVector(const Interval& x)
269 : IntervalVector_<>({x})
270 { }
271
272 explicit IntervalVector(const IntervalVector_<>& x)
273 : IntervalVector_<>(x)
274 { }
275
276 template<int N>
277 explicit IntervalVector(const Vector_<N>& v)
278 : IntervalVector_<>(v)
279 { }
280
281 explicit IntervalVector(size_t n, const double bounds[][2])
282 : IntervalVector_<>(n, bounds)
283 { }
284
285 IntervalVector(std::initializer_list<Interval> l)
286 : IntervalVector_<>(l)
287 { }
288
289 // This constructor allows you to construct IntervalVector from Eigen expressions
290 template<typename OtherDerived>
291 IntervalVector(const Eigen::MatrixBase<OtherDerived>& other)
292 : IntervalVector_<>(other)
293 { }
294
295 // This method allows you to assign Eigen expressions to IntervalVector
296 template<typename OtherDerived>
297 IntervalVector& operator=(const Eigen::MatrixBase<OtherDerived>& other)
298 {
299 this->IntervalVector_<>::operator=(other);
300 return *this;
301 }
302
303 void resize(size_t n)
304 {
305 this->IntervalVector_<>::resize(n);
306 }
307
308 static IntervalVector empty_set(size_t n)
309 {
310 return IntervalMatrix_<>::empty_set(n,1);
311 }
312 };
313
314} // namespace codac
315
316#endif