00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010
00011
00012 #include "HeavyFlavorAnalysis/Skimming/interface/Combinatorics.h"
00013
00014 using namespace std;
00015
00016
00017
00018
00019 Combinatorics::Combinatorics(Int_t SetQuantity, Int_t SubsetQuantity) :
00020
00021 m_SetQuantity(SetQuantity),
00022 m_SubsetQuantity(SubsetQuantity)
00023 {
00024
00025 CalculatePermutations();
00026 }
00027
00028
00029
00030
00031
00032 Combinatorics::~Combinatorics()
00033 {}
00034
00035
00036
00037
00038
00039 vector <vector <UInt_t> > Combinatorics::GetPermutations()
00040 {
00041 return m_Permutations;
00042 }
00043
00044
00045
00046
00047 Int_t Combinatorics::CalculatePermutations()
00048 {
00049 if (m_SetQuantity < 1 || m_SubsetQuantity < 1 || (m_SetQuantity < m_SubsetQuantity))
00050 {
00051 edm::LogWarning("Combinatorics") << "[Combinatorics] No valid choice of set or subset!" << endl;
00052 return -1;
00053 }
00054
00055 Int_t* currentSubset = new Int_t[m_SubsetQuantity];
00056 Int_t* currentMapping = new Int_t[m_SetQuantity];
00057
00058 initial_subset(m_SubsetQuantity, currentSubset);
00059 do
00060 {
00061 initial_permutation(m_SetQuantity, currentMapping);
00062 do
00063 {
00064 for (UShort_t i = 0; i < m_SubsetQuantity; i++)
00065 {
00066 m_Subset.push_back(currentSubset[currentMapping[i]]);
00067 }
00068 m_Permutations.push_back(m_Subset);
00069 m_Subset.clear();
00070 }
00071 while (next_permutation(m_SubsetQuantity, currentMapping));
00072 }
00073 while (next_subset(m_SetQuantity, m_SubsetQuantity, currentSubset));
00074
00075 delete[] currentSubset;
00076 delete[] currentMapping;
00077
00078 return 0;
00079 }
00080
00081
00082
00083
00084
00085 void Combinatorics::initial_permutation(int size, int *permutation)
00086 {
00087 for (int i = 0; i < size; i++)
00088 {
00089 permutation[i] = i;
00090 }
00091 }
00092
00093
00094
00095
00096
00097 void Combinatorics::initial_subset(int k, int *subset)
00098 {
00099 for (int i = 0; i < k; i++)
00100 {
00101 subset[i] = i;
00102 }
00103 }
00104
00105
00106
00107
00108
00109 Bool_t Combinatorics::next_permutation(int size, int *permutation)
00110 {
00111 int i, j, k;
00112 if (size < 2) return false;
00113 i = size - 2;
00114
00115 while ((permutation[i] > permutation[i+1]) && (i != 0))
00116 {
00117 i--;
00118 }
00119 if ((i == 0) && (permutation[0] > permutation[1])) return false;
00120
00121 k = i + 1;
00122 for (j = i + 2; j < size; j++ )
00123 {
00124 if ((permutation[j] > permutation[i]) && (permutation[j] < permutation[k]))
00125 {
00126 k = j;
00127 }
00128 }
00129
00130
00131 {
00132 int tmp = permutation[i];
00133 permutation[i] = permutation[k];
00134 permutation[k] = tmp;
00135 }
00136
00137 for (j = i + 1; j <= ((size + i) / 2); j++)
00138 {
00139 int tmp = permutation[j];
00140 permutation[j] = permutation[size + i - j];
00141 permutation[size + i - j] = tmp;
00142 }
00143
00144
00145 return true;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155 Bool_t Combinatorics::next_subset(int n, int k, int *subset)
00156 {
00157 int i;
00158 int j;
00159 int jsave;
00160 bool done;
00161
00162 if ( subset[0] < n-k )
00163 {
00164 done = false;
00165 jsave = k-1;
00166 for ( j = 0; j < k-1; j++ )
00167 {
00168 if ( subset[j] + 1 < subset[j+1] )
00169 {
00170 jsave = j;
00171 break;
00172 }
00173 }
00174 for ( i = 0; i < jsave; i++ ) subset[i] = i;
00175 subset[jsave] = subset[jsave] + 1;
00176 }
00177 else
00178 {
00179 done = true;
00180 }
00181
00182 return !done;
00183 }
00184
00185
00186
00187
00188
00189 vector < vector <UInt_t> > Combinatorics::GetCombinations()
00190 {
00191 if (m_Permutations.size() == 0)
00192 {
00193 LogDebug("Combinatorics") << "Nothing to do." << endl;
00194 return m_Combinations;
00195 }
00196
00197 m_Combinations.push_back(m_Permutations.at(0));
00198
00199 for (UInt_t i = 1; i < m_Permutations.size(); i++)
00200 {
00201 if (!EqualPermutation(m_Combinations.back(), m_Permutations.at(i)))
00202 {
00203 m_Combinations.push_back(m_Permutations.at(i));
00204 }
00205 }
00206 return m_Combinations;
00207 }
00208
00209
00210
00211
00212
00213
00214 Int_t Combinatorics::EqualPermutation(vector<UInt_t> p1, vector <UInt_t> p2)
00215 {
00216 if (p1.size() != p2.size())
00217 {
00218 edm::LogWarning("Combinatorics") << "[Combinatorics::EqualPermutation] permutations have different size!" << endl;
00219 return -1;
00220 }
00221
00222 Float_t p1_sum = 0.0;
00223 Float_t p2_sum = 0.0;
00224
00225
00226 for (UInt_t i = 0; i < p1.size(); i++) p1_sum += (1 << p1.at(i));
00227 for (UInt_t i = 0; i < p2.size(); i++) p2_sum += (1 << p2.at(i));
00228
00229 return (p1_sum == p2_sum ? 1 : 0);
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239 vector < vector <UInt_t> > Combinatorics::GetCombinations_2_2()
00240 {
00241
00242 vector< vector <UInt_t> > FinalCombinations;
00243
00244 if (m_Permutations.size() == 0)
00245 {
00246 LogDebug("Combinatorics") << "[Combinatorics::GetCombinations_2_2] Nothing to do." << endl;
00247 return FinalCombinations;
00248 }
00249
00250
00251 if (m_SubsetQuantity != 4)
00252 {
00253 edm::LogWarning("Combinatorics") << "[Combinatorics::GetCombinations_2_2] Subset must be 4." << endl;
00254 return FinalCombinations;
00255 }
00256
00257
00258 Skip_2_2(m_Permutations, FinalCombinations);
00259
00260 return FinalCombinations;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270 vector < vector <UInt_t> > Combinatorics::GetCombinations_2_0()
00271 {
00272
00273 vector< vector <UInt_t> > FinalCombinations;
00274
00275 if (m_Permutations.size() == 0)
00276 {
00277 LogDebug("Combinatorics") << "[Combinatorics::GetCombinations_2_0] Nothing to do." << endl;
00278 return FinalCombinations;
00279 }
00280
00281
00282 if (m_SubsetQuantity != 4)
00283 {
00284 edm::LogWarning("Combinatorics") << "[Combinatorics::GetCombinations_2_0] Subset must be 4." << endl;
00285 return FinalCombinations;
00286 }
00287
00288
00289 Skip_2_0(m_Permutations, FinalCombinations);
00290
00291 return FinalCombinations;
00292 }
00293
00294
00295
00296
00297
00298 void Combinatorics::Skip_2_0(vector <vector <UInt_t> > p1,
00299 vector <vector <UInt_t> > &p2)
00300 {
00301 Bool_t Skip = kFALSE;
00302
00303 p2.push_back(p1.at(0));
00304
00305 for (UShort_t i = 1; i < p1.size(); i++)
00306 {
00307 for (UShort_t j = 0; j < p2.size(); j++)
00308 {
00309 if (EqualPermutation_2_0(p1.at(i), p2.at(j)))
00310 {
00311 Skip = kTRUE;
00312 }
00313 }
00314 if (!Skip) p2.push_back(p1.at(i));
00315
00316 Skip = kFALSE;
00317 }
00318 }
00319
00320
00321
00322
00323
00324 void Combinatorics::Skip_2_2(vector <vector <UInt_t> > p1,
00325 vector <vector <UInt_t> > &p2)
00326 {
00327 Bool_t Skip = kFALSE;
00328
00329 p2.push_back(p1.at(0));
00330
00331 for (UShort_t i = 1; i < p1.size(); i++)
00332 {
00333 for (UShort_t j = 0; j < p2.size(); j++)
00334 {
00335 if (EqualPermutation_2_2(p1.at(i), p2.at(j)))
00336 {
00337 Skip = kTRUE;
00338 }
00339 }
00340 if (!Skip) p2.push_back(p1.at(i));
00341
00342 Skip = kFALSE;
00343 }
00344 }
00345
00346
00347
00348
00349
00350
00351 Int_t Combinatorics::EqualPermutation_2_0(vector<UInt_t> p1, vector<UInt_t> p2)
00352 {
00353 if (p1.size() < 2)
00354 {
00355 edm::LogWarning("Combinatorics") << "[Combinatorics::EqualPermutation_2_0] permutation has wrong size!" << endl;
00356 return -1;
00357 }
00358
00359
00360 if ( ((1 << p1.at(0)) + (1 << p1.at(1)) == (1 << p2.at(0)) + (1 << p2.at(1)) ) &&
00361 p1.at(2) == p2.at(2) && p1.at(3) == p2.at(3) )
00362 {
00363 return 1;
00364 }
00365 return 0;
00366 }
00367
00368
00369
00370
00371
00372
00373 Int_t Combinatorics::EqualPermutation_2_2(vector<UInt_t> p1, vector<UInt_t> p2)
00374 {
00375
00376
00377
00378 if (p1.size() != 4 && p2.size() != 4)
00379 {
00380 edm::LogWarning("Combinatorics") << "[Combinatorics::EqualPermutationTwoByTwo] permutation(s) have wrong size!" << endl;
00381 return -1;
00382 }
00383
00384
00385 if ( ((1 << p1.at(0)) + (1 << p1.at(1)) == (1 << p2.at(0)) + (1 << p2.at(1)) ) &&
00386 ((1 << p1.at(2)) + (1 << p1.at(3)) == (1 << p2.at(2)) + (1 << p2.at(3)) ) )
00387 {
00388 return 1;
00389 }
00390 return 0;
00391 }
00392
00393
00394
00395
00396
00397
00398 Int_t Combinatorics::EqualPermutation_N_1(vector<UInt_t> p1, vector<UInt_t> p2)
00399 {
00400
00401
00402
00403 if (p1.size() != p2.size())
00404 {
00405 edm::LogWarning("Combinatorics") << "[Combinatorics::EqualPermutationTwoByTwo] permutation(s) have wrong size!" << endl;
00406 return -1;
00407 }
00408
00409 return (EqualPermutation(p1, p2) && p1.back() == p2.back() ? 1 : 0);
00410 }
00411
00412
00413
00414
00415
00416 vector < vector <UInt_t> > Combinatorics::GetCombinations_N_1()
00417 {
00418
00419 m_Combinations.clear();
00420 GetCombinations();
00421
00422
00423 vector < vector <UInt_t> > FinalCombinations;
00424
00425 if (m_Combinations.size() == 0)
00426 {
00427 LogDebug("Combinatorics") << "[Combinatorics::GetCombinationsThreeByOne] Nothing to do." << endl;
00428 return FinalCombinations;
00429 }
00430
00431 for (UInt_t i = 0; i < m_Combinations.size(); i++)
00432 {
00433 vector <UInt_t> RotatingPermutation = m_Combinations.at(i);
00434 FinalCombinations.push_back(m_Combinations.at(i));
00435
00436 for (UInt_t j = 1; j < RotatingPermutation.size(); j++)
00437 {
00438 FinalCombinations.push_back(Rotate(RotatingPermutation,j));
00439 }
00440 }
00441 return FinalCombinations;
00442 }
00443
00444
00445
00446
00447
00448 vector<UInt_t> Combinatorics::Rotate(vector <UInt_t> permutation, UInt_t digm_)
00449 {
00450 vector<UInt_t> p;
00451 vector<UInt_t> tmp;
00452
00453 if (permutation.size() <= digm_)
00454 {
00455 edm::LogWarning("Combinatorics") << "[Combinatorics::Rotate] WARNING: More rotations than digm_ in permutation!" << endl;
00456 }
00457
00458
00459 for (UInt_t i = 0; i < digm_; i++)
00460 {
00461 tmp.push_back(permutation.at(i));
00462 }
00463 for (UInt_t j = 0; j < permutation.size() - digm_; j++)
00464 {
00465 p.push_back(permutation.at(j + digm_));
00466 }
00467 for (UInt_t k = 0; k < digm_; k++) p.push_back(tmp.at(k));
00468
00469 return p;
00470 }
00471
00472
00473
00474
00475
00476 void Combinatorics::Print(vector<UInt_t> p)
00477 {
00478
00479 for (UShort_t i = 0; i < p.size(); i++)
00480 {
00481 LogDebug("Combinatorics") << (p.at(i));
00482 }
00483 LogDebug("Combinatorics") << endl;
00484 }
00485
00486
00487
00488
00489
00490 void Combinatorics::Print(vector <vector <UInt_t> > p)
00491 {
00492 LogDebug("Combinatorics") << "**************" << endl;
00493 LogDebug("Combinatorics") << "Permutations: " << p.size() << endl;
00494
00495
00496 for (UShort_t i = 0; i < p.size(); i++)
00497 {
00498 for(UShort_t j = 0; j < (p.at(0)).size(); j++) LogDebug("Combinatorics") << (p.at(i)).at(j);
00499 LogDebug("Combinatorics") << endl;
00500 }
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512