codac 2.0.0
Loading...
Searching...
No Matches
codac2_mat.h
1
9
10#pragma once
11
14#include "codac2_AnalyticType.h"
16
17namespace codac2
18{
19 struct MatrixOp
20 {
21 template<typename... X>
22 static std::string str(const X&... x)
23 {
24 std::string s = (("\t" + x->str() + ",\n") + ...);
25 s.pop_back(); s.pop_back(); // removes last separation
26 return "[\n" + s + "\n]";
27 }
28
29 template<typename X1, typename... X>
30 static std::pair<Index,Index> output_shape(const X1& s1, [[maybe_unused]] const X&... s)
31 {
32 auto shape1=s1->output_shape();
33 assert_release(shape1.second==1);
34 return { shape1.first, 1+sizeof...(X) };
35 }
36
37 static inline void set_col_i(IntervalMatrix& m, const IntervalVector& x, Index i)
38 {
39 assert(i >= 0 && i < m.cols());
40 assert_release(x.size() == m.rows());
41 m.col(i) = x;
42 }
43
44 template<typename X1,typename... X>
45 requires ((X1::ColsAtCompileTime == 1) && ((X::ColsAtCompileTime == 1) && ...))
46 static inline IntervalMatrix fwd(const X1& x1, const X&... x)
47 {
48 IntervalMatrix m(x1.size(), 1+sizeof...(X));
49 Index i = 0;
50 MatrixOp::set_col_i(m, x1, i++); // first column x1
51 (MatrixOp::set_col_i(m, x, i++), ...); // other columns
52 return m;
53 }
54
55 template<typename... X>
56 requires (std::is_base_of_v<VectorType,X> && ...)
57 static inline MatrixType fwd_natural(const X&... x)
58 {
59 return {
60 MatrixOp::fwd(x.a...),
61 (x.def_domain && ...)
62 };
63 }
64
65 static inline void fill_diff_matrix(IntervalMatrix &d,
66 const IntervalMatrix &dax, Index &l) {
67 d.middleRows(l,dax.rows())=dax;
68 l += dax.rows();
69 }
70
71
72 template<typename X1, typename... X>
73 requires (std::is_base_of_v<VectorType,X1>
74 && (std::is_base_of_v<VectorType,X> && ...))
75 static inline MatrixType fwd_centered(const X1& x1, const X&... x)
76 {
77 if (centered_form_not_available_for_args(x1,x...))
78 return fwd_natural(x1,x...);
79
80 IntervalMatrix d(x1.a.size()*(1+sizeof...(X)),x1.da.cols());
81 Index l=0;
82 d.topRows(x1.da.rows()) = x1.da;
83 l += x1.da.rows();
84 ( MatrixOp::fill_diff_matrix(d,x.da,l) , ...);
85 assert (l==d.rows());
86
87 return {
88 MatrixOp::fwd(x1.m,x.m...),
89 MatrixOp::fwd(x1.a,x.a...),
90 d,
91 (x1.def_domain && (x.def_domain && ...))
92 };
93 }
94
95 template<typename... X>
96 requires (std::is_base_of_v<IntervalVector,X> && ...)
97 static inline void bwd(const IntervalMatrix& y, X&... x)
98 {
99 throw std::runtime_error("MatrixOp not fully implemented yet");
100 Index i = 0;
101 ((x &= y.col(i++)), ...);
102 }
103 };
104
105 // Analytic operator
106 // The following function can be used to build analytic expressions.
107
108 // Generic variadic case, cannot handle const values (int, double) for now
109
110 template<typename... X>
111 inline MatrixExpr
112 mat(const std::shared_ptr<AnalyticExpr<X>>&... x)
113 {
114 return { std::make_shared<AnalyticOperationExpr<MatrixOp,MatrixType,X...>>(
115 AnalyticOperationExpr<MatrixOp,MatrixType,X...>(x...)) };
116 }
117}