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