codac 2.0.0
Loading...
Searching...
No Matches
codac2_CtcInverse_.h
1
9
10#pragma once
11
12#include <map>
14#include "codac2_Ctc.h"
15#include "codac2_CtcWrapper.h"
16#include "codac2_Collection.h"
17#include "codac2_arith_mul.h"
18#include "codac2_Wrapper.h"
19
20namespace codac2
21{
22 class CtcNot;
23
24 template<typename Y, typename... X>
25 requires (sizeof...(X) > 0)
26 class CtcInverse : public Ctc<CtcInverse<Y,X...>,X...>
27 {
28 public:
29
30 using Ctc<CtcInverse<Y,X...>,X...>::contract;
31
32 template<typename C>
33 requires IsCtcBaseOrPtr<C,Y>
34 CtcInverse(const AnalyticFunction<typename ExprType<Y>::Type>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false, double freq = 0.)
35 : Ctc<CtcInverse<Y,X...>,X...>(f.args()[0]->size()), _f(f), _ctc_y(ctc_y), _with_centered_form(with_centered_form), _is_not_in(is_not_in), _freq(freq)
36 {
37 assert_release([&]() { return f.output_size() == size_of(ctc_y); }()
38 && "CtcInverse: invalid dimension of image argument ('y' or 'ctc_y')");
39 }
40
41 CtcInverse(const AnalyticFunction<typename ExprType<Y>::Type>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false, double freq = 0.)
42 : CtcInverse(f, CtcWrapper<Y,Y>(y), with_centered_form, is_not_in, freq)
43 { }
44
45 void contract(X&... x) const
46 {
47 return contract_(*_ctc_y.front(), x...);
48 }
49
50 void contract_(const Y& y, X&... x) const
51 {
52 return contract_(CtcWrapper<Y,Y>(y), x...);
53 }
54
55 void contract_(const CtcBase<Y>& ctc_y, X&... x) const
56 {
57 //using X0b = std::tuple_element_t<0, std::tuple<X...>>;
58 //X0b x0_before = std::get<0>(std::tie(x...));
59//double md = std::get<0>(std::tie(x...)).max_diam();
60bool using_nat = true;//_both || md >= _freq;
61bool using_centered = true;//_both || _both_then_one || md < _freq;
62
63 ValuesMap v;
64 // Setting user values into a map before the tree evaluation
65 _f.fill_from_args(v, x...);
66
67 // Forward/backward algorithm:
68
69 // [1/4] Forward evaluation
70 _f.expr()->fwd_eval(v, _f.args().total_size(), !using_centered);
71 auto& val_expr = _f.expr()->value(v);
72
73 if(_is_not_in && !val_expr.def_domain)
74 return; // <-- iota: if the input x is outside the definition
75 // domain of one of the involved expressions, or their combinations,
76 // then the inner contraction is disabled.
77
78 // [2/4] Performing top contraction (from the root of the tree) with
79 // the contractor expressing the output domain Y.
80 // The underlying constraint is: f(x) \in [y]
81 ctc_y.contract(val_expr.a);
82
83 // [3/4 - optional]
84 // The contraction can be significantly improved using a centered form
85 // expression (enabled by default). This step must be processed before the
86 // backward part of the FwdBwd algorithm (the .m, .a values must not be
87 // changed before the centered evaluation).
88
89 if(using_nat)
90 {
91 _f.expr()->bwd_eval(v); // recursive backward from the root to the leaves
92 _f.intersect_from_args(v, x...); // updating input values
93 }
94
95
96 //if(_both || _both_then_one || md < _freq)
97 // if(_with_centered_form && val_expr.def_domain && !val_expr.da.is_unbounded() && val_expr.da.size() != 0)
98 if(using_centered)
99 {
100 // todo: the above condition !val_expr.da.is_unbounded() should not be necesary,
101 // possible bug in MulOp in case of unbounded domain?
102 using X0 = std::tuple_element_t<0, std::tuple<X...>>;
103
104 if constexpr(sizeof...(X) == 1 && std::is_same_v<X0,IntervalVector>)
105 {
106 X0& x_ = std::get<0>(std::tie(x...));
107 X0 x_mid = X0(x_.mid());
108
109 assert(val_expr.a.size() == val_expr.m.size());
110
111 if constexpr(std::is_same_v<Y,IntervalMatrix>)
112 {
113 std::cout << "CtcInverse: matrices expressions not (yet) supported with centered form" << std::endl;
114 }
115
116 else
117 {
118 IntervalVector p = x_ - x_mid;
119 IntervalVector fm { val_expr.a - val_expr.m };
120 MulOp::bwd(fm, val_expr.da, p);
121 x_ &= p + x_mid;
122 }
123 }
124
125 else
126 {
127 // Centered form not (yet) implemented for multi-nonvector-arguments
128 }
129 }
130
131 // [4/4] Backward evaluation
132
133 /*X0b x0_after = std::get<0>(std::tie(x...));
134 if(x0_after.is_empty())
135 _data.push_back({x0_before.max_diam(), 0.});
136 else
137 _data.push_back({x0_before.max_diam(), x0_before.volume()/x0_after.volume()});*/
138
139 }
140
141 const AnalyticFunction<typename ExprType<Y>::Type>& function() const
142 {
143 return _f;
144 }
145
146 //mutable std::vector<std::pair<double,double>> _data;
147
148 double _freq = 0.;
149 bool _both = true;
150 bool _both_then_one = true;
151
152 protected:
153
154 const AnalyticFunction<typename ExprType<Y>::Type> _f;
155 const Collection<CtcBase<Y>> _ctc_y;
156 bool _with_centered_form;
157 bool _is_not_in = false;
158 };
159
160
161 // Template deduction guides
162
163 // ScalarType
164
165 CtcInverse(const AnalyticFunction<ScalarType>&, std::initializer_list<double>, bool = true, bool = false) ->
166 CtcInverse<Interval,IntervalVector>;
167
168 template<typename Y>
169 CtcInverse(const AnalyticFunction<ScalarType>&, std::initializer_list<Y>, bool = true, bool = false) ->
170 CtcInverse<Interval,IntervalVector>;
171
172 CtcInverse(const AnalyticFunction<ScalarType>&, const Interval&, bool = true, bool = false) ->
173 CtcInverse<Interval,IntervalVector>;
174
175 CtcInverse(const AnalyticFunction<ScalarType>&, double, bool = true, bool = false) ->
176 CtcInverse<Interval,IntervalVector>;
177
178 template<typename C>
179 requires IsCtcBaseOrPtr<C,Interval>
180 CtcInverse(const AnalyticFunction<ScalarType>&, const C&, bool = true, bool = false) ->
181 CtcInverse<Interval,IntervalVector>;
182
183 // VectorType
184
185 CtcInverse(const AnalyticFunction<VectorType>&, std::initializer_list<double>, bool = true, bool = false) ->
186 CtcInverse<IntervalVector,IntervalVector>;
187
188 CtcInverse(const AnalyticFunction<VectorType>&, std::initializer_list<std::initializer_list<double>>, bool = true, bool = false) ->
189 CtcInverse<IntervalVector,IntervalVector>;
190
191 CtcInverse(const AnalyticFunction<VectorType>&, const Vector&, bool = true, bool = false) ->
192 CtcInverse<IntervalVector,IntervalVector>;
193
194 CtcInverse(const AnalyticFunction<VectorType>&, const IntervalVector&, bool = true, bool = false) ->
195 CtcInverse<IntervalVector,IntervalVector>;
196
197 template<typename OtherDerived>
198 requires (OtherDerived::RowsAtCompileTime == -1 && OtherDerived::ColsAtCompileTime == 1)
199 CtcInverse(const AnalyticFunction<VectorType>&, const Eigen::MatrixBase<OtherDerived>&, bool = true, bool = false) ->
200 CtcInverse<IntervalVector,IntervalVector>;
201
202 template<typename C>
203 requires IsCtcBaseOrPtr<C,IntervalVector>
204 CtcInverse(const AnalyticFunction<VectorType>&, const C&, bool = true, bool = false) ->
205 CtcInverse<IntervalVector,IntervalVector>;
206
207 // MatrixType
208
209 CtcInverse(const AnalyticFunction<MatrixType>&, std::initializer_list<std::initializer_list<double>>, bool = true, bool = false) ->
210 CtcInverse<IntervalMatrix,IntervalVector>;
211
212 CtcInverse(const AnalyticFunction<MatrixType>&, std::initializer_list<std::initializer_list<std::initializer_list<double>>>, bool = true, bool = false) ->
213 CtcInverse<IntervalMatrix,IntervalVector>;
214
215 template<typename OtherDerived>
216 requires (OtherDerived::RowsAtCompileTime == -1 && OtherDerived::ColsAtCompileTime == -1)
217 CtcInverse(const AnalyticFunction<MatrixType>&, const Eigen::MatrixBase<OtherDerived>&, bool = true, bool = false) ->
218 CtcInverse<IntervalMatrix,IntervalVector>;
219
220 template<typename C>
221 requires IsCtcBaseOrPtr<C,IntervalMatrix>
222 CtcInverse(const AnalyticFunction<MatrixType>&, const C&, bool = true, bool = false) ->
223 CtcInverse<IntervalMatrix,IntervalVector>;
224}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:49
Definition codac2_OctaSym.h:21
Eigen::Matrix< double,-1, 1 > Vector
Alias for a dynamically-sized column vector of doubles.
Definition codac2_Vector.h:24
Eigen::Matrix< Interval,-1, 1 > IntervalVector
Alias for a dynamic-size column vector of intervals.
Definition codac2_IntervalVector.h:25