Constructor of the separator.
52 :Sep<SepImage>(f.output_size())
53 {
54
55 int dim = f.output_size();
56 auto v_par =
PEIBOS(f,psi_0,Sigma,epsilon);
57
59 ctc_init.contract(X0);
60
61
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
69 ctc_union.contract(Y0);
70 Y0.inflate(Y0.min_diam()/10.);
71
72
73 if (epsilon_pave == -1)
74 epsilon_pave = Y0.min_diam()/50.;
75
76
77 PavingInOut p = pave(Y0,sep_boundary,epsilon_pave);
78
79
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 {
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());
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
104
105 if (!could_contract)
106 {
107 std::vector<IntervalVector> boxes;
108 split(X0_copy,0.125,boxes);
109 for (auto box: boxes)
110 {
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
131
132
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
142
143 for (const auto& bi : boxes_to_color)
144 {
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 {
159 if (!bjh.is_empty())
160 lbi.push_back(bjh);
161 }
162
164
165
166
167 while (h != prev_x_in)
168 {
170
171 for (const auto& li : lbi)
172 {
173 std::list<IntervalVector> d = h.diff(li);
174
175 if (!d.empty())
176 {
177
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
195 p.tree()->visit(visitor);
196
197
198 SepWrapper<PavingInOut> sep_paving(p);
199
200
201
202 SepInter sep_inter = sep_paving&Y0;
203
204 _sep.push_back(sep_inter);
205 }
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 ....