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