codac 1.5.6
Loading...
Searching...
No Matches
codac2_arith_add.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Interval.h"
15#include "codac2_AnalyticType.h"
17
18namespace codac2
19{
20 struct AddOp
21 {
22 // Unary operations
23
24 template<typename X1>
25 static std::string str(const X1& x1)
26 {
27 return x1->str();
28 }
29
30 template<typename X1>
31 static std::pair<Index,Index> output_shape(const X1& s1) {
32 return s1->output_shape();
33 }
34
35 static Interval fwd(const Interval& x1);
36 static ScalarType fwd_natural(const ScalarType& x1);
37 static ScalarType fwd_centered(const ScalarType& x1);
38 static void bwd(const Interval& y, Interval& x1);
39
40 static IntervalVector fwd(const IntervalVector& x1);
41 static VectorType fwd_natural(const VectorType& x1);
42 static VectorType fwd_centered(const VectorType& x1);
43 static void bwd(const IntervalVector& y, IntervalVector& x1);
44
45 static IntervalMatrix fwd(const IntervalMatrix& x1);
46 static MatrixType fwd_natural(const MatrixType& x1);
47 static MatrixType fwd_centered(const MatrixType& x1);
48 static void bwd(const IntervalMatrix& y, IntervalMatrix& x1);
49
50 static std::pair<Index,Index> output_shape(const std::pair<Index,Index> &s1);
51
52 // Binary operations
53
54 template<typename X1,typename X2>
55 static std::string str(const X1& x1, const X2& x2)
56 {
57 return x1->str() + "+" + x2->str();
58 }
59
60 template<typename X1, typename X2>
61 static std::pair<Index,Index> output_shape(const X1& s1, [[maybe_unused]] const X2& s2)
62 {
63 auto shape1 = s1->output_shape();
64 assert(shape1 == s2->output_shape());
65 return shape1;
66 }
67
68 static Interval fwd(const Interval& x1, const Interval& x2);
69 static ScalarType fwd_natural(const ScalarType& x1, const ScalarType& x2);
70 static ScalarType fwd_centered(const ScalarType& x1, const ScalarType& x2);
71 static void bwd(const Interval& y, Interval& x1, Interval& x2);
72
73 static IntervalVector fwd(const IntervalVector& x1, const IntervalVector& x2);
74 static VectorType fwd_natural(const VectorType& x1, const VectorType& x2);
75 static VectorType fwd_centered(const VectorType& x1, const VectorType& x2);
76 static void bwd(const IntervalVector& y, IntervalVector& x1, IntervalVector& x2);
77
78 static IntervalMatrix fwd(const IntervalMatrix& x1, const IntervalMatrix& x2);
79 static MatrixType fwd_natural(const MatrixType& x1, const MatrixType& x2);
80 static MatrixType fwd_centered(const MatrixType& x1, const MatrixType& x2);
81 static void bwd(const IntervalMatrix& y, IntervalMatrix& x1, IntervalMatrix& x2);
82 };
83
84 // operator+ (unary case)
85 // The following functions can be used to build analytic expressions.
86
87 inline ScalarExpr
88 operator+(const ScalarExpr& x1)
89 {
90 return { std::make_shared<AnalyticOperationExpr<AddOp,ScalarType,ScalarType>>(x1) };
91 }
92
93 inline VectorExpr
94 operator+(const VectorExpr& x1)
95 {
96 return { std::make_shared<AnalyticOperationExpr<AddOp,VectorType,VectorType>>(x1) };
97 }
98
99 inline MatrixExpr
100 operator+(const MatrixExpr& x1)
101 {
102 return { std::make_shared<AnalyticOperationExpr<AddOp,MatrixType,MatrixType>>(x1) };
103 }
104
105
106 // operator+
107 // The following functions can be used to build analytic expressions.
108
109 inline ScalarExpr
110 operator+(ScalarExpr x1, ScalarExpr x2)
111 {
112 return { std::make_shared<AnalyticOperationExpr<AddOp,ScalarType,ScalarType,ScalarType>>(x1,x2) };
113 }
114
115 inline VectorExpr
116 operator+(VectorExpr x1, VectorExpr x2)
117 {
118 return { std::make_shared<AnalyticOperationExpr<AddOp,VectorType,VectorType,VectorType>>(x1,x2) };
119 }
120
121 inline MatrixExpr
122 operator+(MatrixExpr x1, MatrixExpr x2)
123 {
124 return { std::make_shared<AnalyticOperationExpr<AddOp,MatrixType,MatrixType,MatrixType>>(x1,x2) };
125 }
126
127 // Inline functions
128
129 inline Interval AddOp::fwd(const Interval& x1)
130 {
131 return x1;
132 }
133
134 inline ScalarType AddOp::fwd_natural(const ScalarType& x1)
135 {
136 return {
137 fwd(x1.a),
138 x1.def_domain
139 };
140 }
141
142 inline ScalarType AddOp::fwd_centered(const ScalarType& x1)
143 {
144 return {
145 fwd(x1.m),
146 fwd(x1.a),
147 x1.da,
148 x1.def_domain
149 };
150 }
151
152 inline void AddOp::bwd([[maybe_unused]] const Interval& y, [[maybe_unused]] Interval& x1)
153 { }
154
155 inline std::pair<Index,Index> AddOp::output_shape([[maybe_unused]] const std::pair<Index,Index>& s1)
156 {
157 return s1;
158 }
159
160 inline IntervalVector AddOp::fwd(const IntervalVector& x1)
161 {
162 return x1;
163 }
164
165 inline VectorType AddOp::fwd_natural(const VectorType& x1)
166 {
167 return {
168 fwd(x1.a),
169 x1.def_domain
170 };
171 }
172
173 inline VectorType AddOp::fwd_centered(const VectorType& x1)
174 {
175 return {
176 fwd(x1.m),
177 fwd(x1.a),
178 x1.da,
179 x1.def_domain
180 };
181 }
182
183 inline void AddOp::bwd([[maybe_unused]] const IntervalVector& y, [[maybe_unused]] IntervalVector& x1)
184 {
185 assert(y.size() == x1.size());
186 }
187
188 inline IntervalMatrix AddOp::fwd(const IntervalMatrix& x1)
189 {
190 return x1;
191 }
192
193 inline MatrixType AddOp::fwd_natural(const MatrixType& x1)
194 {
195 return {
196 fwd(x1.a),
197 x1.def_domain
198 };
199 }
200
201 inline MatrixType AddOp::fwd_centered(const MatrixType& x1)
202 {
203 if(centered_form_not_available_for_args(x1))
204 return fwd_natural(x1);
205
206 return {
207 fwd(x1.m),
208 fwd(x1.a),
209 x1.da, // unary plus
210 x1.def_domain
211 };
212 }
213
214 inline void AddOp::bwd([[maybe_unused]] const IntervalMatrix& y, [[maybe_unused]] IntervalMatrix& x1)
215 {
216 assert(y.size() == x1.size());
217 }
218
219 inline Interval AddOp::fwd(const Interval& x1, const Interval& x2)
220 {
221 return x1 + x2;
222 }
223
224 inline ScalarType AddOp::fwd_natural(const ScalarType& x1, const ScalarType& x2)
225 {
226 return {
227 fwd(x1.a, x2.a),
228 x1.def_domain && x2.def_domain
229 };
230 }
231
232 inline ScalarType AddOp::fwd_centered(const ScalarType& x1, const ScalarType& x2)
233 {
234 if(centered_form_not_available_for_args(x1,x2))
235 return fwd_natural(x1,x2);
236
237 assert(x1.da.size() == x2.da.size());
238 return {
239 fwd(x1.m, x2.m),
240 fwd(x1.a, x2.a),
241 x1.da + x2.da,
242 x1.def_domain && x2.def_domain
243 };
244 }
245
246 inline void AddOp::bwd(const Interval& y, Interval& x1, Interval& x2)
247 {
248 if((x1 &= y-x2).is_empty())
249 x2.set_empty();
250
251 else if((x2 &= y-x1).is_empty())
252 x1.set_empty();
253 }
254
255 inline IntervalVector AddOp::fwd(const IntervalVector& x1, const IntervalVector& x2)
256 {
257 assert(x1.size() == x2.size());
258 return x1 + x2;
259 }
260
261 inline VectorType AddOp::fwd_natural(const VectorType& x1, const VectorType& x2)
262 {
263 return {
264 fwd(x1.a, x2.a),
265 x1.def_domain && x2.def_domain
266 };
267 }
268
269 inline VectorType AddOp::fwd_centered(const VectorType& x1, const VectorType& x2)
270 {
271 if(centered_form_not_available_for_args(x1,x2))
272 return fwd_natural(x1,x2);
273
274 assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols());
275 return {
276 fwd(x1.m, x2.m),
277 fwd(x1.a, x2.a),
278 x1.da + x2.da,
279 x1.def_domain && x2.def_domain
280 };
281 }
282
283 inline void AddOp::bwd(const IntervalVector& y, IntervalVector& x1, IntervalVector& x2)
284 {
285 assert(y.size() == x1.size() && y.size() == x2.size());
286 for(Index i = 0 ; i < y.size() ; i++)
287 AddOp::bwd(y[i], x1[i], x2[i]);
288 }
289
290 inline IntervalMatrix AddOp::fwd(const IntervalMatrix& x1, const IntervalMatrix& x2)
291 {
292 assert(x1.cols() == x2.cols() && x1.rows() == x2.rows());
293 return x1 + x2;
294 }
295
296 inline MatrixType AddOp::fwd_natural(const MatrixType& x1, const MatrixType& x2)
297 {
298 return {
299 fwd(x1.a, x2.a),
300 x1.def_domain && x2.def_domain
301 };
302 }
303
304 inline MatrixType AddOp::fwd_centered(const MatrixType& x1, const MatrixType& x2)
305 {
306 if(centered_form_not_available_for_args(x1,x2))
307 return fwd_natural(x1,x2);
308
309 return {
310 fwd(x1.m, x2.m),
311 fwd(x1.a, x2.a),
312 x1.da + x2.da,
313 x1.def_domain && x2.def_domain
314 };
315 }
316
317 inline void AddOp::bwd(const IntervalMatrix& y, IntervalMatrix& x1, IntervalMatrix& x2)
318 {
319 assert(y.cols() == x1.cols() && y.rows() == x1.rows()
320 && y.cols() == x2.cols() && y.rows() == x2.rows());
321 for(Index i = 0 ; i < y.size() ; i++)
322 AddOp::bwd(*(y.data()+i), *(x1.data()+i), *(x2.data()+i));
323 }
324}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:62
Ellipsoid operator+(const Ellipsoid &e1, const Ellipsoid &e2)
Compute the Minkowski sum of two ellipsoids.