00001
00009 #include "Calibration/Tools/interface/HouseholderDecomposition.h"
00010 #include <cfloat>
00011 #include <cmath>
00012 #include <cstdlib>
00013
00014 HouseholderDecomposition::HouseholderDecomposition(int squareMode_, int mineta_, int maxeta_, int minphi_, int maxphi_)
00015 :squareMode(squareMode_), countEvents(0),mineta(mineta_), maxeta(maxeta_), minphi(minphi_), maxphi(maxphi_)
00016 {
00017 Neta = maxeta - mineta + 1;
00018 if (mineta * maxeta < 0) Neta--;
00019 Nphi = maxphi - minphi + 1;
00020 if (Nphi <0) Nphi += 360;
00021
00022 Nchannels = Neta * Nphi;
00023
00024 Nxtals = squareMode*squareMode;
00025
00026 sigmaReplacement = 0.00001;
00027
00028 }
00029
00030 HouseholderDecomposition::~HouseholderDecomposition()
00031 {
00032 }
00033
00034
00035 std::vector<float> HouseholderDecomposition::runRegional(const std::vector<std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi, const std::vector<float>& energyVector, const int& nIter, const int& regLength)
00036 {
00037
00038 makeRegions(regLength);
00039
00040 Nevents = eventMatrix.size();
00041
00042 std::vector<float> totalSolution(Nchannels,1.);
00043 std::vector<float> iterSolution(Nchannels,1.);
00044 std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00045 std::vector<float> myEnergyVector(energyVector);
00046
00047
00048 for (int iter=1;iter<=nIter;iter++)
00049 {
00050
00051 for (unsigned int ireg=0; ireg<regMinEta.size(); ireg++)
00052 {
00053 std::vector<float> regIterSolution, regEnergyVector;
00054 std::vector<int> regVmaxCeta, regVmaxCphi;
00055 std::vector<std::vector<float> > regEventMatrix;
00056
00057
00058 HouseholderDecomposition regionalHH(squareMode,regMinEta[ireg],regMaxEta[ireg],regMinPhi[ireg],regMaxPhi[ireg]);
00059
00060
00061 for (unsigned int ia=0; ia<VmaxCeta.size(); ia++)
00062 {
00063 if ((VmaxCeta[ia] >= regMinEta[ireg]) && (VmaxCeta[ia] <= regMaxEta[ireg])
00064 && (VmaxCphi[ia] >= regMinPhi[ireg]) && (VmaxCphi[ia] <= regMaxPhi[ireg]))
00065 {
00066
00067 regVmaxCeta.push_back(VmaxCeta[ia]);
00068 regVmaxCphi.push_back(VmaxCphi[ia]);
00069
00070 std::vector<float> regEvent = myEventMatrix[ia];
00071 float regEnergy = energyVector[ia];
00072 for (int i2=0; i2<Nxtals; i2++)
00073 {
00074 int iFullReg = regionalHH.indexSqr2Reg(i2, VmaxCeta[ia], VmaxCphi[ia]);
00075 if (iFullReg <0)
00076 {
00077 regEnergy -= regEvent[i2];
00078 regEvent[i2] = 0.;
00079 }
00080 }
00081 regEventMatrix.push_back(regEvent);
00082 regEnergyVector.push_back(regEnergy);
00083 }
00084 }
00085
00086
00087
00088
00089 regIterSolution = regionalHH.iterate(regEventMatrix, regVmaxCeta, regVmaxCphi, regEnergyVector);
00090
00091
00092
00093
00094 for (unsigned int i1=0; i1<regIterSolution.size(); i1++)
00095 {
00096 int regFrame = regLength/2;
00097 int currRegPhiRange = regMaxPhi[ireg] - regMinPhi[ireg] + 1;
00098 int currRegEta = i1 / currRegPhiRange + regMinEta[ireg];
00099 int currRegPhi = i1 % currRegPhiRange + regMinPhi[ireg];
00100 int newindex = -100;
00101
00102 if ( (currRegEta >= (regMinEta[ireg]+regFrame*(!(regMinEta[ireg]==mineta))) ) &&
00103 (currRegEta <= (regMaxEta[ireg]-regFrame*(!(regMaxEta[ireg]==maxeta))) ) &&
00104 (currRegPhi >= (regMinPhi[ireg]+regFrame*(!(regMinPhi[ireg]==minphi))) ) &&
00105 (currRegPhi <= (regMaxPhi[ireg]-regFrame*(!(regMaxPhi[ireg]==maxphi))) ) )
00106 {
00107 newindex = (currRegEta-mineta)*Nphi + currRegPhi-minphi;
00108 iterSolution[newindex] = regIterSolution[i1];
00109 }
00110 }
00111 }
00112
00113 if (iterSolution.empty()) return iterSolution;
00114
00115
00116 for (int ievent = 0; ievent<Nevents; ievent++)
00117 {
00118 myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], VmaxCeta[ievent], VmaxCphi[ievent], iterSolution);
00119 }
00120
00121
00122 for (int i=0; i<Nchannels; i++)
00123 {
00124 totalSolution[i] *= iterSolution[i];
00125 }
00126
00127 }
00128
00129 return totalSolution;
00130
00131 }
00132
00133
00134 std::vector<float> HouseholderDecomposition::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi, const std::vector<float>& energyVector, const int& nIter, const bool& normalizeFlag)
00135 {
00136 Nevents = eventMatrix.size();
00137
00138 std::vector<float> totalSolution(Nchannels,1.);
00139 std::vector<float> iterSolution;
00140 std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00141 std::vector<float> myEnergyVector(energyVector);
00142
00143 int i, j;
00144
00145
00146 for (int iter=1;iter<=nIter;iter++)
00147 {
00148
00149
00150 float sumOverEnergy;
00151 if (normalizeFlag)
00152 {
00153 float scale = 0.;
00154
00155 for (i=0; i<Nevents; i++)
00156 {
00157 sumOverEnergy = 0.;
00158 for (j=0; j<Nxtals; j++) {sumOverEnergy += myEventMatrix[i][j];}
00159 sumOverEnergy /= myEnergyVector[i];
00160 scale += sumOverEnergy;
00161 }
00162 scale /= Nevents;
00163
00164 for (i=0; i<Nevents; i++) {myEnergyVector[i] *= scale;}
00165 }
00166
00167
00168
00169
00170 iterSolution = iterate(myEventMatrix,VmaxCeta,VmaxCphi,myEnergyVector);
00171
00172 if (iterSolution.empty()) return iterSolution;
00173
00174
00175 for (int ievent = 0; ievent<Nevents; ievent++)
00176 {
00177 myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], VmaxCeta[ievent], VmaxCphi[ievent], iterSolution);
00178 }
00179
00180 for (int i=0; i<Nchannels; i++)
00181 {
00182
00183 totalSolution[i] *= iterSolution[i];
00184 }
00185
00186 }
00187
00188 return totalSolution;
00189 }
00190
00191
00192
00193 std::vector<float> HouseholderDecomposition::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi, const std::vector<float>& energyVectorOrig)
00194 {
00195 std::vector<float> solution;
00196
00197 Nevents=eventMatrix.size();
00198
00199 if (Nchannels > Nevents)
00200 {
00201 std::cout << "Householder::runIter(): more channels to calibrate than events available. " << std::endl;
00202 std::cout << " Nchannels=" << Nchannels << std::endl;
00203 std::cout << " Nevents=" << Nevents << std::endl;
00204 std::cout << " ****************** ERROR *********************" << std::endl;
00205 return solution;
00206 }
00207
00208
00209 eventMatrixOrig = unzipMatrix(eventMatrix,VmaxCeta,VmaxCphi);
00210
00211 if (eventMatrixOrig.size() != energyVectorOrig.size())
00212 {
00213 std::cout << "Householder::runIter(): matrix dimensions non-conformant. " << std::endl;
00214 std::cout << " energyVectorOrig.size()=" << energyVectorOrig.size() << std::endl;
00215 std::cout << " eventMatrixOrig.size()=" << eventMatrixOrig.size() << std::endl;
00216 std::cout << " ****************** ERROR *********************" << std::endl;
00217 return solution;
00218 }
00219
00220
00221 int i,j;
00222 eventMatrixProc = eventMatrixOrig;
00223 energyVectorProc = energyVectorOrig;
00224 std::vector<float> e(Nchannels);
00225 alpha.assign(Nchannels,0.);
00226 pivot.assign(Nchannels,0);
00227
00228
00229
00230 bool decomposeSuccess = decompose();
00231
00232 if( !decomposeSuccess )
00233 {
00234 std::cout << "Householder::runIter(): Failed: Singular condition in decomposition."<< std::endl;
00235 std::cout << "***************** PROBLEM in DECOMPOSITION *************************"<<std::endl;
00236 return solution;
00237 }
00238
00239
00240 float mydbleps = 2.22045e-16;
00241 float etasqr = mydbleps*mydbleps;
00242
00243
00244
00245
00246
00247 solution.assign(Nchannels,0.);
00248 solve(solution);
00249
00250
00251
00252 for (i=0;i<Nevents;i++)
00253 {
00254 energyVectorProc[i] = energyVectorOrig[i];
00255 for (j=0; j<Nchannels; j++)
00256 {
00257 energyVectorProc[i]-=eventMatrixOrig[i][j]*solution[j];
00258 }
00259 }
00260
00261
00262
00263
00264 solve(e);
00265
00266 float normy0=0.;
00267 float norme1=0.;
00268 float norme0;
00269
00270
00271
00272
00273 for (i=0;i<Nchannels;i++)
00274 {
00275 normy0 += solution[i] * solution[i];
00276 norme1 += e[i] * e[i];
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 if (norme1>(0.0625*normy0))
00286 {
00287
00288 }
00289
00290
00291 for (i=0; i<Nchannels; i++)
00292 {
00293 solution[i]+=e[i];
00294 }
00295
00296
00297
00298
00299
00300 while (norme1>(etasqr*normy0))
00301 {
00302
00303
00304 for (i=0; i<Nevents; i++)
00305 {
00306 energyVectorProc[i] = energyVectorOrig[i];
00307 for (j=0; j<Nchannels; j++)
00308 {
00309 energyVectorProc[i] -= eventMatrixOrig[i][j] * solution[j];
00310 }
00311 }
00312
00313
00314 solve(e);
00315
00316 norme0 = norme1;
00317 norme1 = 0.;
00318
00319 for (i=0;i<Nchannels;i++)
00320 {
00321 norme1+=e[i]*e[i];
00322 }
00323
00324
00325
00326 if (norme1>(0.0625*norme0)) break;
00327
00328
00329 for (i=0;i<Nchannels;i++)
00330 {
00331 solution[i]+=e[i];
00332 }
00333 }
00334
00335
00336 eventMatrixOrig.clear();
00337 eventMatrixProc.clear();
00338 energyVectorProc.clear();
00339 alpha.clear();
00340 pivot.clear();
00341
00342
00343 return solution;
00344 }
00345
00346
00347 bool HouseholderDecomposition::decompose()
00348 {
00349 int i,j,jbar,k;
00350 float beta,sigma,alphak,eventMatrixkk;
00351 std::vector<float> y(Nchannels);
00352 std::vector<float> sum(Nchannels);
00353
00354
00355
00356 for (j=0;j<Nchannels;j++)
00357 {
00358
00359 sum[j]=0.;
00360 for (i=0;i<Nevents;i++)
00361 sum[j]+=eventMatrixProc[i][j]*eventMatrixProc[i][j];
00362
00363
00364 pivot[j] = j;
00365 }
00366
00367 for (k=0;k<Nchannels;k++)
00368 {
00369
00370 sigma = sum[k];
00371 jbar = k;
00372
00373
00374
00375 for (j=k+1;j<Nchannels;j++)
00376 {
00377 if (sum[j] > sigma)
00378 {
00379 sigma = sum[j];
00380 jbar=j;
00381 }
00382 }
00383
00384 if (jbar != k)
00385 {
00386
00387
00388
00389 i = pivot[k];
00390 pivot[k]=pivot[jbar];
00391 pivot[jbar]=i;
00392
00393 sum[jbar]=sum[k];
00394 sum[k]=sigma;
00395
00396 for (i=0;i<Nevents;i++)
00397 {
00398 sigma=eventMatrixProc[i][k];
00399 eventMatrixProc[i][k]=eventMatrixProc[i][jbar];
00400 eventMatrixProc[i][jbar]=sigma;
00401 }
00402 }
00403
00404
00405 sigma=0.;
00406 for (i=k;i<Nevents;i++)
00407 {
00408 sigma+=eventMatrixProc[i][k]*eventMatrixProc[i][k];
00409 }
00410
00411
00412 if (sigma == 0.)
00413 {
00414
00415
00416
00417 sigma = sigmaReplacement;
00418
00419 }
00420
00421
00422
00423
00424
00425
00426 eventMatrixkk = eventMatrixProc[k][k];
00427
00428 if (eventMatrixkk < 0.)
00429 alpha[k] = sqrt(sigma);
00430 else
00431 alpha[k] = sqrt(sigma) * (-1.);
00432
00433 alphak = alpha[k];
00434
00435 beta = 1 / (sigma - eventMatrixkk * alphak);
00436
00437 eventMatrixProc[k][k] = eventMatrixkk - alphak;
00438
00439 for (j=k+1; j<Nchannels; j++)
00440 {
00441 y[j] = 0.;
00442
00443 for (i=k; i<Nevents; i++)
00444 {
00445 y[j] += eventMatrixProc[i][k] * eventMatrixProc[i][j];
00446 }
00447
00448 y[j] *= beta;
00449 }
00450
00451 for (j=k+1; j<Nchannels; j++)
00452 {
00453 for (i=k; i<Nevents; i++)
00454 {
00455 eventMatrixProc[i][j] -= eventMatrixProc[i][k] * y[j];
00456 sum[j] -= eventMatrixProc[k][j] * eventMatrixProc[k][j];
00457 }
00458 }
00459 }
00460
00461
00462
00463 return true;
00464 }
00465
00466
00467 void HouseholderDecomposition::solve(std::vector<float> &y)
00468 {
00469 std::vector<float> z(Nchannels,0.);
00470
00471 float gamma;
00472 int i,j;
00473
00474
00475
00476 for (j=0; j<Nchannels; j++)
00477 {
00478
00479 gamma = 0.;
00480 for (i=j; i<Nevents; i++)
00481 {
00482 gamma += eventMatrixProc[i][j] * energyVectorProc[i];
00483 }
00484 gamma /= (alpha[j] * eventMatrixProc[j][j]);
00485
00486 for (i=j; i<Nevents; i++)
00487 {
00488 energyVectorProc[i] += gamma * eventMatrixProc[i][j];
00489 }
00490 }
00491
00492 z[Nchannels-1] = energyVectorProc[Nchannels-1] / alpha[Nchannels-1];
00493
00494 for (i=Nchannels-2; i>=0; i--)
00495 {
00496 z[i] = energyVectorProc[i];
00497 for (j=i+1; j<Nchannels; j++)
00498 {
00499 z[i] -= eventMatrixProc[i][j]*z[j];
00500 }
00501 z[i] /= alpha[i];
00502 }
00503
00504 for (i=0; i<Nchannels; i++)
00505 {
00506 y[pivot[i]] = z[i];
00507 }
00508
00509
00510
00511 }
00512
00513
00514 std::vector<float> HouseholderDecomposition::recalibrateEvent(const std::vector<float>& eventSquare, const int& maxCeta, const int& maxCphi, const std::vector<float>& recalibrateVector)
00515 {
00516 std::vector<float> newEventSquare(eventSquare);
00517 int iFull;
00518
00519 for (int i=0; i<Nxtals; i++)
00520 {
00521 iFull = indexSqr2Reg(i, maxCeta, maxCphi);
00522 if (iFull >=0)
00523 newEventSquare[i] *= recalibrateVector[iFull];
00524 }
00525 return newEventSquare;
00526 }
00527
00528
00529 int HouseholderDecomposition::indexSqr2Reg(const int& sqrIndex, const int& maxCeta, const int& maxCphi)
00530 {
00531 int regionIndex;
00532
00533
00534 int curr_eta = maxCeta - squareMode/2 + sqrIndex%squareMode;
00535 if (curr_eta * maxCeta <= 0) {if (maxCeta > 0) curr_eta--; else curr_eta++; }
00536
00537 int curr_phi = maxCphi - squareMode/2 + sqrIndex/squareMode;
00538 if (curr_phi < 1) curr_phi += 360;
00539 if (curr_phi > 360) curr_phi -= 360;
00540
00541 bool negPhiDirection = (maxphi < minphi);
00542 int iFullphi;
00543
00544 regionIndex = -1;
00545
00546 if (curr_eta >= mineta && curr_eta <= maxeta)
00547 if ( (!negPhiDirection && (curr_phi >= minphi && curr_phi <= maxphi)) ||
00548 (negPhiDirection && !(curr_phi >= minphi && curr_phi <= maxphi)) )
00549 {
00550 iFullphi = curr_phi - minphi;
00551 if (iFullphi < 0) iFullphi += 360;
00552 regionIndex = (curr_eta - mineta) * (maxphi - minphi + 1 + 360*negPhiDirection) + iFullphi;
00553 }
00554
00555 return regionIndex;
00556 }
00557
00558 std::vector<std::vector<float> > HouseholderDecomposition::unzipMatrix(const std::vector< std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi)
00559 {
00560 std::vector< std::vector<float> > fullMatrix;
00561
00562 int iFull;
00563
00564 for (int i=0; i<Nevents; i++)
00565 {
00566 std::vector<float> foo(Nchannels,0.);
00567 for (int k=0; k<Nxtals; k++)
00568 {
00569 iFull = indexSqr2Reg(k, VmaxCeta[i], VmaxCphi[i]);
00570 if (iFull >=0)
00571 foo[iFull] = eventMatrix[i][k];
00572 }
00573 fullMatrix.push_back(foo);
00574 }
00575
00576 return fullMatrix;
00577 }
00578
00579 void HouseholderDecomposition::makeRegions(const int& regLength)
00580 {
00581
00582 int regFrame = squareMode/2;
00583
00584 int remEta = Neta % regLength;
00585 if (remEta > regLength/2) remEta -= regLength;
00586 int numSubRegEta = Neta / regLength + (remEta < 0)*1;
00587
00588 int addtoEta = remEta / numSubRegEta;
00589 int addtomoreEta = remEta % numSubRegEta;
00590
00591
00592 int remPhi = Nphi % regLength;
00593 if (remPhi > regLength/2) remPhi -= regLength;
00594 int numSubRegPhi = Nphi / regLength + (remPhi < 0)*1;
00595
00596 int addtoPhi = remPhi / numSubRegPhi;
00597 int addtomorePhi = remPhi % numSubRegPhi;
00598
00599
00600 int addedLengthEta = 0;
00601 int addedLengthPhi = 0;
00602 int startIndexEta = mineta;
00603 int startIndexPhi;
00604 int endIndexEta = 0;
00605 int endIndexPhi;
00606 for (int i=0; i < numSubRegEta; i++)
00607 {
00608 addedLengthEta = regLength + addtoEta + addtomoreEta/abs(addtomoreEta)*(i<abs(addtomoreEta));
00609 endIndexEta = startIndexEta + addedLengthEta - 1;
00610
00611 startIndexPhi = minphi;
00612 endIndexPhi = 0;
00613 for (int j=0; j < numSubRegPhi; j++)
00614 {
00615 addedLengthPhi = regLength + addtoPhi + addtomorePhi/abs(addtomorePhi)*(j<abs(addtomorePhi));
00616 endIndexPhi = startIndexPhi + addedLengthPhi - 1;
00617
00618 regMinPhi.push_back(startIndexPhi - regFrame*(j!=0) );
00619 regMaxPhi.push_back(endIndexPhi + regFrame*(j!=(numSubRegPhi-1)) );
00620 regMinEta.push_back(startIndexEta - regFrame*(i!=0) );
00621 regMaxEta.push_back(endIndexEta + regFrame*(i!=(numSubRegEta-1)) );
00622
00623 startIndexPhi = endIndexPhi + 1;
00624 }
00625 startIndexEta = endIndexEta + 1;
00626 }
00627
00628
00629
00630
00631
00632
00633 }