21 #include "analysis/OrcaKinFit/OPALFitterGSL.h"
23 #include "analysis/OrcaKinFit/BaseFitObject.h"
24 #include "analysis/OrcaKinFit/BaseHardConstraint.h"
25 #include "analysis/OrcaKinFit/BaseTracer.h"
26 #include <framework/logging/Logger.h>
28 #include <gsl/gsl_block.h>
29 #include <gsl/gsl_vector.h>
30 #include <gsl/gsl_matrix.h>
31 #include <gsl/gsl_permutation.h>
32 #include <gsl/gsl_linalg.h>
33 #include <gsl/gsl_blas.h>
34 #include <gsl/gsl_cdf.h>
47 namespace OrcaKinFit {
50 OPALFitterGSL::OPALFitterGSL()
51 : npar(0), nmea(0), nunm(0), ncon(0), ierr(0), nit(0),
53 f(nullptr), r(nullptr), Fetaxi(nullptr), S(nullptr), Sinv(nullptr), SinvFxi(nullptr), SinvFeta(nullptr),
54 W1(nullptr), G(nullptr), H(nullptr), HU(nullptr), IGV(nullptr), V(nullptr), VLU(nullptr), Vinv(nullptr), Vnew(nullptr),
55 Minv(nullptr), dxdt(nullptr), Vdxdt(nullptr),
56 dxi(nullptr), Fxidxi(nullptr), lambda(nullptr), FetaTlambda(nullptr),
57 etaxi(nullptr), etasv(nullptr), y(nullptr), y_eta(nullptr), Vinvy_eta(nullptr), FetaV(nullptr),
58 permS(nullptr), permU(nullptr), permV(nullptr), debug(0)
62 OPALFitterGSL::~OPALFitterGSL()
64 if (f) gsl_vector_free(f);
65 if (r) gsl_vector_free(r);
66 if (Fetaxi) gsl_matrix_free(Fetaxi);
67 if (S) gsl_matrix_free(S);
68 if (Sinv) gsl_matrix_free(Sinv);
69 if (SinvFxi) gsl_matrix_free(SinvFxi);
70 if (SinvFeta) gsl_matrix_free(SinvFeta);
71 if (W1) gsl_matrix_free(W1);
72 if (G) gsl_matrix_free(G);
73 if (H) gsl_matrix_free(H);
74 if (HU) gsl_matrix_free(HU);
75 if (IGV) gsl_matrix_free(IGV);
76 if (V) gsl_matrix_free(V);
77 if (VLU) gsl_matrix_free(VLU);
78 if (Vinv) gsl_matrix_free(Vinv);
79 if (Vnew) gsl_matrix_free(Vnew);
80 if (Minv) gsl_matrix_free(Minv);
81 if (dxdt) gsl_matrix_free(dxdt);
82 if (Vdxdt) gsl_matrix_free(Vdxdt);
83 if (dxi) gsl_vector_free(dxi);
84 if (Fxidxi) gsl_vector_free(Fxidxi);
85 if (lambda) gsl_vector_free(lambda);
86 if (FetaTlambda) gsl_vector_free(FetaTlambda);
87 if (etaxi) gsl_vector_free(etaxi);
88 if (etasv) gsl_vector_free(etasv);
89 if (y) gsl_vector_free(y);
90 if (y_eta) gsl_vector_free(y_eta);
91 if (Vinvy_eta) gsl_vector_free(Vinvy_eta);
92 if (FetaV) gsl_matrix_free(FetaV);
93 if (permS) gsl_permutation_free(permS);
94 if (permU) gsl_permutation_free(permU);
95 if (permV) gsl_permutation_free(permV);
119 FetaTlambda =
nullptr;
132 double OPALFitterGSL::fit()
189 assert(f && (
int)f->size == ncon);
190 assert(r && (
int)r->size == ncon);
191 assert(Fetaxi && (
int)Fetaxi->size1 == ncon && (
int)Fetaxi->size2 == npar);
192 assert(S && (
int)S->size1 == ncon && (
int)S->size2 == ncon);
193 assert(Sinv && (
int)Sinv->size1 == ncon && (
int)Sinv->size2 == ncon);
194 assert(nunm == 0 || (SinvFxi && (
int)SinvFxi->size1 == ncon && (
int)SinvFxi->size2 == nunm));
195 assert(SinvFeta && (
int)SinvFeta->size1 == ncon && (
int)SinvFeta->size2 == nmea);
196 assert(nunm == 0 || (W1 && (
int)W1->size1 == nunm && (
int)W1->size2 == nunm));
197 assert(G && (
int)G->size1 == nmea && (
int)G->size2 == nmea);
198 assert(nunm == 0 || (H && (
int)H->size1 == nmea && (
int)H->size2 == nunm));
199 assert(nunm == 0 || (HU && (
int)HU->size1 == nmea && (
int)HU->size2 == nunm));
200 assert(IGV && (
int)IGV->size1 == nmea && (
int)IGV->size2 == nmea);
201 assert(V && (
int)V->size1 == npar && (
int)V->size2 == npar);
202 assert(VLU && (
int)VLU->size1 == nmea && (
int)VLU->size2 == nmea);
203 assert(Vinv && (
int)Vinv->size1 == nmea && (
int)Vinv->size2 == nmea);
204 assert(Vnew && (
int)Vnew->size1 == npar && (
int)Vnew->size2 == npar);
205 assert(Minv && (
int)Minv->size1 == npar && (
int)Minv->size2 == npar);
206 assert(dxdt && (
int)dxdt->size1 == npar && (
int)dxdt->size2 == nmea);
207 assert(Vdxdt && (
int)Vdxdt->size1 == nmea && (
int)Vdxdt->size2 == npar);
208 assert(nunm == 0 || (dxi && (
int)dxi->size == nunm));
209 assert(nunm == 0 || (Fxidxi && (
int)Fxidxi->size == ncon));
210 assert(lambda && (
int)lambda->size == ncon);
211 assert(FetaTlambda && (
int)FetaTlambda->size == nmea);
212 assert(etaxi && (
int)etaxi->size == npar);
213 assert(etasv && (
int)etasv->size == npar);
214 assert(y && (
int)y->size == nmea);
215 assert(y_eta && (
int)y_eta->size == nmea);
216 assert(Vinvy_eta && (
int)Vinvy_eta->size == nmea);
217 assert(FetaV && (
int)FetaV->size1 == ncon && (
int)FetaV->size2 == nmea);
218 assert(permS && (
int)permS->size == ncon);
219 assert(nunm == 0 || (permU && (
int)permU->size == nunm));
220 assert(permV && (
int)permV->size == nmea);
223 gsl_vector_view eta = gsl_vector_subvector(etaxi, 0, nmea);
227 B2DEBUG(11,
"==== " << ncon <<
" " << nmea);
229 gsl_matrix_view Feta = gsl_matrix_submatrix(Fetaxi, 0, 0, ncon, nmea);
231 gsl_matrix_view Vetaeta = gsl_matrix_submatrix(V, 0, 0, nmea, nmea);
233 for (
unsigned int i = 0; i < fitobjects.size(); ++i) {
234 for (
int ilocal = 0; ilocal < fitobjects[i]->getNPar(); ++ilocal) {
235 if (!fitobjects[i]->isParamFixed(ilocal)) {
236 int iglobal = fitobjects[i]->getGlobalParNum(ilocal);
237 assert(iglobal >= 0 && iglobal < npar);
238 gsl_vector_set(etaxi, iglobal, fitobjects[i]->getParam(ilocal));
239 if (fitobjects[i]->isParamMeasured(ilocal)) {
240 assert(iglobal < nmea);
241 gsl_vector_set(y, iglobal, fitobjects[i]->getMParam(ilocal));
243 B2DEBUG(10,
"etaxi[" << iglobal <<
"] = " << gsl_vector_get(etaxi, iglobal)
244 <<
" for jet " << i <<
" and ilocal = " << ilocal);
250 gsl_matrix_set_zero(Fetaxi);
251 for (
int k = 0; k < ncon; k++) {
252 constraints[k]->getDerivatives(Fetaxi->size2, Fetaxi->block->data + k * Fetaxi->tda);
253 if (debug > 1)
for (
int j = 0; j < npar; j++)
254 if (gsl_matrix_get(Fetaxi, k, j) != 0)
255 B2INFO(
"1: Fetaxi[" << k <<
"][" << j <<
"] = " << gsl_matrix_get(Fetaxi, k, j));
259 double chinew = 0, chit = 0, chik = 0;
266 double dchikc = 1.0E-3;
267 double dchitc = 1.0E-4;
268 double dchikt = 1.0E-2;
270 double chimxw = 10000.;
279 if (tracer) tracer->initialize(*
this);
285 bool updatesuccess =
true;
289 gsl_vector_memcpy(etaxi, etasv);
290 updatesuccess = updateFitObjects(etaxi->block->data);
291 if (!updatesuccess) {
292 B2ERROR(
"OPALFitterGSL::fit: old parameters are garbage!");
297 gsl_matrix_set_zero(Fetaxi);
298 for (
int k = 0; k < ncon; ++k) {
299 constraints[k]->getDerivatives(Fetaxi->size2, Fetaxi->block->data + k * Fetaxi->tda);
301 if (debug > 1) debug_print(Fetaxi,
"1: Fetaxi");
303 gsl_vector_memcpy(etasv, etaxi);
309 gsl_matrix_set_zero(V);
311 for (
auto& fitobject : fitobjects) {
312 fitobject->addToGlobCov(V->block->data, V->tda);
314 if (debug > 1) debug_print(V,
"V");
316 gsl_matrix_memcpy(VLU, &Vetaeta.matrix);
322 result = gsl_linalg_LU_decomp(VLU, permV, &signum);
323 B2DEBUG(11,
"gsl_linalg_LU_decomp result=" << result);
324 if (debug > 3) debug_print(VLU,
"VLU");
326 result = gsl_linalg_LU_invert(VLU, permV, Vinv);
327 B2DEBUG(11,
"gsl_linalg_LU_invert result=" << result);
329 if (debug > 2) debug_print(Vinv,
"Vinv");
332 for (
int k = 0; k < ncon; ++k) {
333 gsl_vector_set(f, k, constraints[k]->getValue());
335 if (debug > 1) debug_print(f,
"f");
338 gsl_vector_memcpy(y_eta, y);
339 gsl_vector_sub(y_eta, &eta.vector);
341 gsl_vector_memcpy(r, f);
343 gsl_blas_dgemv(CblasNoTrans, 1, &Feta.matrix, y_eta, 1, r);
345 if (debug > 1) debug_print(r,
"r");
350 B2DEBUG(12,
"Creating FetaV");
351 gsl_blas_dsymm(CblasRight, CblasUpper, 1, &Vetaeta.matrix, &Feta.matrix, 0, FetaV);
353 B2DEBUG(12,
"Creating S");
354 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1, FetaV, &Feta.matrix, 0, S);
362 gsl_matrix_view Fxi = gsl_matrix_submatrix(Fetaxi, 0, nmea, ncon, nunm);
365 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1, &Fxi.matrix, &Fxi.matrix, 1, S);
368 if (debug > 1) debug_print(S,
"S");
373 gsl_linalg_LU_decomp(S, permS, &signum);
374 int inverr = gsl_linalg_LU_invert(S, permS, Sinv);
377 B2ERROR(
"S: gsl_linalg_LU_invert error " << inverr);
386 gsl_blas_dsymv(CblasUpper, 1, Sinv, r, 0, lambda);
392 gsl_matrix_view Fxi = gsl_matrix_submatrix(Fetaxi, 0, nmea, ncon, nunm);
395 gsl_blas_dsymm(CblasLeft, CblasUpper, 1, Sinv, &Fxi.matrix, 0, SinvFxi);
397 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1, &Fxi.matrix, SinvFxi, 0, W1);
400 debug_print(W1,
"W1");
402 for (
int i = 0; i < nunm; ++i) {
403 for (
int j = 0; j < nunm; ++j) {
404 if (abs(gsl_matrix_get(W1, i, j) - gsl_matrix_get(W1, j, i)) > 1E-3 * abs(gsl_matrix_get(W1, i, j) + gsl_matrix_get(W1, j, i)))
405 B2INFO(
"W1[" << i <<
"][" << j <<
"] = " << gsl_matrix_get(W1, i, j)
406 <<
" W1[" << j <<
"][" << i <<
"] = " << gsl_matrix_get(W1, j, i)
407 <<
" => diff=" << abs(gsl_matrix_get(W1, i, j) - gsl_matrix_get(W1, j, i))
408 <<
" => tol=" << 1E-3 * abs(gsl_matrix_get(W1, i, j) + gsl_matrix_get(W1, j, i)));
421 B2DEBUG(11,
"alph = " << alph);
423 debug_print(lambda,
"lambda");
424 debug_print(&(Fxi.matrix),
"Fxi");
427 gsl_blas_dgemv(CblasTrans, -alph, &Fxi.matrix, lambda, 0, dxi);
430 debug_print(dxi,
"dxi0");
431 debug_print(W1,
"W1");
437 gsl_linalg_cholesky_decomp(W1);
438 inverr = gsl_linalg_cholesky_svx(W1, dxi);
440 if (debug > 1) debug_print(dxi,
"dxi1");
444 B2ERROR(
"W1: gsl_linalg_cholesky_svx error " << inverr);
450 if (debug > 1) debug_print(dxi,
"dxi");
454 gsl_vector_view xi = gsl_vector_subvector(etaxi, nmea, nunm);
457 gsl_vector_add(&xi.vector, dxi);
467 gsl_matrix_view Fxi = gsl_matrix_submatrix(Fetaxi, 0, nmea, ncon, nunm);
469 gsl_blas_dgemv(CblasNoTrans, 1, &Fxi.matrix, dxi, 0, Fxidxi);
471 gsl_blas_dsymv(CblasUpper, 1, Sinv, Fxidxi, 1, lambda);
475 if (debug > 1) debug_print(lambda,
"lambda");
479 gsl_vector_memcpy(&eta.vector, y);
481 gsl_blas_dgemv(CblasTrans, 1, &Feta.matrix, lambda, 0, FetaTlambda);
483 gsl_blas_dsymv(CblasUpper, -1, &Vetaeta.matrix, FetaTlambda, 1, &eta.vector);
486 if (debug > 1) debug_print(&eta.vector,
"updated eta");
492 updatesuccess = updateFitObjects(etaxi->block->data);
494 B2DEBUG(10,
"After adjustment of all parameters:\n");
495 for (
int k = 0; k < ncon; ++k) {
496 B2DEBUG(10,
"Value of constraint " << k <<
" = " << constraints[k]->getValue());
498 gsl_matrix_set_zero(Fetaxi);
499 for (
int k = 0; k < ncon; k++) {
500 constraints[k]->getDerivatives(Fetaxi->size2, Fetaxi->block->data + k * Fetaxi->tda);
502 if (debug > 1) debug_print(Fetaxi,
"2: Fetaxi");
508 gsl_vector_memcpy(y_eta, y);
509 gsl_vector_sub(y_eta, &eta.vector);
512 gsl_blas_dsymv(CblasUpper, 1, Vinv, y_eta, 0, Vinvy_eta);
514 gsl_blas_ddot(y_eta, Vinvy_eta, &chit);
516 for (
int i = 0; i < nmea; ++i)
517 for (
int j = 0; j < nmea; ++j) {
518 double dchit = (gsl_vector_get(y_eta, i)) *
519 gsl_matrix_get(Vinv, i, j) *
520 (gsl_vector_get(y_eta, j));
522 B2DEBUG(11,
"chit for i,j = " << i <<
" , " << j <<
" = "
527 for (
int k = 0; k < ncon; ++k) chik += std::abs(2 * gsl_vector_get(lambda, k) * constraints[k]->getValue());
528 chinew = chit + chik;
533 bool sconv = (std::abs(chik - chik0) < dchikc)
534 && (std::abs(chit - chit0) < dchitc * chit)
535 && (chik < dchikt * chit);
545 for (
int k = 0; sconv2 && (k < ncon); ++k)
546 sconv2 &= (std::abs(gsl_vector_get(f, k)) < eps);
548 B2DEBUG(10,
"All constraints fulfilled to better than " << eps);
550 for (
int j = 0; sconv2 && (j < npar); ++j)
551 sconv2 &= (std::abs(gsl_vector_get(etaxi, j) - gsl_vector_get(etasv, j)) < eps);
553 B2DEBUG(10,
"All parameters stable to better than " << eps);
556 bool sbad = (chik > dchik * chik0)
557 && (chik > dchikt * chit)
558 && (chik > chik0 + 1.E-10);
567 }
else if (sconv && updatesuccess) {
572 }
else if (nit > 2 && chinew > chimxw && updatesuccess) {
577 }
else if ((sbad && nit > 1) || !updatesuccess) {
583 alph = std::max(almin, 0.5 * alph);
590 alph = std::min(alph + 0.1, 1.);
595 B2DEBUG(10,
"======== NIT = " << nit <<
", CHI2 = " << chinew
596 <<
", ierr = " << ierr <<
", alph=" << alph);
598 for (
unsigned int i = 0; i < fitobjects.size(); ++i)
599 B2DEBUG(10,
"fitobject " << i <<
": " << *fitobjects[i]);
602 if (tracer) tracer->step(*
this);
608 fitprob = (ncon - nunm > 0) ? gsl_cdf_chisq_Q(chinew, ncon - nunm) : 0.5;
615 gsl_matrix_set_zero(Vnew);
616 gsl_matrix_set_zero(Minv);
618 for (
int i = 0; i < npar; ++i) {
619 for (
int j = 0; j < npar; ++j) {
620 B2INFO(
"Minv[" << i <<
"," << j <<
"]=" << gsl_matrix_get(Minv, i, j));
625 B2DEBUG(10,
"OPALFitterGSL: calcerr = " << calcerr);
636 debug_print(&Vetaeta.matrix,
"V");
637 debug_print(&Feta.matrix,
"Feta");
642 gsl_blas_dsymm(CblasRight, CblasUpper, 1, &Vetaeta.matrix, &Feta.matrix, 0, FetaV);
644 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1, FetaV, &Feta.matrix, 0, S);
653 gsl_matrix_view Fxi = gsl_matrix_submatrix(Fetaxi, 0, nmea, ncon, nunm);
655 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1, &Fxi.matrix, &Fxi.matrix, 1, S);
658 if (debug > 2) debug_print(S,
"S");
664 gsl_linalg_LU_decomp(S, permS, &signum);
665 int inverr = gsl_linalg_LU_invert(S, permS, Sinv);
668 B2ERROR(
"S: gsl_linalg_LU_invert error " << inverr <<
" in error calculation");
679 gsl_blas_dsymm(CblasLeft, CblasUpper, 1, Sinv, &Feta.matrix, 0, SinvFeta);
681 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1, &Feta.matrix, SinvFeta, 0, G);
683 if (debug > 2) debug_print(G,
"G(1)");
691 gsl_matrix_view Fxi = gsl_matrix_submatrix(Fetaxi, 0, nmea, ncon, nunm);
694 gsl_blas_dsymm(CblasLeft, CblasUpper, 1, Sinv, &Fxi.matrix, 0, SinvFxi);
696 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1, &Feta.matrix, SinvFxi, 0, H);
698 if (debug > 2) debug_print(H,
"H");
704 gsl_matrix* Uinv = W1;
705 gsl_matrix_view U = gsl_matrix_submatrix(Minv, nmea, nmea, nunm, nunm);
708 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1, &Fxi.matrix, SinvFxi, 0, Uinv);
710 gsl_linalg_LU_decomp(Uinv, permU, &signum);
711 inverr = gsl_linalg_LU_invert(Uinv, permU, &U.matrix);
713 if (debug > 2) debug_print(&U.matrix,
"U");
714 for (
int i = 0; i < npar; ++i) {
715 for (
int j = 0; j < npar; ++j) {
716 B2DEBUG(12,
"after U Minv[" << i <<
"," << j <<
"]=" << gsl_matrix_get(Minv, i, j));
721 B2ERROR(
"U: gsl_linalg_LU_invert error " << inverr <<
" in error calculation ");
729 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, H, &U.matrix, 0, HU);
731 gsl_matrix_view Minvetaxi = gsl_matrix_submatrix(Minv, 0, nmea, nmea, nunm);
732 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, -1, &Vetaeta.matrix, HU, 0, &Minvetaxi.matrix);
733 for (
int i = 0; i < npar; ++i) {
734 for (
int j = 0; j < npar; ++j) {
735 B2DEBUG(12,
"after etaxi Minv[" << i <<
"," << j <<
"]=" << gsl_matrix_get(Minv, i, j));
742 gsl_matrix_view Minvxieta = gsl_matrix_submatrix(Minv, nmea, 0, nunm, nmea);
743 gsl_matrix_transpose_memcpy(&Minvxieta.matrix, &Minvetaxi.matrix);
744 for (
int i = 0; i < npar; ++i) {
745 for (
int j = 0; j < npar; ++j) {
746 B2DEBUG(12,
"after symmetric: Minv[" << i <<
"," << j <<
"]=" << gsl_matrix_get(Minv, i, j));
752 gsl_blas_dgemm(CblasNoTrans, CblasTrans, -1, HU, H, +1, G);
758 gsl_matrix_set_identity(IGV);
760 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, -1, G, &Vetaeta.matrix, 1, IGV);
763 gsl_matrix_view Minvetaeta = gsl_matrix_submatrix(Minv, 0, 0, nmea, nmea);
766 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, &Vetaeta.matrix, IGV, 0, &Minvetaeta.matrix);
768 for (
int i = 0; i < npar; ++i) {
769 for (
int j = 0; j < npar; ++j) {
770 B2DEBUG(12,
"complete Minv[" << i <<
"," << j <<
"]=" << gsl_matrix_get(Minv, i, j));
790 gsl_matrix_view detadt = gsl_matrix_submatrix(dxdt, 0, 0, nmea, nmea);
791 B2DEBUG(13,
"after detadt");
793 gsl_matrix_view Vdetadt = gsl_matrix_submatrix(Vdxdt, 0, 0, nmea, nmea);
794 B2DEBUG(13,
"after Vdetadt");
797 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, &Minvetaeta.matrix, Vinv, 0, &detadt.matrix);
798 if (debug > 2) debug_print(&detadt.matrix,
"deta/dt");
801 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1, &Vetaeta.matrix, &detadt.matrix, 0, &Vdetadt.matrix);
802 if (debug > 2) debug_print(&Vdetadt.matrix,
"Vetata * deta/dt");
804 gsl_matrix_view Vnewetaeta = gsl_matrix_submatrix(Vnew, 0, 0, nmea, nmea);
806 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, &detadt.matrix, &Vdetadt.matrix, 0, &Vnewetaeta.matrix);
808 if (debug > 2) debug_print(Vnew,
"Vnew after part for measured parameters");
813 gsl_matrix_view Minvxieta = gsl_matrix_submatrix(Minv, nmea, 0, nunm, nmea);
814 B2DEBUG(13,
"after Minvxieta");
815 if (debug > 2) debug_print(&Minvxieta.matrix,
"Minvxieta");
817 gsl_matrix_view dxidt = gsl_matrix_submatrix(dxdt, nmea, 0, nunm, nmea);
818 B2DEBUG(13,
"after dxidt");
820 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, &Minvxieta.matrix, Vinv, 0, &dxidt.matrix);
821 if (debug > 2) debug_print(&dxidt.matrix,
"dxi/dt");
824 gsl_matrix_view Vdxidt = gsl_matrix_submatrix(Vdxdt, 0, nmea, nmea, nunm);
825 B2DEBUG(13,
"after Vdxidt");
827 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1, &Vetaeta.matrix, &dxidt.matrix, 0, &Vdxidt.matrix);
828 if (debug > 2) debug_print(&Vdxidt.matrix,
"Vetaeta * dxi/dt^T");
830 gsl_matrix_view Vnewetaxi = gsl_matrix_submatrix(Vnew, 0, nmea, nmea, nunm);
831 gsl_matrix_view Vnewxieta = gsl_matrix_submatrix(Vnew, nmea, 0, nunm, nmea);
832 gsl_matrix_view Vnewxixi = gsl_matrix_submatrix(Vnew, nmea, nmea, nunm, nunm);
835 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, &dxidt.matrix, &Vdetadt.matrix, 0, &Vnewxieta.matrix);
836 if (debug > 2) debug_print(Vnew,
"Vnew after xieta part");
838 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, &detadt.matrix, &Vdxidt.matrix, 0, &Vnewetaxi.matrix);
839 if (debug > 2) debug_print(Vnew,
"Vnew after etaxi part");
841 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1, &dxidt.matrix, &Vdxidt.matrix, 0, &Vnewxixi.matrix);
842 if (debug > 2) debug_print(Vnew,
"Vnew after xixi part");
848 for (
auto& fitobject : fitobjects) {
849 for (
int ilocal = 0; ilocal < fitobject->getNPar(); ++ilocal) {
850 int iglobal = fitobject->getGlobalParNum(ilocal);
851 for (
int jlocal = ilocal; jlocal < fitobject->getNPar(); ++jlocal) {
852 int jglobal = fitobject->getGlobalParNum(jlocal);
853 if (iglobal >= 0 && jglobal >= 0)
854 fitobject->setCov(ilocal, jlocal, gsl_matrix_get(Vnew, iglobal, jglobal));
860 if (cov && covDim != nmea + nunm) {
864 covDim = nmea + nunm;
865 if (!cov) cov =
new double[covDim * covDim];
866 for (
int i = 0; i < covDim; ++i) {
867 for (
int j = 0; j < covDim; ++j) {
868 cov[i * covDim + j] = gsl_matrix_get(Vnew, i, j);
876 if (tracer) tracer->finish(*
this);
883 bool OPALFitterGSL::initialize()
889 for (
auto& fitobject : fitobjects) {
890 for (
int ilocal = 0; ilocal < fitobject->getNPar(); ++ilocal) {
891 if (fitobject->isParamMeasured(ilocal) &&
892 !fitobject->isParamFixed(ilocal)) {
893 fitobject->setGlobalParNum(ilocal, iglobal);
894 B2DEBUG(10,
"Object " << fitobject->getName()
895 <<
" Parameter " << fitobject->getParamName(ilocal)
896 <<
" is measured, global number " << iglobal);
903 for (
auto& fitobject : fitobjects) {
904 for (
int ilocal = 0; ilocal < fitobject->getNPar(); ++ilocal) {
905 if (!fitobject->isParamMeasured(ilocal) &&
906 !fitobject->isParamFixed(ilocal)) {
907 fitobject->setGlobalParNum(ilocal, iglobal);
908 B2DEBUG(10,
"Object " << fitobject->getName()
909 <<
" Parameter " << fitobject->getParamName(ilocal)
910 <<
" is unmeasured, global number " << iglobal);
916 assert(npar <= NPARMAX);
918 assert(nunm <= NUNMMAX);
921 ncon = constraints.size();
922 assert(ncon <= NCONMAX);
924 ini_gsl_vector(f, ncon);
925 ini_gsl_vector(r, ncon);
927 ini_gsl_matrix(Fetaxi, ncon, npar);
928 ini_gsl_matrix(S, ncon, ncon);
929 ini_gsl_matrix(Sinv, ncon, ncon);
930 ini_gsl_matrix(SinvFxi, ncon, nunm);
931 ini_gsl_matrix(SinvFeta, ncon, nmea);
932 ini_gsl_matrix(W1, nunm, nunm);
933 ini_gsl_matrix(G, nmea, nmea);
934 ini_gsl_matrix(H, nmea, nunm);
935 ini_gsl_matrix(HU, nmea, nunm);
936 ini_gsl_matrix(IGV, nmea, nmea);
937 ini_gsl_matrix(V, npar, npar);
938 ini_gsl_matrix(VLU, nmea, nmea);
939 ini_gsl_matrix(Vinv, nmea, nmea);
940 ini_gsl_matrix(Vnew, npar, npar);
941 ini_gsl_matrix(Minv, npar, npar);
942 ini_gsl_matrix(dxdt, npar, nmea);
943 ini_gsl_matrix(Vdxdt, nmea, npar);
945 ini_gsl_vector(dxi, nunm);
946 ini_gsl_vector(Fxidxi, ncon);
947 ini_gsl_vector(lambda, ncon);
948 ini_gsl_vector(FetaTlambda, nmea);
950 ini_gsl_vector(etaxi, npar);
951 ini_gsl_vector(etasv, npar);
952 ini_gsl_vector(y, nmea);
953 ini_gsl_vector(y_eta, nmea);
954 ini_gsl_vector(Vinvy_eta, nmea);
956 ini_gsl_matrix(FetaV, ncon, nmea);
958 ini_gsl_permutation(permS, ncon);
959 ini_gsl_permutation(permU, nunm);
960 ini_gsl_permutation(permV, nmea);
962 assert(f && (
int)f->size == ncon);
963 assert(r && (
int)r->size == ncon);
964 assert(Fetaxi && (
int)Fetaxi->size1 == ncon && (
int)Fetaxi->size2 == npar);
965 assert(S && (
int)S->size1 == ncon && (
int)S->size2 == ncon);
966 assert(Sinv && (
int)Sinv->size1 == ncon && (
int)Sinv->size2 == ncon);
967 assert(nunm == 0 || (SinvFxi && (
int)SinvFxi->size1 == ncon && (
int)SinvFxi->size2 == nunm));
968 assert(SinvFeta && (
int)SinvFeta->size1 == ncon && (
int)SinvFeta->size2 == nmea);
969 assert(nunm == 0 || (W1 && (
int)W1->size1 == nunm && (
int)W1->size2 == nunm));
970 assert(G && (
int)G->size1 == nmea && (
int)G->size2 == nmea);
971 assert(nunm == 0 || (H && (
int)H->size1 == nmea && (
int)H->size2 == nunm));
972 assert(nunm == 0 || (HU && (
int)HU->size1 == nmea && (
int)HU->size2 == nunm));
973 assert(IGV && (
int)IGV->size1 == nmea && (
int)IGV->size2 == nmea);
974 assert(V && (
int)V->size1 == npar && (
int)V->size2 == npar);
975 assert(VLU && (
int)VLU->size1 == nmea && (
int)VLU->size2 == nmea);
976 assert(Vinv && (
int)Vinv->size1 == nmea && (
int)Vinv->size2 == nmea);
977 assert(Vnew && (
int)Vnew->size1 == npar && (
int)Vnew->size2 == npar);
978 assert(nunm == 0 || (dxi && (
int)dxi->size == nunm));
979 assert(nunm == 0 || (Fxidxi && (
int)Fxidxi->size == ncon));
980 assert(lambda && (
int)lambda->size == ncon);
981 assert(FetaTlambda && (
int)FetaTlambda->size == nmea);
982 assert(etaxi && (
int)etaxi->size == npar);
983 assert(etasv && (
int)etasv->size == npar);
984 assert(y && (
int)y->size == nmea);
985 assert(y_eta && (
int)y_eta->size == nmea);
986 assert(Vinvy_eta && (
int)Vinvy_eta->size == nmea);
987 assert(FetaV && (
int)FetaV->size1 == ncon && (
int)FetaV->size2 == nmea);
988 assert(permS && (
int)permS->size == ncon);
989 assert(permS && (
int)permS->size == ncon);
990 assert(nunm == 0 || (permU && (
int)permU->size == nunm));
991 assert(permV && (
int)permV->size == nmea);
997 bool OPALFitterGSL::updateFitObjects(
double eetaxi[])
1002 for (
auto& fitobject : fitobjects) {
1003 for (
int ilocal = 0; ilocal < fitobject->getNPar(); ++ilocal) {
1004 fitobject->updateParams(eetaxi, npar);
1011 int OPALFitterGSL::getError()
const {
return ierr;}
1012 double OPALFitterGSL::getProbability()
const {
return fitprob;}
1013 double OPALFitterGSL::getChi2()
const {
return chi2;}
1014 int OPALFitterGSL::getDoF()
const {
return ncon - nunm;}
1015 int OPALFitterGSL::getIterations()
const {
return nit;}
1017 void OPALFitterGSL::ini_gsl_permutation(gsl_permutation*& p,
unsigned int size)
1020 if (p->size != size) {
1021 gsl_permutation_free(p);
1022 if (size > 0) p = gsl_permutation_alloc(size);
1025 }
else if (size > 0) p = gsl_permutation_alloc(size);
1028 void OPALFitterGSL::ini_gsl_vector(gsl_vector*& v,
unsigned int size)
1032 if (v->size != size) {
1034 if (size > 0) v = gsl_vector_alloc(size);
1037 }
else if (size > 0) v = gsl_vector_alloc(size);
1040 void OPALFitterGSL::ini_gsl_matrix(gsl_matrix*& m,
unsigned int size1,
unsigned int size2)
1043 if (m->size1 != size1 || m->size2 != size2) {
1045 if (size1 * size2 > 0) m = gsl_matrix_alloc(size1, size2);
1048 }
else if (size1 * size2 > 0) m = gsl_matrix_alloc(size1, size2);
1051 void OPALFitterGSL::setDebug(
int debuglevel)
1056 void OPALFitterGSL::debug_print(gsl_matrix* m,
const char* name)
1058 for (
unsigned int i = 0; i < m->size1; ++i)
1059 for (
unsigned int j = 0; j < m->size2; ++j)
1060 if (gsl_matrix_get(m, i, j) != 0)
1061 B2INFO(name <<
"[" << i <<
"][" << j <<
"]=" << gsl_matrix_get(m, i, j));
1064 void OPALFitterGSL::debug_print(gsl_vector* v,
const char* name)
1066 for (
unsigned int i = 0; i < v->size; ++i)
1067 if (gsl_vector_get(v, i) != 0)
1068 B2INFO(name <<
"[" << i <<
"]=" << gsl_vector_get(v, i));
1071 int OPALFitterGSL::getNcon()
const {
return ncon;}
1072 int OPALFitterGSL::getNsoft()
const {
return 0;}
1073 int OPALFitterGSL::getNunm()
const {
return nunm;}
1074 int OPALFitterGSL::getNpar()
const {
return npar;}
Abstract base class for different kinds of events.