@@ -67,7 +67,8 @@ void BipartiteSBG::addSetVertex(const Set& X, const Set& Y)
6767{
6868 Set vertices = X.cup (Y);
6969 if (!vertices.intersection (_V).isEmpty ()) {
70- Util::ERROR (" Trying to add existing vertices: " , vertices, " to SBG\n " );
70+ Util::ERROR (" BipartiteSBG::addSetVertex: trying to add existing vertices: "
71+ , vertices, " to SBG\n " );
7172 } else if (!vertices.isEmpty ()) {
7273 _V = _V.cup (vertices);
7374 Set set_vertices = _Vmap.image ();
@@ -86,8 +87,8 @@ void BipartiteSBG::addSetEdge(const PWMap& pw1, const PWMap& pw2)
8687 Set edges1 = pw1.domain ();
8788 Set edges2 = pw2.domain ();
8889 if (edges1 != edges2) {
89- // TODO
90- Util::ERROR ( " The domain of " , edges1, " is different from " , edges2, " \n " );
90+ Util::ERROR ( " BipartiteSBG::addSetEdge: " , edges1, " is different from "
91+ , edges2, " \n " );
9192 } else if (edges1.intersection (_E).isEmpty ()) {
9293 Set edges = edges1;
9394 if (!edges.isEmpty ()) {
@@ -102,7 +103,8 @@ void BipartiteSBG::addSetEdge(const PWMap& pw1, const PWMap& pw2)
102103 _Emap.emplace (edges, max + one_all_dims);
103104 }
104105 } else {
105- Util::ERROR (" Trying to add existing edges: " , edges1, " to SBG\n " );
106+ Util::ERROR (" BipartiteSBG::addSetEdge: trying to add existing edges: "
107+ , edges1, " to SBG\n " );
106108 }
107109}
108110
@@ -122,6 +124,67 @@ std::ostream& operator<<(std::ostream& out, const BipartiteSBG& g)
122124 return out;
123125}
124126
127+ // Extra operations ------------------------------------------------------------
128+
129+ BipartiteSBG copy (unsigned int copies, BipartiteSBG sbg)
130+ {
131+ if (copies == 0 ) {
132+ Util::ERROR (" BipartiteSBG::copy: zeros copies is not allowed\n " );
133+ }
134+
135+ Set X = sbg.X ();
136+ Set Y = sbg.Y ();
137+ Set V = sbg.V ();
138+ PWMap Vmap = sbg.Vmap ();
139+ PWMap map1 = sbg.map1 ();
140+ PWMap map2 = sbg.map2 ();
141+ PWMap Emap = sbg.Emap ();
142+ Set E = sbg.E ();
143+
144+ for (unsigned int j = 1 ; j < copies; ++j) {
145+ MD_NAT max_v = sbg.V ().maxElem ();
146+ Set set_vertices = Vmap.image ();
147+ while (!set_vertices.isEmpty ()) {
148+ Set min_elem_set = SET_FACT .createSet (set_vertices.minElem ());
149+ Set vertices = Vmap.preImage (min_elem_set);
150+ Set jth_X = vertices.intersection (X);
151+ Set jth_Y = vertices.intersection (Y);
152+ sbg.addSetVertex (jth_X.offset (max_v), jth_Y.offset (max_v));
153+
154+ set_vertices = set_vertices.difference (min_elem_set);
155+ }
156+
157+ Expression offset_v;
158+ for (std::size_t k = 0 ; k < max_v.arity (); ++k) {
159+ offset_v = offset_v.cartesianProduct (Expression{1 , max_v[k]});
160+ }
161+ PWMap offset_pw_v = PWMAP_FACT .createPWMap (Map{V, offset_v});
162+
163+ MD_NAT max_e = sbg.E ().maxElem ();
164+ Expression offset_e;
165+ for (std::size_t k = 0 ; k < max_e.arity (); ++k) {
166+ offset_e = offset_e.cartesianProduct (Expression{1 , max_e[k]});
167+ }
168+ PWMap offset_pw_e = PWMAP_FACT .createPWMap (Map{E, offset_e});
169+ PWMap inverse_offset_pw_e = offset_pw_e.inverse ();
170+
171+ Set set_edges = Emap.image ();
172+ while (!set_edges.isEmpty ()) {
173+ Set min_elem_set = SET_FACT .createSet (set_edges.minElem ());
174+ Set edges = Emap.preImage (min_elem_set);
175+ PWMap pw1 = map1.restrict (edges);
176+ PWMap pw2 = map2.restrict (edges);
177+ pw1 = offset_pw_v.composition (pw1.composition (inverse_offset_pw_e));
178+ pw2 = offset_pw_v.composition (pw2.composition (inverse_offset_pw_e));
179+ sbg.addSetEdge (pw1, pw2);
180+
181+ set_edges = set_edges.difference (min_elem_set);
182+ }
183+ }
184+
185+ return sbg;
186+ }
187+
125188} // namespace LIB
126189
127190} // namespace SBG
0 commit comments