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