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