codac 2.0.0
Loading...
Searching...
No Matches
codac2_CtcEval.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Ctc.h"
13#include "codac2_SlicedTube.h"
14
15namespace codac2
16{
17 class CtcEval
18 {
19 public:
20
21 CtcEval();
22
23 template<typename T>
24 void contract(Interval& t, T& z, SlicedTube<T>& y, SlicedTube<T>& w)
25 {
26 assert_release(y.tdomain() == w.tdomain());
27 assert(Tube::same_slicing(y, w));
28
29 /*if(t.is_empty() || z.is_empty() || y.is_empty())
30 {
31 // todo: add w.is_empty() in the above conditions ^
32 t.set_empty();
33 z.set_empty();
34 y.set_empty();
35 w.set_empty();
36 return;
37 }*/
38
39 if(t.is_degenerated())
40 {
41 y.set(y(t.lb()) & z, t.lb());
42 return;
43 }
44
45 t &= y.invert(z, w, t);
46
47 /*if(!t.is_empty())
48 {
49 if(t.is_degenerated())
50 return contract(t.lb(), z, y, w);
51
52 z &= y.interpol(t, w);
53
54 if(!z.is_empty())
55 {
56 vector<double> v_gates_to_remove;
57 if(m_preserve_slicing)
58 {
59 if(!y.gate_exists(t.lb())) // will exist then
60 v_gates_to_remove.push_back(t.lb());
61 if(!y.gate_exists(t.ub())) // will exist then
62 v_gates_to_remove.push_back(t.ub());
63 }
64
65 y.set(y.interpol(t.lb(), w), t.lb()); w.sample(t.lb());
66 y.set(y.interpol(t.ub(), w), t.ub()); w.sample(t.ub());
67
68 // Note: w is also sampled to stay compliant with y.
69
70 CtcDeriv ctc_deriv;
71 ctc_deriv.restrict_tdomain(m_restricted_tdomain);
72 ctc_deriv.set_fast_mode(m_fast_mode);
73
74 Interval front_gate(y.size());
75 list<Interval> l_gates;
76 Slice *s_y;
77 Slice *s_w;
78
79 // 1. Forward propagation
80
81 s_y = y.slice(t.lb());
82 s_w = w.slice(t.lb());
83
84 front_gate = s_y->input_gate() & z;
85 // Mathematically, front_gate should not be empty at this point.
86 // Due to numerical approximations, the computation of t by the invert method
87 // provides a wider enclosure t'. The evaluation of y[t'.lb()] may not
88 // intersect z and so the front_gate becomes empty.
89 // An epsilon inflation could be used to overcome this problem. Or:
90 if(front_gate.is_empty())
91 {
92 if(s_y->input_gate().ub() < z.lb()) front_gate = z.lb();
93 else front_gate = z.ub();
94 }
95
96 l_gates.push_front(front_gate);
97
98 while(s_y && s_y->tdomain().lb() < t.ub())
99 {
100 // Forward propagation of the evaluation
101 front_gate += s_y->tdomain().diam() * s_w->codomain(); // projection
102 front_gate |= z; // evaluation
103 front_gate &= s_y->output_gate(); // contraction
104
105 // Storing temporarily fwd propagation
106 l_gates.push_front(front_gate);
107
108 // Iteration
109 s_y = s_y->next_slice();
110 s_w = s_w->next_slice();
111 }
112
113 // 2. Backward propagation
114
115 s_y = y.slice(ibex::previous_float(t.ub()));
116 s_w = w.slice(ibex::previous_float(t.ub()));
117
118 front_gate = s_y->output_gate() & z;
119 // Overcoming numerical approximations, same remark as before:
120 if(front_gate.is_empty())
121 {
122 if(s_y->output_gate().ub() < z.lb()) front_gate = z.lb();
123 else front_gate = z.ub();
124 }
125
126 s_y->set_output_gate(l_gates.front() | front_gate);
127
128 while(s_y && s_y->tdomain().lb() >= t.lb())
129 {
130 // Backward propagation of the evaluation
131 front_gate -= s_y->tdomain().diam() * s_w->codomain(); // projection
132 front_gate |= z; // evaluation
133 front_gate &= s_y->input_gate(); // contraction
134
135 // Updating tube
136 l_gates.pop_front();
137 s_y->set_input_gate(l_gates.front() | front_gate);
138 ctc_deriv.contract_gates(*s_y, *s_w);
139
140 // Iteration
141 s_y = s_y->prev_slice();
142 s_w = s_w->prev_slice();
143 }
144
145 // 3. Envelopes contraction
146
147 if(m_propagation_enabled)
148 ctc_deriv.contract(y, w);
149
150 // 4. Evaluation contraction
151
152 t &= y.invert(z, w, t);
153 if(!t.is_empty())
154 z &= y.interpol(t, w);
155
156 // 5. If requested, preserving the initial slicing
157
158 for(size_t i = 0 ; i < v_gates_to_remove.size() ; i++)
159 {
160 // The gate will be lost during the final operation for
161 // preserving the slicing. So we need to propagate locally
162 // the information on nearby slices, to keep the information,
163 // and then merge them.
164
165 Slice *s_y = y.slice(v_gates_to_remove[i]);
166 Slice *s_w = w.slice(v_gates_to_remove[i]);
167
168 // 1. Contraction
169
170 CtcDeriv ctc_deriv;
171 ctc_deriv.contract(*s_y, *s_w);
172 if(s_y->next_slice() && s_w->next_slice())
173 ctc_deriv.contract(*s_y->next_slice(), *s_w->next_slice());
174
175 // 2. Merge
176
177 y.remove_gate(v_gates_to_remove[i]);
178 w.remove_gate(v_gates_to_remove[i]);
179
180 y.delete_synthesis_tree(); // todo: update tree if created, instead of delete
181 w.delete_synthesis_tree(); // todo: update tree if created, instead of delete
182 }
183 }
184
185 // todo: remove this (or use Polygons with truncation)
186
187 for(Slice *s = y.first_slice() ; s ; s = s->next_slice())
188 {
189 Interval envelope = s->codomain();
190 if(envelope.ub() == BOUNDED_INFINITY) envelope = Interval(envelope.lb(),POS_INFINITY);
191 if(envelope.lb() == -BOUNDED_INFINITY) envelope |= Interval(NEG_INFINITY,envelope.ub());
192 s->set_envelope(envelope);
193
194 Interval ingate = s->input_gate();
195 if(ingate.ub() == BOUNDED_INFINITY) ingate = Interval(ingate.lb(),POS_INFINITY);
196 if(ingate.lb() == -BOUNDED_INFINITY) ingate = Interval(NEG_INFINITY,ingate.ub());
197 s->set_input_gate(ingate);
198
199 Interval outgate = s->output_gate();
200 if(outgate.ub() == BOUNDED_INFINITY) outgate = Interval(outgate.lb(),POS_INFINITY);
201 if(outgate.lb() == -BOUNDED_INFINITY) outgate = Interval(NEG_INFINITY,outgate.ub());
202 s->set_output_gate(outgate);
203 }
204 }*/
205
206 /*if(t.is_empty() || z.is_empty() || y.is_empty())
207 {
208 t.set_empty();
209 z.set_empty();
210 y.set_empty();
211 }*/
212 }
213 };
214}
Definition codac2_OctaSym.h:21