codac 2.0.0
Loading...
Searching...
No Matches
codac2_vec.h
1
9
10#pragma once
11
12#include "codac2_Interval.h"
14#include "codac2_AnalyticType.h"
16
17namespace codac2
18{
19 struct VectorOp
20 {
21 template<typename... X>
22 static inline 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... X>
30 static std::pair<Index,Index> output_shape([[maybe_unused]] const X&... x)
31 {
32 return { sizeof...(X), 1 };
33 }
34
35 template<typename... X>
36 requires (std::is_base_of_v<Interval,X> && ...)
37 static inline IntervalVector fwd(const X&... x)
38 {
39 return IntervalVector({x...});
40 }
41
42 template<typename... X>
43 requires (std::is_base_of_v<ScalarType,X> && ...)
44 static inline VectorType fwd_natural(const X&... x)
45 {
46 bool def_domain = true;
47 ((def_domain &= x.def_domain), ...);
48
49 return {
50 fwd(x.a...),
51 def_domain
52 };
53 }
54
55 template<typename... X>
56 requires (std::is_base_of_v<ScalarType,X> && ...)
57 static inline VectorType fwd_centered(const X&... x)
58 {
59 if(centered_form_not_available_for_args(x...))
60 return fwd_natural(x...);
61
62 IntervalMatrix d(sizeof...(X),std::get<0>(std::tie(x...)).da.cols());
63 Index i = 0;
64 ((d.row(i++) = x.da), ...);
65
66 bool def_domain = true;
67 ((def_domain &= x.def_domain), ...);
68
69 return {
70 fwd(x.m...),
71 fwd(x.a...),
72 d,
73 def_domain
74 };
75 }
76
77 template<typename... X>
78 requires (std::is_base_of_v<Interval,X> && ...)
79 static inline void bwd(const IntervalVector& y, X&... x)
80 {
81 Index i = 0;
82 ((x &= y[i++]), ...);
83 }
84 };
85
86 // Analytic operator
87 // The following functions can be used to build analytic expressions.
88
89 inline ScalarExpr _add_to_vec(const ScalarExpr& x)
90 {
91 return x;
92 }
93
94 inline ScalarExpr _add_to_vec(double x)
95 {
96 return const_value(x);
97 }
98
99 template<class X>
100 concept IsNotScalarExpr = !std::is_base_of_v<ScalarExpr,X>;
101
102 template<typename X1>
103 requires IsNotScalarExpr<X1>
104 inline VectorExpr
105 vec(const X1& x1)
106 {
107 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
108 ScalarType>>(
109 _add_to_vec(x1)) };
110 }
111
112 template<typename X1, typename X2>
113 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2>)
114 inline VectorExpr
115 vec(const X1& x1, const X2& x2)
116 {
117 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
118 ScalarType,ScalarType>>(
119 _add_to_vec(x1),_add_to_vec(x2)) };
120 }
121
122 template<typename X1, typename X2, typename X3>
123 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3>)
124 inline VectorExpr
125 vec(const X1& x1, const X2& x2, const X3& x3)
126 {
127 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
128 ScalarType,ScalarType,ScalarType>>(
129 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3)) };
130 }
131
132 template<typename X1, typename X2, typename X3, typename X4>
133 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3> && IsNotScalarExpr<X4>)
134 inline VectorExpr
135 vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
136 {
137 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
138 ScalarType,ScalarType,ScalarType,ScalarType>>(
139 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4)) };
140 }
141
142 template<typename X1, typename X2, typename X3, typename X4, typename X5>
143 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3> && IsNotScalarExpr<X4> && IsNotScalarExpr<X5>)
144 inline VectorExpr
145 vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5)
146 {
147 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
148 ScalarType,ScalarType,ScalarType,ScalarType,ScalarType>>(
149 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5)) };
150 }
151
152 template<typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
153 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3> && IsNotScalarExpr<X4> && IsNotScalarExpr<X5> && IsNotScalarExpr<X6>)
154 inline VectorExpr
155 vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6)
156 {
157 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
158 ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType>>(
159 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6)) };
160 }
161
162 template<typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7>
163 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3> && IsNotScalarExpr<X4> && IsNotScalarExpr<X5> && IsNotScalarExpr<X6> && IsNotScalarExpr<X7>)
164 inline VectorExpr
165 vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7)
166 {
167 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
168 ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType>>(
169 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7)) };
170 }
171
172 template<typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8>
173 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3> && IsNotScalarExpr<X4> && IsNotScalarExpr<X5> && IsNotScalarExpr<X6> && IsNotScalarExpr<X7> && IsNotScalarExpr<X8>)
174 inline VectorExpr
175 vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8)
176 {
177 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
178 ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType>>(
179 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8)) };
180 }
181
182 template<typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9>
183 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3> && IsNotScalarExpr<X4> && IsNotScalarExpr<X5> && IsNotScalarExpr<X6> && IsNotScalarExpr<X7> && IsNotScalarExpr<X8> && IsNotScalarExpr<X9>)
184 inline VectorExpr
185 vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9)
186 {
187 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
188 ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType>>(
189 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9)) };
190 }
191
192 template<typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, typename X10>
193 requires (IsNotScalarExpr<X1> && IsNotScalarExpr<X2> && IsNotScalarExpr<X3> && IsNotScalarExpr<X4> && IsNotScalarExpr<X5> && IsNotScalarExpr<X6> && IsNotScalarExpr<X7> && IsNotScalarExpr<X8> && IsNotScalarExpr<X9> && IsNotScalarExpr<X10>)
194 inline VectorExpr
195 vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9, const X10& x10)
196 {
197 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,
198 ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType,ScalarType>>(
199 _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9),_add_to_vec(x10)) };
200 }
201
202 // Generic variadic case, cannot handle const values (int, double) for now
203
204 template<typename... X>
205 inline VectorExpr
206 vec(const AnalyticExprWrapper<X>&... x)
207 {
208 return { std::make_shared<AnalyticOperationExpr<VectorOp,VectorType,X...>>(x...) };
209 }
210}