codac  1.5.7
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>
23 #include <codac_IntervalVector.h>
24 #include <ibex_LargestFirst.h>
25 #include "codac2_Interval.h"
26 #include "codac2_IntervalMatrix.h"
27 #include "codac2_Vector.h"
28 #include <codac2_eigen.h>
29 
30 namespace 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