1818 ******************************************************************************/
1919
2020#include < forward_list>
21+ #include < iostream>
2122
2223#include " sbg/map_entry.hpp"
2324#include " sbg/dom_ord_pwmap.hpp"
@@ -154,7 +155,7 @@ bool DomOrdPWMap::operator==(const PWMapStrategy& other) const
154155 Set cap_dom = short_map.dom ().intersection (long_map.dom ());
155156 Map short_cap_map (cap_dom, short_map.exp ());
156157 Map long_cap_map (cap_dom, long_map.exp ());
157- if (short_cap_map != long_cap_map) {
158+ if (!cap_dom. isEmpty () && short_cap_map != long_cap_map) {
158159 return false ;
159160 }
160161 }
@@ -188,7 +189,7 @@ PWMapStratPtr DomOrdPWMap::operator+(const PWMapStrategy& other) const
188189 Set set_in = SET_FACT.createSet ();
189190 Set set_out = SET_FACT.createSet ();
190191 OrdMapCollection res;
191- processMapsOrd (other,set_in, set_out, res,& DomOrdPWMap::processAdd, false );
192+ processMapsOrd (other, set_in, set_out, res, & DomOrdPWMap::processAdd, false );
192193 return std::make_unique<DomOrdPWMap>(res);
193194}
194195
@@ -197,7 +198,7 @@ void DomOrdPWMap::processAdd(const Map& m1, const Map& m2,
197198 OrdMapCollection& ord_pwmap,
198199 NAT global_pos) const
199200{
200- auto res_add = m1 + m2;
201+ Map res_add = m1 + m2;
201202 if (!res_add.dom ().isEmpty ()) {
202203 advanceHint (ord_pwmap, calculatePerimeter (m2.dom ()).first , global_pos);
203204 emplaceHint (ord_pwmap, res_add, global_pos);
@@ -255,29 +256,51 @@ PWMapStratPtr DomOrdPWMap::restrict(const Set& subdom) const
255256{
256257 OrdMapCollection res;
257258
258- if (subdom.isEmpty ())
259+ if (subdom.isEmpty () || isEmpty () )
259260 return std::make_unique<DomOrdPWMap>(res);
261+
262+ // Indexes list corresponding to remaining maps in short_pw
263+ std::forward_list<size_t > indexes;
264+ int sz = pieces_.size ();
265+ for (int i = sz - 1 ; i >= 0 ; --i) {
266+ indexes.push_front (i);
267+ }
268+
269+ auto begin = pieces_.begin ();
270+ for (const SetPiece& mdi : subdom) {
271+ auto prev_index = indexes.before_begin ();
272+ auto curr_index = indexes.begin ();
273+ while (curr_index != indexes.end ()) {
274+ size_t idx = *curr_index;
275+ const MapEntry& mpe = *(begin + idx);
276+ const Map& map = mpe.first ;
277+ const SetPerimeter& map_sp = mpe.second ;
260278
261- NAT global_pos = 0 ;
262-
263- SetPerimeter short_sp = calculatePerimeter (subdom);
264- auto s_max_per = short_sp.second ;
265-
266- for (const MapEntry& mpe : pieces_) {
267- const Map& m = mpe.first ;
268- const SetPerimeter& m_sp = mpe.second ;
269- auto m_min_per = m_sp.first ;
270-
271- if (doInt (m_sp, short_sp)) {
272- Map res_rest = m.restrict (subdom);
273- if (!res_rest.isEmpty ()) {
274- advanceHint (res, m_min_per, global_pos);
275- emplaceHint (res, res_rest, global_pos);
279+ // Here map is "before" mdi, so it is also "before" all the
280+ // remaining set pieces in subdom, thus it can be discarded.
281+ if (map_sp.second < mdi.minElem ()) {
282+ curr_index = indexes.erase_after (prev_index);
283+ continue ;
276284 }
277- continue ;
285+
286+ // Here map is "after" mdi, so no comparison is needed, and
287+ // the loop of subdom continues to check if this map interacts
288+ // with the following elements of subdom.
289+ if (mdi.maxElem () < map_sp.first )
290+ break ;
291+
292+ // Comparison between map and mdi needed.
293+ Set mdi_set = SET_FACT.createSet (mdi);
294+ SetPerimeter mdi_sp = calculatePerimeter (mdi_set);
295+ if (doInt (map_sp, mdi_sp)) {
296+ Internal::emplaceBack (res, map.restrict (mdi_set));
297+ }
298+
299+ ++prev_index;
300+ ++curr_index;
278301 }
279-
280- if (s_max_per < m_min_per )
302+
303+ if (indexes. empty () )
281304 break ;
282305 }
283306
@@ -315,8 +338,9 @@ PWMapStratPtr DomOrdPWMap::inverse() const
315338
316339 for (const MapEntry& mpe : pieces_){
317340 const Map& inv = mpe.first .minInv ();
318- if (!inv.isEmpty ())
341+ if (!inv.isEmpty ()) {
319342 Internal::emplaceBack (res, inv);
343+ }
320344 }
321345
322346 std::sort (res.begin (),res.end (), operator <);
@@ -330,7 +354,6 @@ PWMapStratPtr DomOrdPWMap::composition(const PWMapStrategy& other) const
330354 DomOrdPWMapCRef othr = static_cast <DomOrdPWMapCRef>(other);
331355
332356 NAT global_pos = 0 ;
333-
334357 for (const MapEntry& o_mpe : othr.pieces_ ) {
335358 const auto & o_m = o_mpe.first ;
336359 auto img = o_m.image ();
@@ -347,13 +370,15 @@ PWMapStratPtr DomOrdPWMap::composition(const PWMapStrategy& other) const
347370
348371 if (doInt (t_sp, i_sp)) {
349372 auto res_com = t_m.composition (o_m);
350- if (!res_com.isEmpty ())
373+ if (!res_com.isEmpty ()) {
351374 emplaceHint (res, res_com, global_pos);
375+ }
352376 continue ;
353377 }
354378
355- if (i_max_per < t_min_per)
379+ if (i_max_per < t_min_per) {
356380 break ;
381+ }
357382 }
358383 }
359384
@@ -382,11 +407,8 @@ PWMapStratPtr DomOrdPWMap::mapInf(unsigned int n) const
382407 DomOrdPWMap *rs = static_cast <DomOrdPWMap *>(res.get ());
383408 old_res = std::make_unique<DomOrdPWMap>(*rs);
384409
385-
386410 PWMapStratPtr new_res = res->composition (*res);
387-
388411 new_res = new_res->reduce ();
389-
390412 res = std::move (new_res);
391413 } while (*old_res != *res);
392414 }
@@ -611,7 +633,7 @@ PWMapStratPtr DomOrdPWMap::minAdjMap(const PWMapStrategy& other) const
611633 Set set_in = SET_FACT.createSet ();
612634 Set set_out = SET_FACT.createSet ();
613635 OrdMapCollection res;
614- processMapsOrd (other, set_in, set_out, res,& DomOrdPWMap::processMinAdjMap, true );
636+ processMapsOrd (other, set_in, set_out, res, & DomOrdPWMap::processMinAdjMap, true );
615637 std::sort (res.begin (), res.end (), operator <);
616638 return std::make_unique<DomOrdPWMap>(res);
617639}
@@ -696,7 +718,9 @@ PWMapStratPtr DomOrdPWMap::firstInv(const Set& subdom) const
696718 continue ;
697719 }
698720 }
699- if (s_max_per < t_min_per) break ;
721+ if (s_max_per < t_min_per) {
722+ break ;
723+ }
700724 }
701725
702726 std::sort (res.begin (), res.end (), operator <);
@@ -719,10 +743,13 @@ PWMapStratPtr DomOrdPWMap::filterMap(bool (*f)(const Map& )) const
719743
720744Set DomOrdPWMap::equalImage (const PWMapStrategy& other) const
721745{
746+ if (isEmpty () || other.isEmpty ())
747+ return SET_FACT.createSet ();
748+
722749 Set set_in = SET_FACT.createSet ();
723750 Set set_out = SET_FACT.createSet ();
724- OrdMapCollection no_used ;
725- processMapsOrd (other, set_in, set_out, no_used,& DomOrdPWMap::processEqualImage
751+ OrdMapCollection unused ;
752+ processMapsOrd (other, set_in, set_out, unused, & DomOrdPWMap::processEqualImage
726753 , false );
727754 return set_out;
728755}
@@ -743,19 +770,21 @@ void DomOrdPWMap::processEqualImage(const Map& m1, const Map& m2,
743770
744771Set DomOrdPWMap::lessImage (const PWMapStrategy& other) const
745772{
746- if (isEmpty () || other.isEmpty ())
747- return SET_FACT.createSet ();
748-
749- DomOrdPWMapCRef othr = static_cast <DomOrdPWMapCRef>(other);
750- Set min_in_pw1 = SET_FACT.createSet ();
751- for (const MapEntry& me1 : pieces_) {
752- for (const MapEntry& me2 : othr.pieces_ ) {
753- min_in_pw1 = min_in_pw1.disjointCup (me1.first .lessImage (me2.first ));
754- }
755- }
773+ Set set_in = SET_FACT.createSet ();
774+ Set set_out = SET_FACT.createSet ();
775+ OrdMapCollection unused;
776+ processMapsOrd (other, set_in, set_out, unused, &DomOrdPWMap::processLessImage
777+ , true );
778+ return set_out;
779+ }
756780
757- return min_in_pw1;
758- }
781+ void DomOrdPWMap::processLessImage (const Map& m1, const Map& m2,
782+ Set& set_in, Set& set_out,
783+ OrdMapCollection& ord_pwmap,
784+ NAT global_pos) const
785+ {
786+ set_out = set_out.disjointCup (m1.lessImage (m2));
787+ }
759788
760789void DomOrdPWMap::processMapsOrd (
761790 const PWMapStrategy& other,
@@ -915,32 +944,32 @@ PWMapStratPtr DomOrdPWMap::compact() const
915944 auto li_curr = indexes.begin ();
916945
917946 while (li_curr != indexes.end ()) {
918- size_t id = *li_curr;
919- const MapEntry& mpe = *(begin + id);
920- const Map& m = mpe.first ;
921- Map new_m (m.dom ().compact (), m.exp ());
947+ size_t id = *li_curr;
948+ const MapEntry& mpe = *(begin + id);
949+ const Map& m = mpe.first ;
950+ Map new_m (m.dom ().compact (), m.exp ());
922951
923- li_curr = indexes.erase_after (li_prev);
924-
925- while (li_curr != indexes.end ()) {
926- size_t idx = *li_curr;
927- const MapEntry& next_mpe = *(begin + idx);
928- const Map& next_map = next_mpe.first ;
929-
930- auto comp = new_m.compact (next_map);
931- if (comp) {
932- new_m = comp.value ();
933- li_curr = indexes.erase_after (li_prev);
934- continue ;
935- }
952+ li_curr = indexes.erase_after (li_prev);
936953
937- ++li_prev;
938- ++li_curr;
954+ while (li_curr != indexes.end ()) {
955+ size_t idx = *li_curr;
956+ const MapEntry& next_mpe = *(begin + idx);
957+ const Map& next_map = next_mpe.first ;
958+
959+ auto comp = new_m.compact (next_map);
960+ if (comp) {
961+ new_m = comp.value ();
962+ li_curr = indexes.erase_after (li_prev);
963+ continue ;
939964 }
940-
941- Internal::emplaceBack (res, new_m);
942- li_prev = indexes.before_begin ();
943- li_curr = indexes.begin ();
965+
966+ ++li_prev;
967+ ++li_curr;
968+ }
969+
970+ Internal::emplaceBack (res, new_m);
971+ li_prev = indexes.before_begin ();
972+ li_curr = indexes.begin ();
944973 }
945974
946975 return std::make_unique<DomOrdPWMap>(res);
0 commit comments