codac 2.0.0
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, const X2& s2) {
62 auto shape1=s1->output_shape();
63 assert_release(shape1 == s2->output_shape());
64 return shape1;
65 }
66
67 static Interval fwd(const Interval& x1, const Interval& x2);
68 static ScalarType fwd_natural(const ScalarType& x1, const ScalarType& x2);
69 static ScalarType fwd_centered(const ScalarType& x1, const ScalarType& x2);
70 static void bwd(const Interval& y, Interval& x1, Interval& x2);
71
72 static IntervalVector fwd(const IntervalVector& x1, const IntervalVector& x2);
73 static VectorType fwd_natural(const VectorType& x1, const VectorType& x2);
74 static VectorType fwd_centered(const VectorType& x1, const VectorType& x2);
75 static void bwd(const IntervalVector& y, IntervalVector& x1, IntervalVector& x2);
76
77 static IntervalMatrix fwd(const IntervalMatrix& x1, const IntervalMatrix& x2);
78 static MatrixType fwd_natural(const MatrixType& x1, const MatrixType& x2);
79 static MatrixType fwd_centered(const MatrixType& x1, const MatrixType& x2);
80 static void bwd(const IntervalMatrix& y, IntervalMatrix& x1, IntervalMatrix& x2);
81 };
82
83 // operator+ (unary case)
84 // The following functions can be used to build analytic expressions.
85
86 inline ScalarExpr
87 operator+(const ScalarExpr& x1)
88 {
89 return { std::make_shared<AnalyticOperationExpr<AddOp,ScalarType,ScalarType>>(x1) };
90 }
91
92 inline VectorExpr
93 operator+(const VectorExpr& x1)
94 {
95 return { std::make_shared<AnalyticOperationExpr<AddOp,VectorType,VectorType>>(x1) };
96 }
97
98 inline MatrixExpr
99 operator+(const MatrixExpr& x1)
100 {
101 return { std::make_shared<AnalyticOperationExpr<AddOp,MatrixType,MatrixType>>(x1) };
102 }
103
104
105 // operator+
106 // The following functions can be used to build analytic expressions.
107
108 inline ScalarExpr
109 operator+(ScalarExpr x1, ScalarExpr x2)
110 {
111 return { std::make_shared<AnalyticOperationExpr<AddOp,ScalarType,ScalarType,ScalarType>>(x1,x2) };
112 }
113
114 inline VectorExpr
115 operator+(VectorExpr x1, VectorExpr x2)
116 {
117 return { std::make_shared<AnalyticOperationExpr<AddOp,VectorType,VectorType,VectorType>>(x1,x2) };
118 }
119
120 inline MatrixExpr
121 operator+(MatrixExpr x1, MatrixExpr x2)
122 {
123 return { std::make_shared<AnalyticOperationExpr<AddOp,MatrixType,MatrixType,MatrixType>>(x1,x2) };
124 }
125
126 // Inline functions
127
128 inline Interval AddOp::fwd(const Interval& x1)
129 {
130 return x1;
131 }
132
133 inline ScalarType AddOp::fwd_natural(const ScalarType& x1)
134 {
135 return {
136 fwd(x1.a),
137 x1.def_domain
138 };
139 }
140
141 inline ScalarType AddOp::fwd_centered(const ScalarType& x1)
142 {
143 return {
144 fwd(x1.m),
145 fwd(x1.a),
146 x1.da,
147 x1.def_domain
148 };
149 }
150
151 inline void AddOp::bwd([[maybe_unused]] const Interval& y, [[maybe_unused]] Interval& x1)
152 { }
153
154 inline std::pair<Index,Index> AddOp::output_shape([[maybe_unused]] const std::pair<Index,Index>& s1)
155 {
156 return s1;
157 }
158
159 inline IntervalVector AddOp::fwd(const IntervalVector& x1)
160 {
161 return x1;
162 }
163
164 inline VectorType AddOp::fwd_natural(const VectorType& x1)
165 {
166 return {
167 fwd(x1.a),
168 x1.def_domain
169 };
170 }
171
172 inline VectorType AddOp::fwd_centered(const VectorType& x1)
173 {
174 return {
175 fwd(x1.m),
176 fwd(x1.a),
177 x1.da,
178 x1.def_domain
179 };
180 }
181
182 inline void AddOp::bwd([[maybe_unused]] const IntervalVector& y, [[maybe_unused]] IntervalVector& x1)
183 {
184 assert(y.size() == x1.size());
185 }
186
187 inline IntervalMatrix AddOp::fwd(const IntervalMatrix& x1)
188 {
189 return x1;
190 }
191
192 inline MatrixType AddOp::fwd_natural(const MatrixType& x1)
193 {
194 return {
195 fwd(x1.a),
196 x1.def_domain
197 };
198 }
199
200 inline MatrixType AddOp::fwd_centered(const MatrixType& x1)
201 {
202 if(centered_form_not_available_for_args(x1))
203 return fwd_natural(x1);
204
205 return {
206 fwd(x1.m),
207 fwd(x1.a),
208 x1.da, // unary plus
209 x1.def_domain
210 };
211 }
212
213 inline void AddOp::bwd([[maybe_unused]] const IntervalMatrix& y, [[maybe_unused]] IntervalMatrix& x1)
214 {
215 assert(y.size() == x1.size());
216 }
217
218 inline Interval AddOp::fwd(const Interval& x1, const Interval& x2)
219 {
220 return x1 + x2;
221 }
222
223 inline ScalarType AddOp::fwd_natural(const ScalarType& x1, const ScalarType& x2)
224 {
225 return {
226 fwd(x1.a, x2.a),
227 x1.def_domain && x2.def_domain
228 };
229 }
230
231 inline ScalarType AddOp::fwd_centered(const ScalarType& x1, const ScalarType& x2)
232 {
233 if(centered_form_not_available_for_args(x1,x2))
234 return fwd_natural(x1,x2);
235
236 assert(x1.da.size() == x2.da.size());
237 return {
238 fwd(x1.m, x2.m),
239 fwd(x1.a, x2.a),
240 x1.da + x2.da,
241 x1.def_domain && x2.def_domain
242 };
243 }
244
245 inline void AddOp::bwd(const Interval& y, Interval& x1, Interval& x2)
246 {
247 if((x1 &= y-x2).is_empty())
248 x2.set_empty();
249
250 else if((x2 &= y-x1).is_empty())
251 x1.set_empty();
252 }
253
254 inline IntervalVector AddOp::fwd(const IntervalVector& x1, const IntervalVector& x2)
255 {
256 assert(x1.size() == x2.size());
257 return x1 + x2;
258 }
259
260 inline VectorType AddOp::fwd_natural(const VectorType& x1, const VectorType& x2)
261 {
262 return {
263 fwd(x1.a, x2.a),
264 x1.def_domain && x2.def_domain
265 };
266 }
267
268 inline VectorType AddOp::fwd_centered(const VectorType& x1, const VectorType& x2)
269 {
270 if(centered_form_not_available_for_args(x1,x2))
271 return fwd_natural(x1,x2);
272
273 assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols());
274 return {
275 fwd(x1.m, x2.m),
276 fwd(x1.a, x2.a),
277 x1.da + x2.da,
278 x1.def_domain && x2.def_domain
279 };
280 }
281
282 inline void AddOp::bwd(const IntervalVector& y, IntervalVector& x1, IntervalVector& x2)
283 {
284 assert(y.size() == x1.size() && y.size() == x2.size());
285 for(Index i = 0 ; i < y.size() ; i++)
286 AddOp::bwd(y[i], x1[i], x2[i]);
287 }
288
289 inline IntervalMatrix AddOp::fwd(const IntervalMatrix& x1, const IntervalMatrix& x2)
290 {
291 assert(x1.cols() == x2.cols() && x1.rows() == x2.rows());
292 return x1 + x2;
293 }
294
295 inline MatrixType AddOp::fwd_natural(const MatrixType& x1, const MatrixType& x2)
296 {
297 return {
298 fwd(x1.a, x2.a),
299 x1.def_domain && x2.def_domain
300 };
301 }
302
303 inline MatrixType AddOp::fwd_centered(const MatrixType& x1, const MatrixType& x2)
304 {
305 if(centered_form_not_available_for_args(x1,x2))
306 return fwd_natural(x1,x2);
307
308 return {
309 fwd(x1.m, x2.m),
310 fwd(x1.a, x2.a),
311 x1.da + x2.da,
312 x1.def_domain && x2.def_domain
313 };
314 }
315
316 inline void AddOp::bwd(const IntervalMatrix& y, IntervalMatrix& x1, IntervalMatrix& x2)
317 {
318 assert(y.cols() == x1.cols() && y.rows() == x1.rows()
319 && y.cols() == x2.cols() && y.rows() == x2.rows());
320 for(Index i = 0 ; i < y.size() ; i++)
321 AddOp::bwd(*(y.data()+i), *(x1.data()+i), *(x2.data()+i));
322 }
323}
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.