Public Member Functions | Protected Attributes | List of all members
cmtool::CMergeBookKeeper Class Reference

#include <CMergeBookKeeper.h>

Inheritance diagram for cmtool::CMergeBookKeeper:

Public Member Functions

 CMergeBookKeeper (unsigned short nclusters=0)
 Default constructor. More...
 
void Reset (unsigned short nclusters=0)
 Reset method. More...
 
void ProhibitMerge (unsigned short index1, unsigned short index2)
 Method to set a pair of clusters to prohibit from merging. More...
 
bool MergeAllowed (unsigned short index1, unsigned short index2)
 Method to inqury if a combination is prohibited to merge. More...
 
void Merge (unsigned short index1, unsigned short index2)
 Method to merge 2 clusters via index numbers. More...
 
std::vector< unsigned short > GetMergedSet (unsigned short index1) const
 
bool IsMerged (unsigned short index1, unsigned short index2) const
 
void PassResult (std::vector< std::vector< unsigned short > > &result) const
 
std::vector< std::vector< unsigned short > > GetResult () const
 
void Combine (const CMergeBookKeeper &another)
 
void Report () const
 

Protected Attributes

std::vector< std::vector< bool > > _prohibit_merge
 
size_t _out_cluster_count
 Number of output clusters. More...
 

Detailed Description

A utility class for CMergeManager which merge clusters using merging algorithms. One of major task for CMergeManager is to keep track of which clusters to be merged in the original input. CMergeBookKeeper handles this part. It works with indexes. The user (primarily CMergeManager) provides number of clusters to CMergeBookKeeper's constructor. Then it can ask CMergeBookKeeper to merge two specific clusters by specifying index number of the cluster which has to be smaller than the previously specified number of clusters. CMergeBookKeeper keeps track of which clusters are asked to merge together, and it can be asked to return a vector of merged cluster indexes.

Definition at line 32 of file CMergeBookKeeper.h.

Constructor & Destructor Documentation

cmtool::CMergeBookKeeper::CMergeBookKeeper ( unsigned short  nclusters = 0)

Default constructor.

Definition at line 10 of file CMergeBookKeeper.cxx.

11  {
12  Reset(nclusters);
13  }
void Reset(unsigned short nclusters=0)
Reset method.

Member Function Documentation

void cmtool::CMergeBookKeeper::Combine ( const CMergeBookKeeper another)

Method to combine with another CMergeBookKeeper instance.

Definition at line 278 of file CMergeBookKeeper.cxx.

279  {
280  // Check length compatibility between this instance's result and "another"
281  std::vector<std::vector<unsigned short> > my_result;
282  this->PassResult(my_result);
283  if(my_result.size() != another.size()) {
284  throw CMTException(Form("Input has an incompatible size (%zu != %zu)",
285  my_result.size(),
286  another.size())
287  );
288  return;
289  }
290 
291  // Check if "another" result is different from input
292  std::vector<std::vector<unsigned short> > another_result;
293  another.PassResult(another_result);
294  if(another_result.size() >= my_result.size())
295  throw CMTException(Form("The input has equal or more number of output clusters (%zu>=%zu)",
296  another_result.size(),
297  my_result.size())
298  );
299 
300  // Combine
301  for(auto const& ares : another_result) {
302 
303  if(ares.size()==1) continue;
304 
305  // Get one of cluster to be used for merging
306  unsigned short target = my_result.at(ares.at(0)).at(0);
307 
308  for(auto const &res_index : ares) {
309 
310  for(auto const &orig_index : my_result.at(res_index)) {
311 
312  if(target == orig_index) continue;
313 
314  else this->Merge(target,orig_index);
315 
316  }
317 
318  }
319 
320  }
321 
322  }
void Merge(unsigned short index1, unsigned short index2)
Method to merge 2 clusters via index numbers.
void PassResult(std::vector< std::vector< unsigned short > > &result) const
std::vector< unsigned short > cmtool::CMergeBookKeeper::GetMergedSet ( unsigned short  index1) const

Method to retrieve a vector of cluster indexes which is merged with the input cluster index. All indexes here are regarding the original cluster index.

Definition at line 253 of file CMergeBookKeeper.cxx.

254  {
255 
256  if( index1 >= this->size() )
257  throw CMTException(Form("Invalid cluster index: %d ",index1));
258 
259  auto out_index = this->at(index1);
260  std::vector<unsigned short> result;
261 
262  for(size_t i=0; i<this->size(); ++i)
263  if( this->at(i) == out_index ) result.push_back(i);
264 
265  return result;
266  }
static QCString result
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
std::vector<std::vector<unsigned short> > cmtool::CMergeBookKeeper::GetResult ( ) const
inline

Definition at line 73 of file CMergeBookKeeper.h.

74  {
75  std::vector<std::vector<unsigned short> > result;
76  PassResult(result);
77  return result;
78  }
static QCString result
void PassResult(std::vector< std::vector< unsigned short > > &result) const
bool cmtool::CMergeBookKeeper::IsMerged ( unsigned short  index1,
unsigned short  index2 
) const

Method to ask if a given 2 clusters are already merged. This method is expected to be much faster than obtaining a merged cluster sets from GetMergedIndexes and check if two clusters are merged.

Definition at line 244 of file CMergeBookKeeper.cxx.

245  {
246  if( index1 >= this->size() || index2 >= this->size() )
247  throw CMTException(Form("Invalid cluster index: %d or %d",index1,index2));
248 
249  return this->at(index1) == this->at(index2);
250  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
void cmtool::CMergeBookKeeper::Merge ( unsigned short  index1,
unsigned short  index2 
)

Method to merge 2 clusters via index numbers.

Definition at line 77 of file CMergeBookKeeper.cxx.

78  {
79 
80  if(index1 == index2)
81 
82  throw CMTException(Form("<<%s>> Two input clusters identical (%d)",__FUNCTION__,index1));
83 
84 
85  if( index1 >= this->size() || index2 >= this->size() )
86 
87  throw CMTException(Form("Input cluster index (%d and/or %d) out of range",index1,index2));
88 
89  auto out_index1 = this->at(index1);
90  auto out_index2 = this->at(index2);
91 
92  if(out_index1 == out_index2) return;
93 
94  if(out_index2 < out_index1) std::swap(out_index1,out_index2);
95 
96  if(_prohibit_merge.at(out_index1).at(out_index2-out_index1))
97 
98  throw CMTException(Form("Clusters (%d,%d) correspond to output (%d,%d) which is prohibited to merge",
99  index1,index2,
100  out_index1,out_index2));
101 
102  //
103  // Merge cluster indexes
104  //
105  for(auto &v : (*this)) {
106 
107  if( v == out_index1 || v == out_index2 )
108  v = out_index1;
109  else if( v > out_index2 )
110  v -= 1;
111  }
112 
113  //
114  // Merge prohibit rule
115  //
116  // (1) handle index < out_index1
117  for(size_t index=0; index < out_index1; ++index) {
118 
119  size_t tmp_out_index1 = out_index1 - index;
120  size_t tmp_out_index2 = out_index2 - index;
121 
122  _prohibit_merge.at(index).at(tmp_out_index1) = ( _prohibit_merge.at(index).at(tmp_out_index1)
123  ||
124  _prohibit_merge.at(index).at(tmp_out_index2)
125  );
126 
127  for(size_t in_index=tmp_out_index2;
128  //in_index < _prohibit_merge.at(index).size() - 1;
129  in_index < (_out_cluster_count - index - 1);
130  ++in_index) {
131 
132  /*
133  if(in_index >= (_out_cluster_count - 1 - index))
134 
135  _prohibit_merge.at(index).at(in_index) = false;
136 
137  else
138  */
139  _prohibit_merge.at(index).at(in_index) = _prohibit_merge.at(index).at(in_index+1);
140  }
141 
142  //(*_prohibit_merge.at(index).rbegin()) = false;
143  _prohibit_merge.at(index).at(_out_cluster_count - index - 1) = false;
144 
145  }
146 
147  // (2) handle index == out_index1
148  for(size_t in_index = 1;
149  //in_index < _prohibit_merge.at(out_index1).size() - 1;
150  in_index < (_out_cluster_count - out_index1 - 1);
151  ++in_index) {
152  if( (in_index + out_index1) < out_index2 ) {
153  /*
154  std::cout<<Form("Inspecting1 : (%d,%zu) to (%zu,%zu)",
155  out_index1,in_index,
156  (in_index + out_index1),(out_index2 - (in_index+out_index1)))
157  << std::endl;
158  */
159  _prohibit_merge.at(out_index1).at(in_index) = ( _prohibit_merge.at(out_index1).at(in_index)
160  ||
161  _prohibit_merge.at(in_index + out_index1).at(out_index2 - (in_index+out_index1))
162  );
163  }
164  else {
165  /*
166  std::cout<<Form("Inspecting2 : (%d,%zu) to (%d,%zu) ...",
167  out_index1,in_index+1,
168  out_index2,(in_index+out_index1-out_index2));
169  if(_prohibit_merge.at(out_index1).at(in_index+1)) std::cout<<"T";
170  else std::cout<<"F";
171  std::cout<<",";
172  if(_prohibit_merge.at(out_index2).at(in_index+out_index1-out_index2)) std::cout<<"T";
173  else std::cout<<"F";
174  std::cout<<std::endl;
175  */
176  _prohibit_merge.at(out_index1).at(in_index) = ( _prohibit_merge.at(out_index1).at(in_index+1)
177  ||
178  _prohibit_merge.at(out_index2).at(in_index+1+out_index1-out_index2)
179  );
180 
181  }
182  }
183  //(*_prohibit_merge.at(out_index1).rbegin()) = false;
184  _prohibit_merge.at(out_index1).at(_out_cluster_count - out_index1 - 1) = false;
185 
186  // (3) handle out_index1 < index < out_index2
187  for(size_t index = out_index1+1;
188  index < out_index2;
189  ++index){
190  for(size_t in_index = (out_index2 - index);
191  //in_index < (_prohibit_merge.at(index).size() - 1);
192  in_index < (_out_cluster_count - index - 1);
193  ++in_index)
194 
195  _prohibit_merge.at(index).at(in_index) = _prohibit_merge.at(index).at(in_index+1);
196 
197  //(*_prohibit_merge.at(index).rbegin()) = false;
198  _prohibit_merge.at(index).at(_out_cluster_count - index - 1) = false;
199  }
200  // (4) handle out_index2 <= index
201  for(size_t index = out_index2;
202  //index < (_prohibit_merge.size() - 1);
203  index < (_out_cluster_count - 1);
204  ++index) {
205 
206  for(size_t in_index = 0;
207  in_index < _prohibit_merge.at(index).size();
208  ++in_index)
209 
210  if(in_index < _prohibit_merge.at(index+1).size())
211  _prohibit_merge.at(index).at(in_index) = _prohibit_merge.at(index+1).at(in_index);
212 
213  else
214  _prohibit_merge.at(index).at(in_index) = false;
215 
216  }
217 
218  _out_cluster_count -=1;
219 
220  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
void swap(Handle< T > &a, Handle< T > &b)
size_t _out_cluster_count
Number of output clusters.
std::vector< std::vector< bool > > _prohibit_merge
bool cmtool::CMergeBookKeeper::MergeAllowed ( unsigned short  index1,
unsigned short  index2 
)

Method to inqury if a combination is prohibited to merge.

Definition at line 53 of file CMergeBookKeeper.cxx.

55  {
56 
57  if(index1 == index2)
58 
59  throw CMTException(Form("<<%s>> Two input clusters identical (%d)",__FUNCTION__,index1));
60 
61 
62  if( index1 >= this->size() || index2 >= this->size() )
63 
64  throw CMTException(Form("Input cluster index (%d and/or %d) out of range",index1,index2));
65 
66  auto out_index1 = this->at(index1);
67  auto out_index2 = this->at(index2);
68 
69  if(out_index1 == out_index2) return true;
70 
71  if(out_index2 < out_index1) std::swap(out_index1,out_index2);
72 
73  return !(_prohibit_merge.at(out_index1).at(out_index2-out_index1));
74 
75  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
void swap(Handle< T > &a, Handle< T > &b)
std::vector< std::vector< bool > > _prohibit_merge
void cmtool::CMergeBookKeeper::PassResult ( std::vector< std::vector< unsigned short > > &  result) const

A method to get the full result. The return is a vector of merged cluster indexes (which is a vector of original cluster indexes).

Definition at line 268 of file CMergeBookKeeper.cxx.

269  {
270 
271  result.clear();
272  result.resize(_out_cluster_count, std::vector<unsigned short>());
273 
274  for(size_t i=0; i<this->size(); ++i)
275  result.at(this->at(i)).push_back(i);
276  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
size_t _out_cluster_count
Number of output clusters.
void cmtool::CMergeBookKeeper::ProhibitMerge ( unsigned short  index1,
unsigned short  index2 
)

Method to set a pair of clusters to prohibit from merging.

Definition at line 30 of file CMergeBookKeeper.cxx.

31  {
32  if(index1 == index2)
33 
34  throw CMTException(Form("<<%s>> Two input clusters identical (%d)",__FUNCTION__,index1));
35 
36 
37  if( index1 >= this->size() || index2 >= this->size() )
38 
39  throw CMTException(Form("Input cluster index (%d and/or %d) out of range",index1,index2));
40 
41  auto out_index1 = this->at(index1);
42  auto out_index2 = this->at(index2);
43 
44  if(out_index1 == out_index2)
45  throw CMTException(Form("Cluster %d and %d already merged!",index1,index2));
46 
47  if(out_index2 < out_index1) std::swap(out_index1,out_index2);
48 
49  _prohibit_merge.at(out_index1).at(out_index2-out_index1) = true;
50 
51  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
void swap(Handle< T > &a, Handle< T > &b)
std::vector< std::vector< bool > > _prohibit_merge
void cmtool::CMergeBookKeeper::Report ( ) const

Definition at line 222 of file CMergeBookKeeper.cxx.

223  {
224  std::cout<<"Merge Result:"<<std::endl;
225  for(auto const& v : *this)
226  std::cout<<v<< " ";
227  std::cout<<std::endl<<std::endl;
228 
229  std::cout<<"Prohibit Status:"<<std::endl;
230  for(auto const &bs : _prohibit_merge) {
231 
232  for(auto const &b : bs) {
233 
234  if(b) std::cout<<"\033[93mT\033[00m ";
235  else std::cout<<"\033[95mF\033[00m ";
236 
237  }
238  std::cout<<std::endl;
239  }
240  std::cout<<std::endl;
241 
242  }
std::vector< std::vector< bool > > _prohibit_merge
static bool * b
Definition: config.cpp:1043
QTextStream & endl(QTextStream &s)
void cmtool::CMergeBookKeeper::Reset ( unsigned short  nclusters = 0)

Reset method.

Definition at line 15 of file CMergeBookKeeper.cxx.

16  {
17  _prohibit_merge.clear();
18  _prohibit_merge.reserve(nclusters);
20  std::vector<unsigned short>::reserve(nclusters);
21 
22  for(size_t i=0; i<nclusters; ++i) {
23  this->push_back(i);
24  _prohibit_merge.push_back(std::vector<bool>(nclusters-i,false));
25  }
26  _out_cluster_count = nclusters;
27 
28  }
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
size_t _out_cluster_count
Number of output clusters.
std::vector< std::vector< bool > > _prohibit_merge
vector< vector< double > > clear

Member Data Documentation

size_t cmtool::CMergeBookKeeper::_out_cluster_count
protected

Number of output clusters.

Definition at line 96 of file CMergeBookKeeper.h.

std::vector<std::vector<bool> > cmtool::CMergeBookKeeper::_prohibit_merge
protected

A 2D-map vector that stores pair of clusters for which merging is prohibited

Definition at line 93 of file CMergeBookKeeper.h.


The documentation for this class was generated from the following files: