ADORe
ADORe is a modular open source software library and toolkit for decision making, planning, control and simulation of automated vehicles
intervalarithmetic.h
Go to the documentation of this file.
1 /********************************************************************************
2  * Copyright (C) 2017-2020 German Aerospace Center (DLR).
3  * Eclipse ADORe, Automated Driving Open Research https://eclipse.org/adore
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License 2.0 which is available at
7  * http://www.eclipse.org/legal/epl-2.0.
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  * Daniel Heß - initial API and implementation
13  ********************************************************************************/
14 
15 #pragma once
16 #include <adore/mad/adoremath.h>
17 #include <algorithm>
18 
19 namespace adore
20 {
21  namespace mad
22  {
28  template<typename T>
29  struct interval
30  {
31  T lb, ub;
32  interval(T x0, T x1) :lb(adore::mad::min(x0, x1)), ub(adore::mad::max(x0, x1)) {}
33  interval(T x) :lb(x), ub(x) {}
34  interval() :lb((T)0), ub((T)0) {}
35 
36  void set(T lb, T ub) { this->lb = lb; this->ub = ub; }
37  void setMinMax(T x0, T x1){lb = (adore::mad::min)(x0, x1); ub = (adore::mad::max)(x0, x1);}
38 
39  interval<T>& operator+=(const interval<T>& rhs) { lb += rhs.lb; ub += rhs.ub; return *this; }
40  friend interval<T> operator+(interval<T> lhs, const interval<T>& rhs) { lhs += rhs; return lhs; }
41  interval<T>& operator-=(const interval<T>& rhs) { lb -= rhs.lb; ub -= rhs.ub; return *this; }
42  friend interval<T> operator-(interval<T> lhs, const interval<T>& rhs) { lhs -= rhs; return lhs; }
44  {
45  T a, b, c, d;
46  a = lb*rhs.lb;
47  b = lb*rhs.ub;
48  c = ub*rhs.lb;
49  d = ub*rhs.ub;
50  lb = (std::min)((std::min)(a, b), (std::min)(c, d));
51  ub = (std::max)((std::max)(a, b), (std::max)(c, d));
52  return *this;
53  }
54  friend interval<T> operator*(interval<T> lhs, const interval<T>& rhs) { lhs *= rhs; return lhs; }
56  {
57  return interval<T>(-ub, -lb);
58  }
59  };
60 
61  template<typename T>
62  std::ostream& operator<<(std::ostream& os, const interval<T>& obj)
63  {
64  os << '[' << obj.lb << ';' << obj.ub << ']';
65  return os;
66  }
67 
68  template<typename T> inline bool operator< (const interval<T>& lhs, const interval<T>& rhs) { return lhs.ub < rhs.lb; }//left is below right
69  template<typename T> inline bool operator> (const interval<T>& lhs, const interval<T>& rhs) { return rhs < lhs; }//left is above right
70  template<typename T> inline bool operator<=(const interval<T>& lhs, const interval<T>& rhs) { return lhs.ub <= rhs.lb; }//left is smug below right
71  template<typename T> inline bool operator>=(const interval<T>& lhs, const interval<T>& rhs) { return rhs <= lhs; }//left is smug above right
72  template<typename T> inline bool operator!=(const interval<T>& lhs, const interval<T>& rhs) { return rhs < lhs || lhs < rhs; }//non-intersect
73  template<typename T> inline bool operator==(const interval<T>& lhs, const interval<T>& rhs) { return lhs.lb == rhs.lb && lhs.ub == rhs.ub; }//equality
74 
78 
79  template<typename T, int N, int M>
80  adoreMatrix<interval<T>, N, M> create_interval(const adoreMatrix<T, N, M>& lb, const adoreMatrix<T, N, M>& ub)
81  {
82  adoreMatrix<interval<T>, N, M> result;
83  for (int i = 0; i < N; i++)
84  {
85  for (int j = 0; j < M; j++)
86  {
87  result(i, j) = interval<T>(lb(i, j), ub(i, j));
88  }
89  }
90  return result;
91  }
92 
93  template<typename T>
94  interval<T> create_interval(const T& lb, const T& ub)
95  {
96  return interval<T>(lb, ub);
97  }
98 
99  template<typename T, int N, int M>
100  adoreMatrix<T, N, M> lower_bound(const adoreMatrix<interval<T>, N, M>& data)
101  {
102  adoreMatrix<T, N, M> result;
103  for (int i = 0; i < N; i++)
104  {
105  for (int j = 0; j < M; j++)
106  {
107  result(i, j) = data(i, j).lb;
108  }
109  }
110  return result;
111  }
112 
113  template<typename T>
115  {
116  return iv.lb;
117  }
118 
119  template<typename T, int N, int M>
120  adoreMatrix<T, N, M> upper_bound(const adoreMatrix<interval<T>, N, M>& data)
121  {
122  adoreMatrix<T, N, M> result;
123  for (int i = 0; i < N; i++)
124  {
125  for (int j = 0; j < M; j++)
126  {
127  result(i, j) = data(i, j).ub;
128  }
129  }
130  return result;
131  }
132 
133  template<typename T>
135  {
136  return iv.ub;
137  }
138 
142  template<typename T, int N, int M, int K>
143  inline void imultiply(const adoreMatrix<T, N, M>& lba, const adoreMatrix<T, N, M>& uba, const adoreMatrix<T, M, K>& lbb, const adoreMatrix<T, M, K>& ubb, adoreMatrix<T, N, K>& lb, adoreMatrix<T, N, K>& ub)
144  {
145  adoreMatrix<interval<T>, N, M> a = create_interval<T, N, M>(lba, uba);
146  adoreMatrix<interval<T>, M, K> b = create_interval<T, M, K>(lbb, ubb);
147  adoreMatrix<interval<T>, N, K> c = a*b;
148  lb = lower_bound<T, N, K>(c);
149  ub = upper_bound<T, N, K>(c);
150  }
151 
155  template<typename T, long N>
156  inline void imultiply(const adoreMatrix<T, N, 1l>& lba, const adoreMatrix<T, N, 1l>& uba, const double& lbb,const double& ubb, adoreMatrix<T, N, 1l>& lb, adoreMatrix<T, N, 1l>& ub)
157  {
158  adoreMatrix<interval<T>, N,1> a = create_interval<T, N, 1>(lba, uba);
159  interval<double> b = create_interval<double>(lbb, ubb);
160  adoreMatrix<interval<T>, N, 1> c = a*b;
161  lb = lower_bound<T, N, 1>(c);
162  ub = upper_bound<T, N, 1>(c);
163  }
164 
168  template<typename T, int N, int M, int K>
169  inline void imultiply(const adoreMatrix<interval<T>, N, M>& a, const adoreMatrix<interval<T>, M, K>& b, adoreMatrix<T, N, K>& lb, adoreMatrix<T, N, K>& ub)
170  {
171  adoreMatrix<interval<T>, N, K> c = a*b;
172  lb = lower_bound<T, N, K>(c);
173  ub = upper_bound<T, N, K>(c);
174  }
175 
179  template<typename T>
180  inline void imultiply(const interval<T>& a, const interval<T>& b, T& lb, T& ub)
181  {
182  interval<T> c = a*b;
183  lb = lower_bound<T>(c);
184  ub = upper_bound<T>(c);
185  }
186 
190  inline void imultiply(const double& lba, const double& uba, const double& lbb, const double& ubb, double& lb, double& ub)
191  {
192  interval<double> a = create_interval<double>(lba, uba);
193  interval<double> b = create_interval<double>(lbb, ubb);
194  interval<double> c = a*b;
195  lb = lower_bound<double>(c);
196  ub = upper_bound<double>(c);
197  }
198 
199 
203  template<typename T>
205  {
206  if (x.ub - x.lb > 2.0*M_PI)return interval<T>(-1, 1);
207  T lb = adore::mad::remainder<T>(x.lb + M_PI_2, 2.0*M_PI) - M_PI_2;
208  T ub = x.ub - (x.lb - lb);
209 
210  //lb, ub in fourth and first quadrant? monotonous...
211  bool lb_q41 = -M_PI_2 <= lb && lb <= M_PI_2;
212  bool ub_q41 = -M_PI_2 <= ub && ub <= M_PI_2;
213  bool ub_q23 = M_PI_2 <= lb && lb <= M_PI + M_PI_2;
214 
215  if (lb_q41 && ub_q41)return interval<T>((std::sin)(lb), (std::sin)(ub));//both in q14: monotonous here
216  if (lb_q41)return interval<T>((std::min)((std::sin)(x.lb), (std::sin)(x.ub)), 1); //lb in q14 and ub in q23 -> +1 upper bound
217  if (ub_q23)return interval<T>((std::sin)(ub), (std::sin)(lb));//both in q23: -monotonous here
218  return interval<T>(-1, (std::max)((std::sin)(lb), (std::sin)(ub)));//lb in q23, ub in q45 -> -1 lower bound
219  }
220 
224  template<typename T>
226  {
227  return sin(x + interval<T>(M_PI_2));
228  }
229 
233  template<typename T>
235  {
236  //0,0 included
237  if (x.lb <= 0 && x.ub >= 0 && y.lb <= 0 && y.ub >= 0)return interval<T>(-M_PI, M_PI);
238  //fully included in quadrants
239  if (x.lb > 0 && y.lb >= 0) return interval<T>((std::atan2)(y.lb, x.ub), (std::atan2)(y.ub, x.lb));// I
240  if (x.ub <= 0 && y.lb > 0) return interval<T>((std::atan2)(y.ub, x.ub), (std::atan2)(y.lb, x.lb));// II
241  if (x.ub < 0 && y.ub <= 0) return interval<T>((std::atan2)(y.ub, x.lb), (std::atan2)(y.lb, x.ub));// III
242  if (x.lb >= 0 && y.ub < 0) return interval<T>((std::atan2)(y.lb, x.lb), (std::atan2)(y.ub, x.ub));// IV
243  //fully included in halfs
244  if (x.lb > 0) return interval<T>((std::atan2)(y.lb, x.lb), (std::atan2)(y.ub, x.lb));// IV-I
245  if (y.lb > 0) return interval<T>((std::atan2)(y.lb, x.ub), (std::atan2)(y.lb, x.lb));// I-II
246  if (x.ub < 0) return interval<T>((std::atan2)(y.ub, x.ub), (std::atan2)(y.lb, x.ub) + M_PI*(T)2);// II-III (incl. PI->-PI transition)
247  if (y.ub < 0) return interval<T>((std::atan2)(y.ub, x.lb), (std::atan2)(y.ub, x.ub));// III-IV
248  return interval<T>(-M_PI, M_PI);
249  }
250  }
251 }
#define adoreMatrix
Definition: adoremath.h:31
#define M_PI
Definition: arraymatrixtools.h:24
bool operator!=(const interval< T > &lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:72
interval< double > idouble
Definition: intervalarithmetic.h:75
interval< T > atan2(interval< T > y, interval< T > x)
Definition: intervalarithmetic.h:234
adoreMatrix< T, N, M > lower_bound(const adoreMatrix< interval< T >, N, M > &data)
Definition: intervalarithmetic.h:100
bool operator>(const interval< T > &lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:69
interval< T > cos(interval< T > x)
Definition: intervalarithmetic.h:225
interval< int > iint
Definition: intervalarithmetic.h:77
adoreMatrix< interval< T >, N, M > create_interval(const adoreMatrix< T, N, M > &lb, const adoreMatrix< T, N, M > &ub)
Definition: intervalarithmetic.h:80
bool operator<(const interval< T > &lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:68
std::ostream & operator<<(std::ostream &os, const interval< T > &obj)
Definition: intervalarithmetic.h:62
bool operator<=(const interval< T > &lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:70
bool operator>=(const interval< T > &lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:71
T min(T a, T b, T c, T d)
Definition: adoremath.h:663
interval< T > sin(interval< T > x)
Definition: intervalarithmetic.h:204
void imultiply(const adoreMatrix< T, N, M > &lba, const adoreMatrix< T, N, M > &uba, const adoreMatrix< T, M, K > &lbb, const adoreMatrix< T, M, K > &ubb, adoreMatrix< T, N, K > &lb, adoreMatrix< T, N, K > &ub)
Definition: intervalarithmetic.h:143
adoreMatrix< T, N, M > upper_bound(const adoreMatrix< interval< T >, N, M > &data)
Definition: intervalarithmetic.h:120
interval< float > ifloat
Definition: intervalarithmetic.h:76
adoreMatrix< T, N, M > max(adoreMatrix< T, N, M > a, const adoreMatrix< T, N, M > &b)
Definition: adoremath.h:686
bool operator==(const interval< T > &lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:73
x0
Definition: adore_set_goal.py:25
x
Definition: adore_set_goal.py:30
y
Definition: adore_set_goal.py:31
x1
Definition: adore_set_pose.py:28
Definition: areaofeffectconverter.h:20
Definition: intervalarithmetic.h:30
interval< T > & operator+=(const interval< T > &rhs)
Definition: intervalarithmetic.h:39
friend interval< T > operator*(interval< T > lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:54
interval< T > & operator-=(const interval< T > &rhs)
Definition: intervalarithmetic.h:41
interval()
Definition: intervalarithmetic.h:34
interval(T x0, T x1)
Definition: intervalarithmetic.h:32
interval(T x)
Definition: intervalarithmetic.h:33
void setMinMax(T x0, T x1)
Definition: intervalarithmetic.h:37
friend interval< T > operator-(interval< T > lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:42
interval< T > operator-()
Definition: intervalarithmetic.h:55
interval< T > & operator*=(const interval< T > &rhs)
Definition: intervalarithmetic.h:43
void set(T lb, T ub)
Definition: intervalarithmetic.h:36
T ub
Definition: intervalarithmetic.h:31
friend interval< T > operator+(interval< T > lhs, const interval< T > &rhs)
Definition: intervalarithmetic.h:40
T lb
Definition: intervalarithmetic.h:31