00001
00009 #include "Calibration/Tools/interface/GenericHouseholder.h"
00010 #include <cfloat>
00011 #include <cmath>
00012
00013
00014 GenericHouseholder::GenericHouseholder(bool normalise)
00015 :normaliseFlag(normalise)
00016 {
00017 }
00018
00019
00020 GenericHouseholder::~GenericHouseholder()
00021 {
00022 }
00023
00024
00025 std::vector<float> GenericHouseholder::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<float>& energyVector, const int nIter)
00026 {
00027 std::vector<float> solution;
00028 std::vector<float> theCalibVector(energyVector.size(),1.);
00029 std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00030 int Nevents = eventMatrix.size();
00031 int Nchannels = eventMatrix[0].size();
00032
00033
00034 for (int iter=1;iter<=nIter;iter++)
00035 {
00036
00037 solution = iterate(myEventMatrix, energyVector);
00038
00039 if (solution.empty()) return solution;
00040
00041
00042
00043 for (int i=0; i<Nchannels; i++)
00044 {
00045 for (int ievent = 0; ievent<Nevents; ievent++)
00046 {
00047 myEventMatrix[ievent][i] *= solution[i];
00048 }
00049
00050 theCalibVector[i] *= solution[i];
00051 }
00052
00053 }
00054
00055 return theCalibVector;
00056 }
00057
00058
00059 std::vector<float> GenericHouseholder::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<float>& energyVector)
00060 {
00061
00062
00063
00064
00065
00066
00067
00068 std::vector<float> solution;
00069
00070 unsigned int m=eventMatrix.size();
00071 unsigned int n=eventMatrix[0].size();
00072
00073 std::cout << "Householder::runIter(): starting calibration optimization:" << std::endl;
00074 std::cout << " Events:" << m << ", channels: " << n << std::endl;
00075
00076
00077 if (m != energyVector.size())
00078 {
00079 std::cout << "Householder::runIter(): matrix dimensions non-conformant. " << std::endl;
00080 std::cout << " energyVector.size()=" << energyVector.size() << std::endl;
00081 std::cout << " eventMatrix[0].size()=" << eventMatrix[0].size() << std::endl;
00082 std::cout << " ****************** ERROR *********************" << std::endl;
00083 return solution;
00084 }
00085
00086
00087 float e25p;
00088 unsigned int i,j;
00089 std::vector<std::vector<float> > A(eventMatrix);
00090 std::vector<float> energies(energyVector);
00091
00092 float normalisation = 0.;
00093
00094
00095 if (normaliseFlag)
00096 {
00097 std::cout << "Householder::iterate(): Normalising event data" << std::endl;
00098 std::cout << " WARNING: assuming 5x5 filtering has already been done" << std::endl;
00099
00100 for (i=0; i<m; i++)
00101 {
00102 e25p = 0.;
00103 for (j=0;j<n;j++){
00104 e25p += eventMatrix[i][j];
00105 }
00106 e25p /= energyVector[i];
00107 normalisation += e25p;
00108 }
00109 normalisation/=m;
00110 std::cout << " Normalisation = " << normalisation << std::endl;
00111
00112 for (i=0;i<energies.size();++i)
00113 energies[i]*=normalisation;
00114 }
00115
00116
00117
00118
00119 std::vector<std::vector<float> > Acopy(A);
00120 std::vector<float> alpha(n);
00121 std::vector<int> pivot(n);
00122 if( !decompose(m, n, A, alpha, pivot)) {
00123 std::cout << "Householder::runIter(): Failed: Singular condition in decomposition."
00124 << std::endl;
00125 std::cout << "***************** PROBLEM in DECOMPOSITION *************************"<<std::endl;
00126 return solution;
00127 }
00128
00129
00130 float etasqr = DBL_EPSILON*DBL_EPSILON;
00131 std::cout<<"LOOK at DBL_EPSILON :"<<DBL_EPSILON<<std::endl;
00132
00133 std::vector<float> r(energies);
00134 std::vector<float> e(n);
00135
00136
00137 solution.assign(n,0.);
00138 solve(m,n,A,alpha,pivot,r,solution);
00139
00140
00141 for (i=0;i<m;i++) {
00142 r[i]=energies[i];
00143 for (j=0;j<n;j++)
00144 r[i]-=Acopy[i][j]*solution[j];
00145 }
00146
00147 solve(m,n,A,alpha,pivot,r,e);
00148
00149 float normy0=0.;
00150 float norme1=0.;
00151 float norme0;
00152
00153 for (i=0;i<n;i++) {
00154 normy0+=solution[i]*solution[i];
00155 norme1+=e[i]*e[i];
00156 }
00157
00158 std::cout << "Householder::runIter(): applying first correction" << std::endl;
00159 std::cout << " normy0 = " << normy0 << std::endl;
00160 std::cout << " norme1 = " << norme1 << std::endl;
00161
00162
00163
00164 if (norme1>(0.0625*normy0)) {
00165 std::cout << "Householder::runIter(): first correction is too large. Failed."
00166 << std::endl;
00167 }
00168
00169
00170 for (i=0;i<n;i++)
00171 solution[i]+=e[i];
00172
00173 std::cout << "Householder::runIter(): improving solution...." << std::endl;
00174
00175
00176 while (norme1>(etasqr*normy0)) {
00177 std::cout << "Householder::runIter(): norme1 = " << norme1 << std::endl;
00178
00179 for (i=0;i<m;i++) {
00180 r[i] = energies[i];
00181 for (j=0;j<n;j++)
00182 r[i]-=Acopy[i][j]*solution[j];
00183 }
00184
00185
00186 solve(m,n,A,alpha,pivot,r,e);
00187
00188 norme0=norme1;
00189 norme1=0.;
00190 for (i=0;i<n;i++)
00191 norme1+=e[i]*e[i];
00192
00193
00194
00195 if (norme1>(0.0625*norme0))
00196 break;
00197
00198
00199 for (i=0;i<n;i++)
00200 solution[i]+=e[i];
00201 }
00202
00203 return solution;
00204 }
00205
00206
00207 bool GenericHouseholder::decompose(const int m, const int n, std::vector<std::vector<float> >& qr, std::vector<float>& alpha, std::vector<int>& pivot)
00208 {
00209 int i,j,jbar,k;
00210 float beta,sigma,alphak,qrkk;
00211 std::vector<float> y(n);
00212 std::vector<float> sum(n);
00213
00214 std::cout << "Householder::decompose() started" << std::endl;
00215
00216 for (j=0;j<n;j++) {
00217
00218
00219 sum[j]=0.;
00220 for (i=0;i<m;i++)
00221
00222 sum[j]+=qr[i][j]*qr[i][j];
00223
00224 pivot[j] = j;
00225 }
00226
00227 for (k=0;k<n;k++) {
00228
00229
00230 sigma = sum[k];
00231 jbar = k;
00232
00233 for (j=k+1;j<n;j++) {
00234 if (sigma < sum[j]) {
00235 sigma = sum[j];
00236 jbar=j;
00237 }
00238 }
00239
00240 if (jbar != k) {
00241
00242 i = pivot[k];
00243 pivot[k]=pivot[jbar];
00244 pivot[jbar]=i;
00245 sum[jbar]=sum[k];
00246 sum[k]=sigma;
00247
00248 for (i=0;i<m;i++) {
00249 sigma=qr[i][k];
00250 qr[i][k]=qr[i][jbar];
00251
00252 qr[i][jbar]=sigma;
00253
00254 }
00255 }
00256
00257 sigma=0.;
00258 for (i=k;i<m;i++){
00259 sigma+=qr[i][k]*qr[i][k];
00260
00261 }
00262
00263 if (sigma == 0.) {
00264 std::cout << "Householder::decompose() failed" << std::endl;
00265 return false;
00266 }
00267
00268 qrkk = qr[k][k];
00269
00270 if (qrkk < 0.)
00271 alpha[k] = sqrt(sigma);
00272 else
00273 alpha[k] = sqrt(sigma) * (-1.);
00274 alphak = alpha[k];
00275
00276 beta = 1/(sigma-qrkk*alphak);
00277 qr[k][k]=qrkk-alphak;
00278
00279 for (j=k+1;j<n;j++) {
00280 y[j]=0.;
00281 for (i=k;i<m;i++)
00282 y[j]+=qr[i][k]*qr[i][j];
00283 y[j]*=beta;
00284 }
00285
00286 for (j=k+1;j<n;j++) {
00287
00288 for (i=k;i<m;i++) {
00289 qr[i][j]-=qr[i][k]*y[j];
00290 sum[j]-=qr[k][j]*qr[k][j];
00291 }
00292 }
00293 }
00294
00295 std::cout << "Householder::decompose() finished" << std::endl;
00296
00297 return true;
00298 }
00299
00300
00301 void GenericHouseholder::solve(int m, int n, const std::vector<std::vector<float> > &qr, const std::vector<float> &alpha, const std::vector<int> &pivot,
00302 std::vector<float> &r, std::vector<float> &y)
00303 {
00304 std::vector<float> z(n,0.);
00305
00306 float gamma;
00307 int i,j;
00308
00309 std::cout << "Householder::solve() begin" << std::endl;
00310
00311 for (j=0;j<n;j++) {
00312
00313 gamma=0.;
00314 for (i=j;i<m;i++)
00315 gamma+=qr[i][j]*r[i];
00316 gamma/=(alpha[j]*qr[j][j]);
00317
00318 for (i=j;i<m;i++)
00319 r[i]+=gamma*qr[i][j];
00320 }
00321
00322
00323 z[n-1]=r[n-1]/alpha[n-1];
00324
00325
00326 for (i=n-2;i>=0;i--) {
00327 z[i]= r[i];
00328 for (j=i+1;j<n;j++)
00329 z[i]-=qr[i][j]*z[j];
00330 z[i]/=alpha[i];
00331 }
00332
00333
00334 for (i=0;i<n;i++)
00335 y[pivot[i]]=z[i];
00336
00337 std::cout << "Householder::solve() finished." << std::endl;
00338
00339 }