9#include "FemtoYlmSolver.h"
13#include "FemtoSHSlice.h"
16#include <gsl/gsl_blas.h>
17#include <gsl/gsl_cblas.h>
18#include <gsl/gsl_matrix_double.h>
19#include <gsl/gsl_vector_double.h>
25 FemtoYlmSolver::FemtoYlmSolver() {}
27 FemtoYlmSolver::~FemtoYlmSolver() {}
29 void FemtoYlmSolver::GetMtilde(std::complex<double>* aMat,
double* aMTilde) {
39 for (
int iz = 0; iz < GetMaxJM() * 2; iz++)
40 for (
int ip = 0; ip < GetMaxJM() * 2; ip++)
41 aMTilde[iz * GetMaxJM() * 2 + ip] = 0.0;
43 for (
int izero = 0; izero < GetMaxJM(); izero++) {
44 GetElEmForIndex(izero, lzero, mzero);
45 GetElEmForIndex(izero, lzeroi, mzeroi);
48 for (
int ibis = 0; ibis < GetMaxJM(); ibis++) {
49 GetElEmForIndex(ibis, lbis, mbis);
50 GetElEmForIndex(ibis, lbisi, mbisi);
54 std::complex<double> val = std::complex<double>(0.0, 0.0);
55 std::unique_ptr<std::complex<double>[]> mcomp(
new std::complex<double>[fMaxJM]());
56 for (
int iprim = 0; iprim < GetMaxJM(); iprim++) {
57 GetElEmForIndex(iprim, lprim, mprim);
58 GetElEmForIndex(iprim, lprimi, mprimi);
63 mcomp[iprim] = std::complex<double>(-1.0, 0.0);
65 mcomp[iprim] = std::complex<double>(1.0, 0.0);
67 mcomp[iprim] *= sqrt((2 * lzero + 1) * (2 * lprim + 1) * (2 * lbis + 1));
68 mcomp[iprim] *= fLmMath.WignerSymbol(lzero, 0, lprim, 0, lbis, 0);
69 mcomp[iprim] *= fLmMath.WignerSymbol(lzero, -mzero, lprim, mprim, lbis,
71 mcomp[iprim] *= aMat[iprim];
76 aMTilde[(izero * 2) * (2 * GetMaxJM()) + (ibis * 2)] = real(val);
77 aMTilde[(izero * 2 + 1) * (2 * GetMaxJM()) + (ibis * 2)] = imag(val);
79 aMTilde[(izero * 2) * (2 * GetMaxJM()) + (ibis * 2 + 1)] = -imag(val);
81 aMTilde[(izero * 2) * (2 * GetMaxJM()) + (ibis * 2 + 1)] = 0.0;
82 aMTilde[(izero * 2 + 1) * (2 * GetMaxJM()) + (ibis * 2 + 1)] = real(val);
87 void FemtoYlmSolver::InvertYlmIndependentMatrix(
double* inmat,
double* outmat)
const {
92 std::unique_ptr<double[]> mU(
new double[GetMaxJM() * GetMaxJM() * 4]);
93 int isize = PackYlmMatrixIndependentOnly(inmat, mU.get());
96 gsl_matrix_view matU = gsl_matrix_view_array(mU.get(), isize, isize);
99 std::unique_ptr<double[]> mI(
new double[GetMaxJM() * GetMaxJM() * 4]);
100 for (
int iterm = 0; iterm < isize; iterm++)
101 for (
int iterp = 0; iterp < isize; iterp++)
103 mI[iterm * isize + iterp] = 1.0;
105 mI[iterm * isize + iterp] = 0.0;
107 gsl_matrix_view matI = gsl_matrix_view_array(mI.get(), isize, isize);
109 gsl_blas_dtrsm(CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, 1.0, &matU.matrix, &matI.matrix);
111 std::cout <<
"GLS NOT ENABLED!" << std::endl;
113 UnPackYlmMatrixIndependentOnly(mI.get(), outmat, isize);
116 void FemtoYlmSolver::UnPackYlmMatrixIndependentOnly(
double* inmat,
double* outmat,
int insize)
const {
117 int lmax = sqrt(insize) - 1;
119 if (0) { lmax *= 2; }
120 int tmax = (lmax + 1) * (lmax + 1) * 2;
121 std::unique_ptr<int[]> indexfrom(
new int[tmax]);
122 std::unique_ptr<int[]> multfrom(
new int[tmax]);
125 for (
int iter = 0; iter < tmax; iter++) {
127 GetElEmForIndex(iter / 2, el, em);
133 indexfrom[iter] = el * el;
137 indexfrom[iter] = (el * el) + (-em) * 2 - 1;
138 if (im) indexfrom[iter]++;
149 indexfrom[iter] = (el * el) + (em) *2 - 1;
150 if (im) indexfrom[iter]++;
163 for (
int ilmz = 0; ilmz < GetMaxJM() * 2; ilmz++)
164 for (
int ilmp = 0; ilmp < GetMaxJM() * 2; ilmp++)
165 outmat[ilmz * GetMaxJM() * 2 + ilmp] =
166 inmat[(indexfrom[ilmz] * insize) + indexfrom[ilmp]] * multfrom[ilmz] * multfrom[ilmp];
169 int FemtoYlmSolver::PackYlmVectorIndependentOnly(
double* invec,
double* outvec)
const {
172 for (
int ilm = 0; ilm < GetMaxJM(); ilm++) {
173 GetElEmForIndex(ilm, el, em);
174 if (em < 0)
continue;
175 outvec[ioutcount++] = invec[ilm * 2];
176 if (em == 0)
continue;
177 outvec[ioutcount++] = invec[ilm * 2 + 1];
182 int FemtoYlmSolver::PackYlmMatrixIndependentOnly(
double* inmat,
double* outmat)
const {
189 for (
int ilm = 0; ilm < GetMaxJM(); ilm++) {
190 GetElEmForIndex(ilm, elz, emz);
191 if (emz < 0)
continue;
193 if (emz == 0)
continue;
198 auto GetBin = [](
int maxJm,
int ilmzero,
int zeroimag,
int ilmprim,
int primimag) ->
int {
199 return ((ilmprim * 2 + primimag) * maxJm * 2 + ilmzero * 2 + zeroimag);
202 for (
int ilmz = 0; ilmz < GetMaxJM(); ilmz++) {
203 GetElEmForIndex(ilmz, elz, emz);
206 if (emz < 0)
continue;
207 for (
int ilmp = 0; ilmp < GetMaxJM(); ilmp++) {
208 GetElEmForIndex(ilmp, elp, emp);
209 if (emp < 0)
continue;
210 outmat[ioutcountz * finalsize + ioutcountp] = inmat[GetBin(fMaxJM, ilmz, 0, ilmp, 0)];
212 if (emp == 0)
continue;
213 outmat[ioutcountz * finalsize + ioutcountp] = inmat[GetBin(fMaxJM, ilmz, 0, ilmp, 1)];
218 if (emz == 0)
continue;
220 for (
int ilmp = 0; ilmp < GetMaxJM(); ilmp++) {
221 GetElEmForIndex(ilmp, elp, emp);
222 if (emp < 0)
continue;
223 outmat[ioutcountz * finalsize + ioutcountp] = inmat[GetBin(fMaxJM, ilmz, 1, ilmp, 0)];
225 if (emp == 0)
continue;
226 outmat[ioutcountz * finalsize + ioutcountp] = inmat[GetBin(fMaxJM, ilmz, 1, ilmp, 1)];
235 FemtoYlmSolver::FemtoYlmSolver(Int_t maxL, FemtoSHCF* cf, Bool_t sumw) :
236 fMaxJM((maxL + 1) * (maxL + 1)),
237 fFactorialsSize((maxL + 1) * 4),
240 fSlice(FemtoSHSlice(maxL)),
242 fLmVals.Resize(maxL);
243 fFactorials.resize(fFactorialsSize);
244 fMaxJM2_4 = 4.0 * fMaxJM * fMaxJM;
247 fNumEnt = cf->GetNumRe(0, 0)->GetEffectiveEntries();
248 fDenEnt = cf->GetDenRe(0, 0)->GetEffectiveEntries();
250 fNumEnt = cf->GetNumRe(0, 0)->GetEntries();
251 fDenEnt = cf->GetDenRe(0, 0)->GetEntries();
257 for (
int iter = 1; iter < fFactorialsSize; iter++) {
259 fFactorials[iter] = fac;
263 void FemtoYlmSolver::DoMath(Bool_t recalc) {
265 std::unique_ptr<std::complex<double>[]> tMq0(
new std::complex<double>[fMaxJM]);
266 std::unique_ptr<std::complex<double>[]> tTq0(
new std::complex<double>[fMaxJM]);
267 std::unique_ptr<double[]> tMTilde(
new double[fMaxJM * fMaxJM * 4]);
269 for (
int i = 0; i < fMaxJM; i++) {
270 fSlice.fCFImag[i] = 0;
271 fSlice.fCFReal[i] = 0;
272 fSlice.fCFImagE[i] = 0;
273 fSlice.fCFRealE[i] = 0;
276 for (
int i = 0; i < fMaxJM * 2; i++)
277 for (
int j = 0; j < fMaxJM * 2; j++)
278 fSlice.fCovCF[i][j] = 0;
279 if (fSlice.fCovNum[0][0] == 0) MakeFakeCovMatrix();
281 std::cout <<
"NORM " << fNormFactor << std::endl;
282 std::cout <<
"RECALC " << recalc << std::endl;
284 std::cout <<
"Nu ent " << fCF->fNumReal[0]->GetEntries() <<
" " << fCF->fNumReal[0]->GetBinContent(1) << std::endl;
286 for (
int ilm = 0; ilm < fMaxJM; ilm++) {
291 std::complex<double>(fSlice.fDenReal[ilm] / (fDenEnt / fNormFactor), fSlice.fDenImag[ilm] / (fDenEnt / fNormFactor));
294 tTq0[ilm] = std::complex<double>(fSlice.fNumReal[ilm] / fNumEnt, fSlice.fNumImag[ilm] / fNumEnt);
296 tMq0[ilm] = std::complex<double>(fSlice.fDenReal[ilm] / fNormFactor, fSlice.fDenImag[ilm] / fNormFactor);
297 tTq0[ilm] = std::complex<double>(fSlice.fNumReal[ilm], fSlice.fNumImag[ilm]);
304 for (
int ilm = 0; ilm < fMaxJM; ilm++) {
305 std::cout << tTq0[ilm] <<
" " << std::endl;
307 std::cout << std::endl;
309 for (
int ilm = 0; ilm < fMaxJM; ilm++) {
310 std::cout << tMq0[ilm] <<
" " << std::endl;
312 std::cout << std::endl;
329 for (
int ilmzero = 0; ilmzero < GetMaxJM(); ilmzero++) {
330 const int ilmzero2 = ilmzero * 2;
331 for (
int ilmprim = 0; ilmprim < GetMaxJM(); ilmprim++) {
332 const int ilmprim2 = ilmprim * 2;
333 if (std::isnan(fSlice.fCovNum[ilmzero2][ilmprim2])) {}
334 if (std::isnan(fSlice.fCovNum[ilmzero2][ilmprim2 + 1])) {}
335 if (std::isnan(fSlice.fCovNum[ilmzero2 + 1][ilmprim2])) {}
336 if (std::isnan(fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1])) {}
338 a = fSlice.fCovNum[ilmzero2][ilmprim2];
339 b = fSlice.fCovNum[ilmzero2][ilmprim2 + 1];
340 c = fSlice.fCovNum[ilmzero2 + 1][ilmprim2];
341 d = fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1];
342 if (fDebug) std::cout <<
">" << a <<
" " << b <<
" " << c <<
" " << d <<
" " << fNumEnt << std::endl;
344 fSlice.fCovNum[ilmzero2][ilmprim2] /= fNumEnt;
345 fSlice.fCovNum[ilmzero2][ilmprim2 + 1] /= fNumEnt;
346 fSlice.fCovNum[ilmzero2 + 1][ilmprim2] /= fNumEnt;
347 fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1] /= fNumEnt;
349 a = fSlice.fCovNum[ilmzero2][ilmprim2];
350 b = fSlice.fCovNum[ilmzero2][ilmprim2 + 1];
351 c = fSlice.fCovNum[ilmzero2 + 1][ilmprim2];
352 d = fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1];
353 if (fDebug) std::cout <<
"->" << a <<
" " << b <<
" " << c <<
" " << d << std::endl;
356 fSlice.fCovNum[ilmzero2][ilmprim2] -= real(tTq0[ilmzero]) * real(tTq0[ilmprim]);
357 fSlice.fCovNum[ilmzero2][ilmprim2 + 1] -= real(tTq0[ilmzero]) * imag(tTq0[ilmprim]);
358 fSlice.fCovNum[ilmzero2 + 1][ilmprim2] -= imag(tTq0[ilmzero]) * real(tTq0[ilmprim]);
359 fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1] -= imag(tTq0[ilmzero]) * imag(tTq0[ilmprim]);
360 a = fSlice.fCovNum[ilmzero2][ilmprim2];
361 b = fSlice.fCovNum[ilmzero2][ilmprim2 + 1];
362 c = fSlice.fCovNum[ilmzero2 + 1][ilmprim2];
363 d = fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1];
364 if (fDebug) std::cout <<
"-->" << a <<
" " << b <<
" " << c <<
" " << d << std::endl;
365 fSlice.fCovNum[ilmzero2][ilmprim2] /= ((fNumEnt) -1);
366 fSlice.fCovNum[ilmzero2][ilmprim2 + 1] /= ((fNumEnt) -1);
367 fSlice.fCovNum[ilmzero2 + 1][ilmprim2] /= ((fNumEnt) -1);
368 fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1] /= ((fNumEnt) -1);
369 a = fSlice.fCovNum[ilmzero2][ilmprim2];
370 b = fSlice.fCovNum[ilmzero2][ilmprim2 + 1];
371 c = fSlice.fCovNum[ilmzero2 + 1][ilmprim2];
372 d = fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1];
373 if (fDebug) std::cout <<
"--->" << a <<
" " << b <<
" " << c <<
" " << d << std::endl;
379 std::cout <<
"COVNUM" << std::endl;
380 for (
int ilmzero = 0; ilmzero < GetMaxJM(); ilmzero++) {
381 const int ilmzero2 = ilmzero * 2;
382 for (
int ilmprim = 0; ilmprim < GetMaxJM(); ilmprim++) {
383 const int ilmprim2 = ilmprim * 2;
384 std::cout << fSlice.fCovNum[ilmzero2 + 0][ilmprim2 + 0] <<
" ";
385 std::cout << fSlice.fCovNum[ilmzero2 + 0][ilmprim2 + 1] <<
" ";
386 std::cout << fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 0] <<
" ";
387 std::cout << fSlice.fCovNum[ilmzero2 + 1][ilmprim2 + 1] <<
" ";
388 std::cout << std::endl;
390 std::cout << std::endl;
395 GetMtilde(tMq0.get(), tMTilde.get());
410 if (fSlice.fNumReal[0] <= 0) {
411 for (
int ilm = 0; ilm < GetMaxJM(); ilm++) {
412 fSlice.fCFReal[ilm] = 0;
413 fSlice.fCFRealE[ilm] = 0;
414 fSlice.fCFImag[ilm] = 0;
415 fSlice.fCFImagE[ilm] = 0;
418 for (
int ilmz = 0; ilmz < GetMaxJM(); ilmz++) {
419 for (
int ilmp = 0; ilmp < GetMaxJM(); ilmp++) {
420 fSlice.fCovNum[2 * ilmz][2 * ilmp] = 0;
421 fSlice.fCovNum[2 * ilmz][2 * ilmp + 1] = 0;
429 std::unique_ptr<double[]> mDeltaT(
new double[fMaxJM * fMaxJM * 4]);
430 for (
int ilmzero = 0; ilmzero < GetMaxJM() * 2; ilmzero++)
431 for (
int ilmprim = 0; ilmprim < GetMaxJM() * 2; ilmprim++)
432 mDeltaT[(ilmzero * fMaxJM * 2) + ilmprim] = fSlice.fCovNum[ilmzero][ilmprim];
435 std::cout <<
"Delta T matrix " << std::endl;
436 for (
int ilmz = 0; ilmz < GetMaxJM() * 2; ilmz++) {
437 for (
int ilmp = 0; ilmp < GetMaxJM() * 2; ilmp++) {
438 std::cout.precision(3);
440 std::cout << mDeltaT[ilmz * GetMaxJM() * 2 + ilmp];
442 std::cout << std::endl;
446 std::unique_ptr<double[]> mDeltaTPacked(
new double[fMaxJM * fMaxJM * 4]);
447 int msize = PackYlmMatrixIndependentOnly(mDeltaT.get(), mDeltaTPacked.get());
450 std::cout <<
"Delta T matrix packed " << std::endl;
451 for (
int ilmz = 0; ilmz < msize; ilmz++) {
452 for (
int ilmp = 0; ilmp < msize; ilmp++) {
453 std::cout.precision(3);
455 std::cout << mDeltaTPacked[ilmz * msize + ilmp];
457 std::cout << std::endl;
465 std::unique_ptr<double[]> mM(
new double[fMaxJM * fMaxJM * 4]);
466 std::unique_ptr<double[]> mMPacked(
new double[fMaxJM * fMaxJM * 4]);
467 for (
int iter = 0; iter < fMaxJM * fMaxJM * 4; iter++)
468 mM[iter] = tMTilde[iter];
469 PackYlmMatrixIndependentOnly(mM.get(), mMPacked.get());
471 gsl_matrix_view matM = gsl_matrix_view_array(mMPacked.get(), msize, msize);
473 std::cout <<
"Mtilde matrix " << std::endl;
474 for (
int ilmz = 0; ilmz < GetMaxJM() * 2; ilmz++) {
475 for (
int ilmp = 0; ilmp < GetMaxJM() * 2; ilmp++) {
476 std::cout.precision(3);
478 std::cout << mM[ilmz * GetMaxJM() * 2 + ilmp];
480 std::cout << std::endl;
483 std::cout <<
"Mtilde matrix packed " << std::endl;
484 for (
int ilmz = 0; ilmz < msize; ilmz++) {
485 for (
int ilmp = 0; ilmp < msize; ilmp++) {
486 std::cout.precision(3);
488 std::cout << mMPacked[ilmz * msize + ilmp];
490 std::cout << std::endl;
496 std::unique_ptr<double[]> mU(
new double[fMaxJM * fMaxJM * 4]);
497 InvertYlmIndependentMatrix(mDeltaT.get(), mU.get());
499 std::unique_ptr<double[]> mDTInvertedPacked(
new double[fMaxJM * fMaxJM * 4]);
500 PackYlmMatrixIndependentOnly(mU.get(), mDTInvertedPacked.get());
502 gsl_matrix_view matDTI = gsl_matrix_view_array(mDTInvertedPacked.get(), msize, msize);
505 std::cout <<
"Delta T matrix inverted packed " << std::endl;
506 for (
int ilmz = 0; ilmz < msize; ilmz++) {
507 for (
int ilmp = 0; ilmp < msize; ilmp++) {
508 std::cout.precision(3);
510 std::cout << mDTInvertedPacked[ilmz * msize + ilmp];
512 std::cout << std::endl;
517 std::unique_ptr<double[]> mQ(
new double[fMaxJM * fMaxJM * 4]);
518 for (
int iter = 0; iter < msize * msize; iter++)
520 gsl_matrix_view matQ = gsl_matrix_view_array(mQ.get(), msize, msize);
522 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, &matDTI.matrix, &matM.matrix, 0.0, &matQ.matrix);
525 std::unique_ptr<double[]> mTest(
new double[fMaxJM * fMaxJM * 4]);
526 gsl_matrix_view matTest = gsl_matrix_view_array(mTest.get(), msize, msize);
528 std::unique_ptr<double[]> mF(
new double[fMaxJM * fMaxJM * 4]);
529 for (
int iter = 0; iter < fMaxJM * fMaxJM * 4; iter++)
530 mF[iter] = mDeltaTPacked[iter];
531 gsl_matrix_view matF = gsl_matrix_view_array(mF.get(), msize, msize);
533 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, &matF.matrix, &matQ.matrix, 0.0, &matTest.matrix);
536 std::cout <<
"Test matrix packed - compare to Mtilde" << std::endl;
537 for (
int ilmz = 0; ilmz < msize; ilmz++) {
538 for (
int ilmp = 0; ilmp < msize; ilmp++) {
539 std::cout.precision(3);
541 std::cout << mTest[ilmz * msize + ilmp];
543 std::cout << std::endl;
549 std::unique_ptr<double[]> mP(
new double[fMaxJM * fMaxJM * 4]);
550 for (
int iter = 0; iter < fMaxJM * fMaxJM * 4; iter++)
553 gsl_matrix_view matP = gsl_matrix_view_array(mP.get(), msize, msize);
555 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, &matM.matrix, &matQ.matrix, 0.0, &matP.matrix);
558 std::cout <<
"P matrix packed " << std::endl;
559 for (
int ilmz = 0; ilmz < msize; ilmz++) {
560 for (
int ilmp = 0; ilmp < msize; ilmp++) {
561 std::cout.precision(3);
563 std::cout << mP[ilmz * msize + ilmp];
565 std::cout << std::endl;
570 std::unique_ptr<double[]> mPUnpacked(
new double[fMaxJM * fMaxJM * 4]);
571 UnPackYlmMatrixIndependentOnly(mP.get(), mPUnpacked.get(), msize);
574 std::cout <<
"P matrix unpacked " << std::endl;
575 for (
int ilmz = 0; ilmz < GetMaxJM() * 2; ilmz++) {
576 for (
int ilmp = 0; ilmp < GetMaxJM() * 2; ilmp++) {
577 std::cout.precision(3);
579 std::cout << mPUnpacked[ilmz * GetMaxJM() * 2 + ilmp];
581 std::cout << std::endl;
587 std::unique_ptr<double[]> mPInverted(
new double[fMaxJM * fMaxJM * 4]);
588 InvertYlmIndependentMatrix(mPUnpacked.get(), mPInverted.get());
590 std::unique_ptr<double[]> mPInvertedPacked(
new double[fMaxJM * fMaxJM * 4]);
591 PackYlmMatrixIndependentOnly(mPInverted.get(), mPInvertedPacked.get());
593 gsl_matrix_view matPI = gsl_matrix_view_array(mPInvertedPacked.get(), msize, msize);
596 std::cout <<
"P matrix inverted packed " << std::endl;
597 for (
int ilmz = 0; ilmz < msize; ilmz++) {
598 for (
int ilmp = 0; ilmp < msize; ilmp++) {
599 std::cout.precision(3);
601 std::cout << mPInvertedPacked[ilmz * msize + ilmp];
603 std::cout << std::endl;
633 std::unique_ptr<double[]> mR(
new double[fMaxJM * fMaxJM * 4]);
634 for (
int ir = 0; ir < fMaxJM * fMaxJM * 4; ir++)
636 gsl_matrix_view matR = gsl_matrix_view_array(mR.get(), msize, msize);
641 std::cout <<
"Matrix M Packed " << std::endl;
642 for (
int ilmz = 0; ilmz < msize; ilmz++) {
643 for (
int ilmp = 0; ilmp < msize; ilmp++) {
644 std::cout.precision(3);
646 std::cout << mMPacked[ilmz * msize + ilmp];
648 std::cout << std::endl;
652 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, &matPI.matrix, &matM.matrix, 1.0, &matR.matrix);
655 std::cout <<
"R matrix packed " << std::endl;
657 for (
int ilmz = 0; ilmz < msize; ilmz++) {
658 for (
int ilmp = 0; ilmp < msize; ilmp++) {
659 std::cout.precision(3);
661 std::cout << mR[ilmz * msize + ilmp];
663 std::cout << std::endl;
668 std::unique_ptr<double[]> vL(
new double[fMaxJM * 2]);
669 for (
int i = 0; i < fMaxJM * 2; i++)
671 gsl_vector_view vecL = gsl_vector_view_array(vL.get(), msize);
677 std::unique_ptr<double[]> vB(
new double[fMaxJM * 2]);
678 for (
int iter = 0; iter < GetMaxJM(); iter++) {
679 vB[iter * 2] = real(tTq0[iter]);
680 vB[iter * 2 + 1] = imag(tTq0[iter]);
683 std::unique_ptr<double[]> vBPacked(
new double[fMaxJM * 2]);
684 PackYlmVectorIndependentOnly(vB.get(), vBPacked.get());
686 gsl_vector_view vecB = gsl_vector_view_array(vBPacked.get(), msize);
693 std::cout <<
"L vector packed " << std::endl;
694 for (
int ilmp = 0; ilmp < msize; ilmp++) {
695 std::cout.precision(3);
697 std::cout << vL[ilmp];
699 std::cout << std::endl;
704 gsl_blas_dgemv(CblasNoTrans, 1.0, &matDTI.matrix, &vecB.vector, 0.0, &vecL.vector);
708 std::unique_ptr<double[]> vY(
new double[fMaxJM * 2]);
709 for (
int iter = 0; iter < GetMaxJM() * 2; iter++) {
714 gsl_vector_view vecY = gsl_vector_view_array(vY.get(), msize);
716 gsl_blas_dgemv(CblasNoTrans, 1.0, &matR.matrix, &vecL.vector, 0.0, &vecY.vector);
719 std::cout <<
"C vector packed " << std::endl;
720 for (
int ilmp = 0; ilmp < msize; ilmp++) {
721 std::cout.precision(3);
723 std::cout << vY[ilmp];
725 std::cout << std::endl;
729 for (
int ilm = 0; ilm < fMaxJM; ilm++) {
731 GetElEmForIndex(ilm, el, em);
733 fSlice.fCFReal[ilm] = 0.0;
734 fSlice.fCFImag[ilm] = 0.0;
738 fCFReal[ilm]->SetBinContent(ibin, fNumReal[ilm]->GetBinContent(ibin) / fDenReal[ilm]->GetBinContent(ibin));
739 fCFImag[ilm]->SetBinContent(ibin, fNumImag[ilm]->GetBinContent(ibin) / fDenImag[ilm]->GetBinContent(ibin));
743 fSlice.fCFReal[ilm] = 0.0;
744 fSlice.fCFImag[ilm] = 0.0;
746 fSlice.fCFReal[ilm] = vY[mpack++];
748 fSlice.fCFImag[ilm] = 0;
751 fSlice.fCFImag[ilm] = vY[mpack++];
776 for (
int ilm = 0; ilm < fMaxJM; ilm++) {
777 GetElEmForIndex(ilm, el, em);
779 fSlice.fCFRealE[ilm] = 0;
780 fSlice.fCFImagE[ilm] = 0;
782 fSlice.fCFRealE[ilm] = sqrt(fabs(mPInvertedPacked[mpack * msize + mpack]));
785 fSlice.fCFImag[ilm] = 0;
787 fSlice.fCFImagE[ilm] = sqrt(fabs(mPInvertedPacked[mpack * msize + mpack]));
793 for (
int ilmz = 0; ilmz < GetMaxJM() * 2; ilmz++) {
794 for (
int ilmp = 0; ilmp < GetMaxJM() * 2; ilmp++) {
796 fSlice.fCovCF[ilmz][ilmp] = mPInverted[ilmz * GetMaxJM() * 2 + ilmp];
798 fSlice.fCovCF[ilmz][ilmp] = mPInverted[ilmp * GetMaxJM() * 2 + ilmz];
803 void FemtoYlmSolver::Solve(Bool_t recalc) {
804 int nbins = fCF->GetNum()->GetNbinsX();
805 for (
int i = 1; i <= nbins; i++) {
806 fSlice.BuildSlice(*fCF, i);
807 if (fDebugBin == i) {
818 void FemtoYlmSolver::UpdateCF(Int_t bin) {
819 for (
int j = 0; j < fMaxJM; j++) {
820 fCF->fCFReal[j]->SetBinContent(bin, fSlice.fCFReal[j]);
821 fCF->fCFImag[j]->SetBinContent(bin, fSlice.fCFImag[j]);
822 fCF->fCFReal[j]->SetBinError(bin, fSlice.fCFRealE[j]);
823 fCF->fCFImag[j]->SetBinError(bin, fSlice.fCFImagE[j]);
825 for (
int a = 0; a < 2 * fMaxJM; a++) {
826 for (
int b = 0; b < 2 * fMaxJM; b++) {
827 fCF->fCovCf[bin - 1][a][b] = fSlice.fCovCF[a][b];
833 void FemtoYlmSolver::FixCF() {
834 for (
int l = 0; l <= fMaxL; l++) {
835 for (
int m = -l; m < 0; m++) {
836 Int_t from = fLmVals.GetIndex(l, -m);
837 Int_t to = fLmVals.GetIndex(l, m);
838 fSlice.fCFReal[to] = fSlice.fCFReal[from];
839 fSlice.fCFImag[to] = -fSlice.fCFImag[from];
840 fSlice.fCFRealE[to] = fSlice.fCFRealE[from];
841 fSlice.fCFImagE[to] = fSlice.fCFImagE[from];
846 void FemtoYlmSolver::SetNormalizationArea(Double_t min, Double_t max) {
847 TH1* num0 = fCF->fNumReal[0];
848 TH1* den0 = fCF->fDenReal[0];
851 double normbinmax = min;
852 double normbinmin = max;
854 if (normbinmax > 0) {
859 if (normbinmin < 1) normbinmin = 1;
860 if (normbinmax > den0->GetNbinsX()) normbinmax = den0->GetNbinsX();
862 normbinmax = den0->GetNbinsX();
863 for (
int ib = normbinmin; ib <= normbinmax; ib++) {
864 ks = den0->GetXaxis()->GetBinCenter(ib);
865 sk = num0->GetBinContent(ib) / (den0->GetBinContent(ib) * (1.0 - fNormPurity / (fNormRadius * fNormBohr * ks * ks)));
866 wk = num0->GetBinContent(ib);
870 fNormFactor *= sksum / wksum;
872 fNormFactor /= num0->GetEffectiveEntries() / den0->GetEffectiveEntries();
874 fNormFactor /= num0->GetEntries() / den0->GetEntries();
880 void FemtoYlmSolver::MakeFakeCovMatrix() {
881 double nent = fNumEnt;
882 double nentd = fDenEnt;
883 for (
int ilmx = 0; ilmx < GetMaxJM(); ilmx++) {
884 const int ilmx2 = ilmx * 2;
885 for (
int ilmy = 0; ilmy < GetMaxJM(); ilmy++) {
886 const int ilmy2 = ilmy * 2;
887 double t1t2rr = fSlice.fNumReal[ilmx] * fSlice.fNumReal[ilmy] / nent / nent;
888 double t1t2ri = fSlice.fNumReal[ilmx] * fSlice.fNumImag[ilmy] / nent / nent;
889 double t1t2ir = fSlice.fNumImag[ilmx] * fSlice.fNumReal[ilmy] / nent / nent;
890 double t1t2ii = fSlice.fNumImag[ilmx] * fSlice.fNumImag[ilmy] / nent / nent;
892 fSlice.fCovNum[ilmx2][ilmy2] = nent * (TMath::Power(fSlice.fNumRealE[ilmx] / nent, 2) * (nent - 1) + t1t2rr);
893 fSlice.fCovNum[ilmx2][ilmy2 + 1] = nent * t1t2ri;
894 fSlice.fCovNum[ilmx2 + 1][ilmy2] = nent * t1t2ir;
895 fSlice.fCovNum[ilmx2 + 1][ilmy2 + 1] = nent * (TMath::Power(fSlice.fNumImagE[ilmx] / nent, 2) * (nent - 1) + t1t2rr);
897 fSlice.fCovNum[ilmx2][ilmy2] = nent * t1t2rr;
898 fSlice.fCovNum[ilmx2][ilmy2 + 1] = nent * t1t2ri;
899 fSlice.fCovNum[ilmx2 + 1][ilmy2] = nent * t1t2ir;
900 fSlice.fCovNum[ilmx2 + 1][ilmy2 + 1] = nent * t1t2ii;
902 t1t2rr = fSlice.fDenReal[ilmx] * fSlice.fDenReal[ilmy] / nentd / nentd;
903 t1t2ri = fSlice.fDenReal[ilmx] * fSlice.fDenImag[ilmy] / nentd / nentd;
904 t1t2ir = fSlice.fDenImag[ilmx] * fSlice.fDenReal[ilmy] / nentd / nentd;
905 t1t2ii = fSlice.fDenImag[ilmx] * fSlice.fDenImag[ilmy] / nentd / nentd;
908 fSlice.fCovDen[ilmx2 + 0][ilmy2 + 0] = nentd * t1t2rr;
909 fSlice.fCovDen[ilmx2 + 0][ilmy2 + 1] = nentd * t1t2ri;
910 fSlice.fCovDen[ilmx2 + 1][ilmy2 + 0] = nentd * t1t2ir;
911 fSlice.fCovDen[ilmx2 + 1][ilmy2 + 1] = nentd * t1t2ii;