codac 2.0.0
Loading...
Searching...
No Matches
codac2_arith_mul.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Interval.h"
14#include "codac2_IntervalRow.h"
16#include "codac2_AnalyticType.h"
18#include "codac2_arith_add.h"
19
20#include "codac2_linear_ctc.h"
21#include "codac2_GaussJordan.h"
22
23namespace codac2
24{
25 struct MulOp
26 {
27 template<typename X1,typename X2>
28 static std::string str(const X1& x1, const X2& x2)
29 {
30 return x1->str(!x1->is_str_leaf()) + "*" + x2->str(!x2->is_str_leaf());
31 }
32
33 template<typename X1, typename X2>
34 static std::pair<Index,Index> output_shape(const X1& s1, const X2& s2)
35 {
36 auto shape1=s1->output_shape();
37 auto shape2=s2->output_shape();
38 if (shape1.first==1 && shape1.second==1) {
39 return shape2;
40 } else if (shape2.first==1 && shape2.second==1) {
41 return shape1;
42 } else {
43 assert_release(shape1.second==shape2.first);
44 return std::pair(shape1.first, shape2.second);
45 }
46 }
47
48 static Interval fwd(const Interval& x1, const Interval& x2);
49 static ScalarType fwd_natural(const ScalarType& x1, const ScalarType& x2);
50 static ScalarType fwd_centered(const ScalarType& x1, const ScalarType& x2);
51 static void bwd(const Interval& y, Interval& x1, Interval& x2);
52
53 static IntervalVector fwd(const Interval& x1, const IntervalVector& x2);
54 static VectorType fwd_natural(const ScalarType& x1, const VectorType& x2);
55 static VectorType fwd_centered(const ScalarType& x1, const VectorType& x2);
56 static void bwd(const IntervalVector& y, Interval& x1, IntervalVector& x2);
57
58 static IntervalVector fwd(const IntervalVector& x1, const Interval& x2);
59 static VectorType fwd_natural(const VectorType& x1, const ScalarType& x2);
60 static VectorType fwd_centered(const VectorType& x1, const ScalarType& x2);
61 static void bwd(const IntervalVector& y, IntervalVector& x1, Interval& x2);
62
63 static Interval fwd(const IntervalRow& x1, const IntervalVector& x2);
64 //static ScalarType fwd(const RowType& x1, const VectorType& x2); // RowType not yet defined
65 static void bwd(const Interval& y, IntervalRow& x1, IntervalVector& x2);
66
67 static IntervalMatrix fwd(const Interval& x1, const IntervalMatrix& x2);
68 static MatrixType fwd_natural(const ScalarType& x1, const MatrixType& x2);
69 static MatrixType fwd_centered(const ScalarType& x1, const MatrixType& x2);
70 static void bwd(const IntervalMatrix& y, Interval& x1, IntervalMatrix& x2);
71
72 static IntervalVector fwd(const IntervalMatrix& x1, const IntervalVector& x2);
73 static VectorType fwd_natural(const MatrixType& x1, const VectorType& x2);
74 static VectorType fwd_centered(const MatrixType& x1, const VectorType& x2);
75 static void bwd(const IntervalVector& y, IntervalMatrix& 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*
84 // The following functions can be used to build analytic expressions.
85
86 inline ScalarExpr
87 operator*(const ScalarExpr& x1, const ScalarExpr& x2)
88 {
89 return { std::make_shared<AnalyticOperationExpr<MulOp,ScalarType,ScalarType,ScalarType>>(x1,x2) };
90 }
91
92 inline VectorExpr
93 operator*(const ScalarExpr& x1, const VectorExpr& x2)
94 {
95 return { std::make_shared<AnalyticOperationExpr<MulOp,VectorType,ScalarType,VectorType>>(x1,x2) };
96 }
97
98 inline VectorExpr
99 operator*(const VectorExpr& x1, const ScalarExpr& x2)
100 {
101 return { std::make_shared<AnalyticOperationExpr<MulOp,VectorType,VectorType,ScalarType>>(x1,x2) };
102 }
103
104 inline MatrixExpr
105 operator*(const ScalarExpr& x1, const MatrixExpr& x2)
106 {
107 return { std::make_shared<AnalyticOperationExpr<MulOp,MatrixType,ScalarType,MatrixType>>(x1,x2) };
108 }
109
110 inline VectorExpr
111 operator*(const MatrixExpr& x1, const VectorExpr& x2)
112 {
113 return { std::make_shared<AnalyticOperationExpr<MulOp,VectorType,MatrixType,VectorType>>(x1,x2) };
114 }
115
116 inline MatrixExpr
117 operator*(const MatrixExpr& x1, const MatrixExpr& x2)
118 {
119 return { std::make_shared<AnalyticOperationExpr<MulOp,MatrixType,MatrixType,MatrixType>>(x1,x2) };
120 }
121
122 // Inline functions
123
124 inline Interval MulOp::fwd(const Interval& x1, const Interval& x2)
125 {
126 return x1 * x2;
127 }
128
129 inline ScalarType MulOp::fwd_natural(const ScalarType& x1, const ScalarType& x2)
130 {
131 return {
132 fwd(x1.a, x2.a),
133 x1.def_domain && x2.def_domain
134 };
135 }
136
137 inline ScalarType MulOp::fwd_centered(const ScalarType& x1, const ScalarType& x2)
138 {
139 if(centered_form_not_available_for_args(x1,x2))
140 return fwd_natural(x1,x2);
141
142 assert(x1.da.rows() == 1);
143 assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols());
144
145 IntervalMatrix d(1,x1.da.cols());
146 for(Index i = 0 ; i < d.size() ; i++)
147 d(0,i) = x1.da(0,i)*x2.a + x1.a*x2.da(0,i);
148
149 return {
150 fwd(x1.m, x2.m),
151 fwd(x1.a, x2.a),
152 d,
153 x1.def_domain && x2.def_domain
154 };
155 }
156
157 inline void MulOp::bwd(const Interval& y, Interval& x1, Interval& x2)
158 {
159 x1 = gaol::div_rel(y, x2, x1);
160 x2 = gaol::div_rel(y, x1, x2);
161 }
162
163 inline IntervalVector MulOp::fwd(const Interval& x1, const IntervalVector& x2)
164 {
165 return x1 * x2;
166 }
167
168 inline VectorType MulOp::fwd_natural(const ScalarType& x1, const VectorType& x2)
169 {
170 return {
171 fwd(x1.a, x2.a),
172 x1.def_domain && x2.def_domain
173 };
174 }
175
176 inline VectorType MulOp::fwd_centered(const ScalarType& x1, const VectorType& x2)
177 {
178 if(centered_form_not_available_for_args(x1,x2))
179 return fwd_natural(x1,x2);
180
181 assert(x1.da.rows() == 1);
182 assert(x1.da.cols() == x2.da.cols());
183 assert(x2.a.size() == x2.da.rows());
184
185 IntervalMatrix d(x2.da.rows(),x2.da.cols());
186 for(Index i = 0 ; i < d.rows() ; i++)
187 for(Index j = 0 ; j < d.cols() ; j++)
188 d(i,j) = x1.da(0,j)*x2.a[i]+x1.a*x2.da(i,j);
189
190 return {
191 fwd(x1.m, x2.m),
192 fwd(x1.a, x2.a),
193 d,
194 x1.def_domain && x2.def_domain
195 };
196 }
197
198 inline void MulOp::bwd(const IntervalVector& y, Interval& x1, IntervalVector& x2)
199 {
200 assert(y.size() == x2.size());
201 for(Index i = 0 ; i < x2.size() ; i++)
202 MulOp::bwd(y[i], x1, x2[i]);
203 }
204
205 inline IntervalVector MulOp::fwd(const IntervalVector& x1, const Interval& x2)
206 {
207 return MulOp::fwd(x2,x1);
208 }
209
210 inline VectorType MulOp::fwd_natural(const VectorType& x1, const ScalarType& x2)
211 {
212 return MulOp::fwd_natural(x2,x1);
213 }
214
215 inline VectorType MulOp::fwd_centered(const VectorType& x1, const ScalarType& x2)
216 {
217 return MulOp::fwd_centered(x2,x1);
218 }
219
220 inline void MulOp::bwd(const IntervalVector& y, IntervalVector& x1, Interval& x2)
221 {
222 MulOp::bwd(y, x2, x1);
223 }
224
225 inline Interval MulOp::fwd(const IntervalRow& x1, const IntervalVector& x2)
226 {
227 assert(x1.size() == x2.size());
228 Interval s(0.);
229 for(Index i = 0 ; i < x1.size() ; i++)
230 s += x1[i]*x2[i];
231 return s;
232 }
233
234 //ScalarType MulOp::fwd(const RowType& x1, const VectorType& x2)
235 //{
236 // // RowType not yet defined
237 //}
238
239 inline IntervalMatrix MulOp::fwd(const Interval& x1, const IntervalMatrix& x2)
240 {
241 return x1 * x2;
242 }
243
244 inline MatrixType MulOp::fwd_natural(const ScalarType& x1, const MatrixType& x2)
245 {
246 return {
247 fwd(x1.a, x2.a),
248 x1.def_domain && x2.def_domain
249 };
250 }
251
252 inline MatrixType MulOp::fwd_centered(const ScalarType& x1, const MatrixType& x2)
253 {
254 if(centered_form_not_available_for_args(x1,x2))
255 return fwd_natural(x1,x2);
256
257 assert(x2.da.cols() == x1.da.cols());
258 IntervalMatrix d(x2.da.rows(),x2.da.cols());
259 for (Index j=0; j<d.cols(); j++)
260 for (Index i=0; i<d.rows(); i++) {
261 d(i,j) = x1.da(0,j)*x2.a.reshaped<Eigen::ColMajor>()[i]+x1.a*x2.da(i,j);
262 }
263
264 return {
265 fwd(x1.m, x2.m),
266 fwd(x1.a, x2.a),
267 d,
268 x1.def_domain && x2.def_domain
269 };
270 }
271
272 inline void MulOp::bwd([[maybe_unused]] const IntervalMatrix& y, [[maybe_unused]] Interval& x1, [[maybe_unused]] IntervalMatrix& x2)
273 {
274 // todo
275 }
276
277 inline IntervalVector MulOp::fwd(const IntervalMatrix& x1, const IntervalVector& x2)
278 {
279 assert(x1.cols() == x2.size());
280 return x1 * x2;
281 }
282
283 inline VectorType MulOp::fwd_natural(const MatrixType& x1, const VectorType& x2)
284 {
285 return {
286 fwd(x1.a, x2.a),
287 x1.def_domain && x2.def_domain
288 };
289 }
290
291 inline VectorType MulOp::fwd_centered(const MatrixType& x1, const VectorType& x2)
292 {
293 if(centered_form_not_available_for_args(x1,x2))
294 return fwd_natural(x1,x2);
295
296 assert(x2.da.cols() == x1.da.cols());
297 IntervalMatrix d = IntervalMatrix::zero(x1.a.rows(),x1.da.cols());
298 for (Index j=0; j<d.cols(); j++)
299 for (Index i=0; i<d.rows(); i++) {
300 for (Index k=0; k<x2.a.size(); k++) {
301 d(i,j) += x1.da(i+k*x1.a.rows(),j)*x2.a[k]+x1.a(i,k)*x2.da(k,j);
302 }
303 }
304
305 return {
306 fwd(x1.m, x2.m),
307 fwd(x1.a, x2.a),
308 d,
309 x1.def_domain && x2.def_domain
310 };
311 }
312
313 inline IntervalMatrix MulOp::fwd(const IntervalMatrix& x1, const IntervalMatrix& x2)
314 {
315 assert(x1.cols() == x2.rows());
316 return x1 * x2;
317 }
318
319 inline MatrixType MulOp::fwd_natural(const MatrixType& x1, const MatrixType& x2)
320 {
321 return {
322 fwd(x1.a, x2.a),
323 x1.def_domain && x2.def_domain
324 };
325 }
326
327 inline MatrixType MulOp::fwd_centered(const MatrixType& x1, const MatrixType& x2)
328 {
329 if(centered_form_not_available_for_args(x1,x2))
330 return fwd_natural(x1,x2);
331
332 assert(x2.da.cols() == x1.da.cols());
333 IntervalMatrix d = IntervalMatrix::zero(x1.a.rows()*x2.a.cols(),x1.da.cols());
334 for (Index j=0; j<d.cols(); j++)
335 for (Index i=0; i<d.rows(); i++)
336 {
337 Index row_i = i%x1.a.rows();
338 Index col_i = i/x1.a.rows();
339 for (Index k=0; k<x2.a.rows(); k++) {
340 d(i,j) += x1.da(row_i+k*x1.a.rows(),j)*x2.a(k,col_i)
341 +x1.a(row_i,k)*x2.da(k+col_i*x2.a.rows(),j);
342 }
343 }
344
345 return {
346 fwd(x1.m, x2.m),
347 fwd(x1.a, x2.a),
348 d,
349 x1.def_domain && x2.def_domain
350 };
351 }
352
353 inline void MulOp::bwd([[maybe_unused]] const IntervalMatrix& y, [[maybe_unused]] IntervalMatrix& x1, [[maybe_unused]] IntervalMatrix& x2)
354 {
355 assert(x1.rows() == x2.cols());
356 assert(y.rows() == x1.rows() && y.cols() == x2.cols());
357
358 // todo
359 }
360}
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:412