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