codac 1.5.6
Loading...
Searching...
No Matches
codac2_CtcInverse.h
Go to the documentation of this file.
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 template<typename C>
31 requires IsCtcBaseOrPtr<C,Y>
32 CtcInverse(const AnalyticFunction<typename ExprType<Y>::Type>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false)
33 : 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)
34 {
35 assert_release([&]() { return f.output_size() == size_of(ctc_y); }()
36 && "CtcInverse: invalid dimension of image argument ('y' or 'ctc_y')");
37 }
38
39 CtcInverse(const AnalyticFunction<typename ExprType<Y>::Type>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false)
40 : CtcInverse(f, CtcWrapper<Y>(y), with_centered_form, is_not_in)
41 { }
42
43 void contract(X&... x) const
44 {
45 return contract_(*_ctc_y.front(), x...);
46 }
47
48 void contract_(const Y& y, X&... x) const
49 {
50 return contract_(CtcWrapper<Y>(y), x...);
51 }
52
53 void contract_(const CtcBase<Y>& ctc_y, X&... x) const
54 {
55 ValuesMap v;
56 // Setting user values into a map before the tree evaluation
57 _f.fill_from_args(v, x...);
58
59 // Forward/backward algorithm:
60
61 // [1/4] Forward evaluation
62 _f.expr()->fwd_eval(v, _f.args().total_size(), !_with_centered_form);
63 auto& val_expr = _f.expr()->value(v);
64
65 if(_is_not_in && !val_expr.def_domain)
66 return; // <-- iota: if the input x is outside the definition
67 // domain of one of the involved expressions, or their combinations,
68 // then the inner contraction is disabled.
69
70 // [2/4] Performing top contraction (from the root of the tree) with
71 // the contractor expressing the output domain Y.
72 // The underlying constraint is: f(x) \in [y]
73 ctc_y.contract(val_expr.a);
74
75 // [3/4 - optional]
76 // The contraction can be significantly improved using a centered form
77 // expression (enabled by default). This step must be processed before the
78 // backward part of the FwdBwd algorithm (the .m, .a values must not be
79 // changed before the centered evaluation).
80 if(_with_centered_form && val_expr.def_domain && !val_expr.da.is_unbounded() && val_expr.da.size() != 0)
81 {
82 // todo: the above condition !val_expr.da.is_unbounded() should not be necesary,
83 // possible bug in MulOp in case of unbounded domain?
84 using X0 = std::tuple_element_t<0, std::tuple<X...>>;
85
86 if constexpr(sizeof...(X) == 1 && std::is_same_v<X0,IntervalVector>)
87 {
88 X0& x_ = std::get<0>(std::tie(x...));
89 X0 x_mid = X0(x_.mid());
90
91 assert(val_expr.a.size() == val_expr.m.size());
92 IntervalVector fm { val_expr.a - val_expr.m };
93
94 if constexpr(std::is_same_v<Y,IntervalMatrix>)
95 {
96 std::cout << "CtcInverse: matrices expressions not (yet) supported with centered form" << std::endl;
97 }
98
99 else
100 {
101 IntervalVector p = x_ - x_mid;
102 MulOp::bwd(fm, val_expr.da, p);
103 x_ &= p + x_mid;
104 }
105 }
106
107 else
108 {
109 // Centered form not (yet) implemented for multi-nonvector-arguments
110 }
111 }
112
113 // [4/4] Backward evaluation
114 _f.expr()->bwd_eval(v); // recursive backward from the root to the leaves
115 _f.intersect_from_args(v, x...); // updating input values
116 }
117
118 const AnalyticFunction<typename ExprType<Y>::Type>& function() const
119 {
120 return _f;
121 }
122
123 protected:
124
125 const AnalyticFunction<typename ExprType<Y>::Type> _f;
126 const Collection<CtcBase<Y>> _ctc_y;
127 bool _with_centered_form;
128 bool _is_not_in = false;
129 };
130
131
132 // Template deduction guides
133
134 // ScalarType
135
136 CtcInverse(const AnalyticFunction<ScalarType>&, std::initializer_list<double>, bool = true, bool = false) ->
137 CtcInverse<Interval,IntervalVector>;
138
139 template<typename Y>
140 CtcInverse(const AnalyticFunction<ScalarType>&, std::initializer_list<Y>, bool = true, bool = false) ->
141 CtcInverse<Interval,IntervalVector>;
142
143 CtcInverse(const AnalyticFunction<VectorType>&, const Interval&, bool = true, bool = false) ->
144 CtcInverse<Interval,IntervalVector>;
145
146 template<typename C>
147 requires IsCtcBaseOrPtr<C,Interval>
148 CtcInverse(const AnalyticFunction<ScalarType>&, const C&, bool = true, bool = false) ->
149 CtcInverse<Interval,IntervalVector>;
150
151 // VectorType
152
153 CtcInverse(const AnalyticFunction<VectorType>&, std::initializer_list<double>, bool = true, bool = false) ->
154 CtcInverse<IntervalVector,IntervalVector>;
155
156 CtcInverse(const AnalyticFunction<VectorType>&, std::initializer_list<std::initializer_list<double>>, bool = true, bool = false) ->
157 CtcInverse<IntervalVector,IntervalVector>;
158
159 CtcInverse(const AnalyticFunction<VectorType>&, const Vector&, bool = true, bool = false) ->
160 CtcInverse<IntervalVector,IntervalVector>;
161
162 CtcInverse(const AnalyticFunction<VectorType>&, const IntervalVector&, bool = true, bool = false) ->
163 CtcInverse<IntervalVector,IntervalVector>;
164
165 template<typename OtherDerived>
166 requires (OtherDerived::RowsAtCompileTime == -1 && OtherDerived::ColsAtCompileTime == 1)
167 CtcInverse(const AnalyticFunction<VectorType>&, const Eigen::MatrixBase<OtherDerived>&, bool = true, bool = false) ->
168 CtcInverse<IntervalVector,IntervalVector>;
169
170 template<typename C>
171 requires IsCtcBaseOrPtr<C,IntervalVector>
172 CtcInverse(const AnalyticFunction<VectorType>&, const C&, bool = true, bool = false) ->
173 CtcInverse<IntervalVector,IntervalVector>;
174
175 // MatrixType
176
177 CtcInverse(const AnalyticFunction<MatrixType>&, std::initializer_list<std::initializer_list<double>>, bool = true, bool = false) ->
178 CtcInverse<IntervalMatrix,IntervalVector>;
179
180 CtcInverse(const AnalyticFunction<MatrixType>&, std::initializer_list<std::initializer_list<std::initializer_list<double>>>, bool = true, bool = false) ->
181 CtcInverse<IntervalMatrix,IntervalVector>;
182
183 template<typename OtherDerived>
184 requires (OtherDerived::RowsAtCompileTime == -1 && OtherDerived::ColsAtCompileTime == -1)
185 CtcInverse(const AnalyticFunction<VectorType>&, const Eigen::MatrixBase<OtherDerived>&, bool = true, bool = false) ->
186 CtcInverse<IntervalMatrix,IntervalVector>;
187
188 template<typename C>
189 requires IsCtcBaseOrPtr<C,IntervalMatrix>
190 CtcInverse(const AnalyticFunction<MatrixType>&, const C&, bool = true, bool = false) ->
191 CtcInverse<IntervalMatrix,IntervalVector>;
192}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:62