16 const std::vector<float>& energyVector,
18 std::vector<float> solution;
19 std::vector<float> theCalibVector(energyVector.size(), 1.);
20 std::vector<std::vector<float> > myEventMatrix(eventMatrix);
21 int Nevents = eventMatrix.size();
22 int Nchannels = eventMatrix[0].size();
25 for (
int iter = 1; iter <= nIter; iter++) {
27 solution =
iterate(myEventMatrix, energyVector);
34 for (
int i = 0;
i < Nchannels;
i++) {
35 for (
int ievent = 0; ievent < Nevents; ievent++) {
36 myEventMatrix[ievent][
i] *= solution[
i];
39 theCalibVector[
i] *= solution[
i];
44 return theCalibVector;
48 const std::vector<float>& energyVector) {
56 std::vector<float> solution;
58 unsigned int m = eventMatrix.size();
59 unsigned int n = eventMatrix[0].size();
61 std::cout <<
"Householder::runIter(): starting calibration optimization:" << std::endl;
62 std::cout <<
" Events:" << m <<
", channels: " << n << std::endl;
65 if (m != energyVector.size()) {
66 std::cout <<
"Householder::runIter(): matrix dimensions non-conformant. " << std::endl;
67 std::cout <<
" energyVector.size()=" << energyVector.size() << std::endl;
68 std::cout <<
" eventMatrix[0].size()=" << eventMatrix[0].size() << std::endl;
69 std::cout <<
" ****************** ERROR *********************" << std::endl;
76 std::vector<std::vector<float> >
A(eventMatrix);
77 std::vector<float> energies(energyVector);
79 float normalisation = 0.;
83 std::cout <<
"Householder::iterate(): Normalising event data" << std::endl;
84 std::cout <<
" WARNING: assuming 5x5 filtering has already been done" << std::endl;
86 for (i = 0; i <
m; i++) {
88 for (j = 0; j <
n; j++) {
89 e25p += eventMatrix[
i][
j];
91 e25p /= energyVector[
i];
92 normalisation += e25p;
95 std::cout <<
" Normalisation = " << normalisation << std::endl;
97 for (i = 0; i < energies.size(); ++
i)
98 energies[i] *= normalisation;
103 std::vector<std::vector<float> > Acopy(A);
104 std::vector<float>
alpha(n);
105 std::vector<int> pivot(n);
107 std::cout <<
"Householder::runIter(): Failed: Singular condition in decomposition." << std::endl;
108 std::cout <<
"***************** PROBLEM in DECOMPOSITION *************************" << std::endl;
113 float etasqr = DBL_EPSILON * DBL_EPSILON;
114 std::cout <<
"LOOK at DBL_EPSILON :" << DBL_EPSILON << std::endl;
116 std::vector<float>
r(energies);
117 std::vector<float>
e(n);
120 solution.assign(n, 0.);
121 solve(m, n, A, alpha, pivot, r, solution);
124 for (i = 0; i <
m; i++) {
126 for (j = 0; j <
n; j++)
127 r[i] -= Acopy[i][j] * solution[j];
130 solve(m, n, A, alpha, pivot, r, e);
136 for (i = 0; i <
n; i++) {
137 normy0 += solution[
i] * solution[
i];
138 norme1 += e[
i] * e[
i];
141 std::cout <<
"Householder::runIter(): applying first correction" << std::endl;
142 std::cout <<
" normy0 = " << normy0 << std::endl;
143 std::cout <<
" norme1 = " << norme1 << std::endl;
147 if (norme1 > (0.0625 * normy0)) {
148 std::cout <<
"Householder::runIter(): first correction is too large. Failed." << std::endl;
152 for (i = 0; i <
n; i++)
155 std::cout <<
"Householder::runIter(): improving solution...." << std::endl;
158 while (norme1 > (etasqr * normy0)) {
159 std::cout <<
"Householder::runIter(): norme1 = " << norme1 << std::endl;
161 for (i = 0; i <
m; i++) {
163 for (j = 0; j <
n; j++)
164 r[i] -= Acopy[i][j] * solution[j];
168 solve(m, n, A, alpha, pivot, r, e);
172 for (i = 0; i <
n; i++)
173 norme1 += e[i] * e[i];
177 if (norme1 > (0.0625 * norme0))
181 for (i = 0; i <
n; i++)
191 std::vector<float>&
alpha,
192 std::vector<int>& pivot) {
194 float beta, sigma, alphak, qrkk;
195 std::vector<float>
y(n);
196 std::vector<float> sum(n);
198 std::cout <<
"Householder::decompose() started" << std::endl;
200 for (j = 0; j <
n; j++) {
204 for (i = 0; i <
m; i++)
206 sum[j] += qr[i][j] * qr[i][j];
211 for (k = 0; k <
n; k++) {
217 for (j = k + 1; j <
n; j++) {
218 if (sigma < sum[j]) {
227 pivot[
k] = pivot[jbar];
232 for (i = 0; i <
m; i++) {
234 qr[
i][
k] = qr[
i][jbar];
242 for (i = k; i <
m; i++) {
243 sigma += qr[
i][
k] * qr[
i][
k];
248 std::cout <<
"Householder::decompose() failed" << std::endl;
255 alpha[
k] =
sqrt(sigma);
257 alpha[
k] =
sqrt(sigma) * (-1.);
260 beta = 1 / (sigma - qrkk * alphak);
261 qr[
k][
k] = qrkk - alphak;
263 for (j = k + 1; j <
n; j++) {
265 for (i = k; i <
m; i++)
266 y[j] += qr[i][k] * qr[i][j];
270 for (j = k + 1; j <
n; j++) {
271 for (i = k; i <
m; i++) {
272 qr[
i][
j] -= qr[
i][
k] * y[
j];
273 sum[
j] -= qr[
k][
j] * qr[
k][
j];
278 std::cout <<
"Householder::decompose() finished" << std::endl;
286 const std::vector<float>&
alpha,
287 const std::vector<int>& pivot,
288 std::vector<float>&
r,
289 std::vector<float>&
y) {
290 std::vector<float>
z(n, 0.);
295 std::cout <<
"Householder::solve() begin" << std::endl;
297 for (j = 0; j <
n; j++) {
300 for (i = j; i <
m; i++)
301 gamma += qr[i][j] * r[i];
302 gamma /= (alpha[
j] * qr[
j][
j]);
304 for (i = j; i <
m; i++)
305 r[i] += gamma * qr[i][j];
309 z[n - 1] = r[n - 1] / alpha[n - 1];
312 for (i = n - 2; i >= 0; i--) {
314 for (j = i + 1; j <
n; j++)
315 z[i] -= qr[i][j] * z[j];
320 for (i = 0; i <
n; i++)
323 std::cout <<
"Householder::solve() finished." << std::endl;
bool decompose(const int m, const int n, std::vector< std::vector< float > > &qr, std::vector< float > &alpha, std::vector< int > &pivot)
void solve(int m, int n, const std::vector< std::vector< float > > &qr, const std::vector< float > &alpha, const std::vector< int > &pivot, std::vector< float > &r, std::vector< float > &y)
GenericHouseholder(bool normalise=false)
std::vector< float > iterate(const std::vector< std::vector< float > > &eventMatrix, const std::vector< float > &energyVector, const int nIter)
run the Householder Algorithm several times (nIter). Returns the final vector of calibration coeffici...
~GenericHouseholder()
Destructor.