codac 2.0.0
Loading...
Searching...
No Matches
codac2_SepImage.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Sep.h"
13#include "codac2_Collection.h"
14#include "codac2_Paving.h"
15#include "codac2_PavingNode.h"
16#include "codac2_Subpaving.h"
18#include "codac2_OctaSym.h"
19#include "codac2_peibos.h"
20#include "codac2_CtcUnion.h"
21#include "codac2_CtcWrapper.h"
22#include "codac2_CtcIdentity.h"
23#include "codac2_SepCtcPair.h"
24#include "codac2_SepInverse.h"
25#include "codac2_SepWrapper.h"
26#include "codac2_SepInter.h"
27#include "codac2_pave.h"
28#include <codac2_hull.h>
29
30namespace codac2
31{
35 class SepImage : public Sep<SepImage>
36 {
37 public:
38
49 template<typename C>
50 requires IsCtcBaseOrPtr<C,IntervalVector>
51 SepImage(const AnalyticFunction<VectorType>& f, const AnalyticFunction<VectorType>& psi_0, const std::vector<OctaSym>& Sigma, double epsilon, const C& ctc_init, double epsilon_pave = -1)
52 :Sep<SepImage>(f.output_size())
53 {
54 // Using PEIBOS to get the boundary of the image set
55 int dim = f.output_size();
56 auto v_par = PEIBOS(f,psi_0,Sigma,epsilon);
57
58 IntervalVector X0 (dim);
59 ctc_init.contract(X0);
60
61 // Contractor on the boundary
62 CtcUnion ctc_union (dim);
63 for (const auto& par : v_par)
64 ctc_union |= CtcWrapper(par);
65
66 SepCtcPair sep_boundary(CtcIdentity(dim), ctc_union);
67
68 IntervalVector Y0 (dim);
69 ctc_union.contract(Y0);
70 Y0.inflate(Y0.min_diam()/10.);
71
72 // paving resolution, can be tuned
73 if (epsilon_pave == -1)
74 epsilon_pave = Y0.min_diam()/50.;
75
76 // Initial paving, with only an outer aproximation
77 PavingInOut p = pave(Y0,sep_boundary,epsilon_pave);
78
79 // Determination of the inner connected susets
80 auto v_cs = p.connected_subsets(PavingInOut::outer_complem);
81 std::list<std::shared_ptr<PavingInOut::ConnectedSubset_>> cs_to_color;
82 for (const auto& cs: v_cs)
83 {
84 IntervalVector max_box = IntervalVector::empty(dim);
85 for (const auto& box : cs.boxes())
86 if (box.volume()>max_box.volume())
87 max_box=box;
88
89 CtcInverse ctc_inv (f, max_box.mid());
90 IntervalVector X0_copy (X0);
91 bool could_contract = false;
92
93 ctc_inv.contract(X0_copy);
94 ctc_init.contract(X0_copy);
95
96 if (X0_copy != X0)
97 {
98 could_contract = true;
99 if (!X0_copy.is_empty())
100 cs_to_color.push_back(std::make_shared<PavingInOut::ConnectedSubset_>(cs));
101 }
102
103 // if the CtcInverse was not able to conclude directly, we subdivide the initial box
104
105 if (!could_contract)
106 {
107 std::vector<IntervalVector> boxes;
108 split(X0_copy,0.125,boxes);
109 for (auto box: boxes)
110 {
111 IntervalVector box_copy (box);
112 ctc_inv.contract(box);
113 ctc_init.contract(box);
114 if (box != box_copy)
115 {
116 could_contract = true;
117 if (!box.is_empty())
118 {
119 cs_to_color.push_back(std::make_shared<PavingInOut::ConnectedSubset_>(cs));
120 break;
121 }
122 }
123 }
124 }
125
126 if (!could_contract)
127 printf("warning, the SepImage was not able to conclude on the inner regions\n");
128 }
129
130 // Turning the previously identified connected subsets as inner (displayed green)
131 // This code comes from the example coloration.py,
132 // TODO : factorize it by allowing to pass a list of ConnectedSubset as argument
133 auto visitor = [&](std::shared_ptr<PavingNode<PavingInOut>> n)
134 {
135 std::list<IntervalVector> boxes_to_color;
136 for (const auto& cs : cs_to_color)
137 for (const auto& box : cs->boxes())
138 boxes_to_color.push_back(box);
139
140 IntervalVector h = n->hull();
141 IntervalVector u = n->unknown();
142
143 for (const auto& bi : boxes_to_color)
144 {
145 IntervalVector bih = bi & h;
146 if (!bih.is_empty())
147 {
148 if (std::get<0>(n->boxes()).is_empty())
149 {
150 n->set_boxes(std::make_tuple(std::get<1>(n->boxes()),std::get<0>(n->boxes())));
151 return false;
152 }
153
154 std::list<IntervalVector> lbi;
155
156 for (const auto& bj : boxes_to_color)
157 {
158 IntervalVector bjh = bj & h;
159 if (!bjh.is_empty())
160 lbi.push_back(bjh);
161 }
162
163 IntervalVector prev_x_in = IntervalVector::empty(dim);
164
165 // there used to be a copy x_in = h there, but didn't behave as exepected
166
167 while (h != prev_x_in)
168 {
169 prev_x_in = IntervalVector(h);
170
171 for (const auto& li : lbi)
172 {
173 std::list<IntervalVector> d = h.diff(li);
174
175 if (!d.empty())
176 {
177
178 IntervalVector hi = IntervalVector::empty(dim);
179 for (const auto& di : d)
180 hi |= (h & di);
181 h &= hi;
182
183 }
184 }
185 }
186
187 n->set_boxes(std::make_tuple(hull(lbi)|u, h));
188 return true;
189 }
190 }
191 return true;
192 };
193
194 // Use the visitor to color the inner regions
195 p.tree()->visit(visitor);
196
197 // Create a separator on this paving
198 SepWrapper<PavingInOut> sep_paving(p);
199
200 // By construction, we know that we have the whole image set.
201 // What is outside of the paving box Y0 is for sure ouside of it.
202 SepInter sep_inter = sep_paving&Y0;
203
204 _sep.push_back(sep_inter);
205 }
206
217 template<typename C>
218 requires IsCtcBaseOrPtr<C,IntervalVector>
219 SepImage(const AnalyticFunction<VectorType>& f, const AnalyticFunction<VectorType>& psi_0, const std::vector<OctaSym>& Sigma, double epsilon, const std::shared_ptr<C>& ctc_init, double epsilon_pave = -1)
220 : SepImage(f, psi_0, Sigma, epsilon, *ctc_init, epsilon_pave)
221 { }
222
230 BoxPair separate(const IntervalVector& x) const;
231
232 protected:
233
234 Collection<SepBase> _sep;
235 };
236}
SepImage(const AnalyticFunction< VectorType > &f, const AnalyticFunction< VectorType > &psi_0, const std::vector< OctaSym > &Sigma, double epsilon, const std::shared_ptr< C > &ctc_init, double epsilon_pave=-1)
Constructor of the separator.
Definition codac2_SepImage.h:219
SepImage(const AnalyticFunction< VectorType > &f, const AnalyticFunction< VectorType > &psi_0, const std::vector< OctaSym > &Sigma, double epsilon, const C &ctc_init, double epsilon_pave=-1)
Constructor of the separator.
Definition codac2_SepImage.h:51
BoxPair separate(const IntervalVector &x) const
Separates the box.
Definition codac2_OctaSym.h:21
Eigen::Matrix< Interval,-1, 1 > IntervalVector
Alias for a dynamic-size column vector of intervals.
Definition codac2_IntervalVector.h:25
double split(const IntervalVector &X, double eps, std::vector< IntervalVector > &boxes)
Recursively split a box until the maximum diameter of each box is less than eps. Note that the result...
std::vector< Parallelepiped > PEIBOS(const AnalyticFunction< VectorType > &f, const AnalyticFunction< VectorType > &psi_0, const std::vector< OctaSym > &Sigma, double epsilon, bool verbose=false)
Compute a set of parallelepipeds enclosing for each symmetry in the set of symmetries ....