141 DeleteMatrix(&fVyyInv);
230 for(
Int_t i=0;i<2;i++) {
334 if(rank !=
GetNx()) {
335 Warning(
"DoUnfold",
"rank of matrix E %d expect %d",rank,
GetNx());
359 epsilonNosparse(A_cols[i],0) += A_data[i];
371 Fatal(
"Unfold",
"epsilon#Eepsilon has dimension %d != 1",
378 y_minus_epsx += (*fY)(iy,0);
381 for(
Int_t ix=0;ix<epsilonNosparse.GetNrows();ix++) {
382 y_minus_epsx -= epsilonNosparse(ix,0) * (*fX)(ix,0);
385 lambda_half=y_minus_epsx*one_over_epsEeps;
390 if(EEpsilon_rows[ix]<EEpsilon_rows[ix+1]) {
391 (*fX)(ix,0) += lambda_half * EEpsilon_data[EEpsilon_rows[ix]];
410 data[i]=one_over_epsEeps;
420 AddMSparse(temp, -one_over_epsEeps, epsilonB);
457 if(VyyinvDy_rows[iy]<VyyinvDy_rows[iy+1]) {
458 fChi2A += VyyinvDy_data[VyyinvDy_rows[iy]]*dy(iy,0);
467 if(LsquaredDx_rows[ix]<LsquaredDx_rows[ix+1]) {
468 fLXsquared += LsquaredDx_data[LsquaredDx_rows[ix]]*dx(ix,0);
483 "epsilon#fDXDtauSquared has dimension %d != 1",
506 (Eepsilon,Eepsilon,0);
531 if(rank !=
GetNx()) {
532 Warning(
"DoUnfold",
"rank of output covariance is %d expect %d",
541 for(
int ik=VxxInv_rows[ix];ik<VxxInv_rows[ix+1];ik++) {
542 if(ix==VxxInv_cols[ik]) {
543 VxxInvDiag(ix)=VxxInv_data[ik];
557 for(
int ik=Vxx_rows[ix];ik<Vxx_rows[ix+1];ik++) {
558 if(ix==Vxx_cols[ik]) {
560 1. - 1. / (VxxInvDiag(ix) * Vxx_data[ik]);
561 if (rho_squared > rho_squared_max)
562 rho_squared_max = rho_squared;
563 if(rho_squared>0.0) {
572 fRhoAvg = (n_rho>0) ? (rho_sum/n_rho) : -1.0;
621 Fatal(
"MultiplyMSparseMSparse",
622 "inconsistent matrix col/ matrix row %d !=%d",
636 if(a_rows[irow+1]>a_rows[irow]) nMax += b->
GetNcols();
638 if((nMax>0)&&(a_cols)&&(b_cols)) {
645 if(a_rows[irow+1]<=a_rows[irow])
continue;
651 for(
Int_t ia=a_rows[irow];ia<a_rows[irow+1];ia++) {
654 for(
Int_t ib=b_rows[k];ib<b_rows[k+1];ib++) {
655 row_data[b_cols[ib]] += a_data[ia]*b_data[ib];
660 if(row_data[icol] != 0.0) {
663 r_data[
n]=row_data[icol];
669 r->SetMatrixArray(n,r_rows,r_cols,r_data);
696 Fatal(
"MultiplyMSparseTranspMSparse",
697 "inconsistent matrix row numbers %d!=%d",
711 typedef std::map<Int_t,Double_t> MMatrixRow_t;
712 typedef std::map<Int_t, MMatrixRow_t > MMatrix_t;
716 for(
Int_t ia=a_rows[iRowAB];ia<a_rows[iRowAB+1];ia++) {
717 for(
Int_t ib=b_rows[iRowAB];ib<b_rows[iRowAB+1];ib++) {
719 MMatrixRow_t &row=matrix[a_cols[ia]];
720 MMatrixRow_t::iterator icol=row.find(b_cols[ib]);
721 if(icol!=row.end()) {
723 (*icol).second += a_data[ia]*b_data[ib];
726 row[b_cols[ib]] = a_data[ia]*b_data[ib];
733 for(MMatrix_t::const_iterator irow=matrix.begin();
734 irow!=matrix.end();irow++) {
735 n += (*irow).second.size();
743 for(MMatrix_t::const_iterator irow=matrix.begin();
744 irow!=matrix.end();irow++) {
745 for(MMatrixRow_t::const_iterator icol=(*irow).second.begin();
746 icol!=(*irow).second.end();icol++) {
747 r_rows[
n]=(*irow).first;
748 r_cols[
n]=(*icol).first;
749 r_data[
n]=(*icol).second;
755 r->SetMatrixArray(n,r_rows,r_cols,r_data);
780 Fatal(
"MultiplyMSparseM",
"inconsistent matrix col /matrix row %d!=%d",
791 if(a_rows[irow+1]-a_rows[irow]>0) nMax += b->
GetNcols();
801 if(a_rows[irow+1]-a_rows[irow]<=0)
continue;
806 for(
Int_t i=a_rows[irow];i<a_rows[irow+1];i++) {
808 r_data[
n] += a_data[i]*(*b)(j,icol);
810 if(r_data[n]!=0.0) n++;
814 r->SetMatrixArray(n,r_rows,r_cols,r_data);
842 Fatal(
"MultiplyMSparseMSparseTranspVector",
843 "matrix cols/vector rows %d!=%d!=%d or vector rows %d!=1\n",
846 Fatal(
"MultiplyMSparseMSparseTranspVector",
855 if(rows_m1[i]<rows_m1[i+1]) num_m1++;
862 if(rows_m2[j]<rows_m2[j+1]) num_m2++;
865 const Int_t *v_rows=0;
871 Int_t num_r=num_m1*num_m2+1;
879 Int_t index_m1=rows_m1[i];
880 Int_t index_m2=rows_m2[j];
881 while((index_m1<rows_m1[i+1])&&(index_m2<rows_m2[j+1])) {
882 Int_t k1=cols_m1[index_m1];
883 Int_t k2=cols_m2[index_m2];
890 Int_t v_index=v_rows[k1];
891 if(v_index<v_rows[k1+1]) {
892 data_r[num_r] += data_m1[index_m1] * data_m2[index_m2]
896 data_r[num_r] += data_m1[index_m1] * data_m2[index_m2]
899 data_r[num_r] += data_m1[index_m1] * data_m2[index_m2];
905 if(data_r[num_r] !=0.0) {
913 num_r,row_r,col_r,data_r);
945 Fatal(
"AddMSparse",
"inconsistent matrix rows %d!=%d OR cols %d!=%d",
954 Int_t i_dest=dest_rows[row];
955 Int_t i_src=src_rows[row];
956 while((i_dest<dest_rows[row+1])||(i_src<src_rows[row+1])) {
957 Int_t col_dest=(i_dest<dest_rows[row+1]) ?
958 dest_cols[i_dest] : dest->
GetNcols();
959 Int_t col_src =(i_src <src_rows[row+1] ) ?
962 if(col_dest<col_src) {
963 result_cols[
n]=col_dest;
964 result_data[
n]=dest_data[i_dest++];
965 }
else if(col_dest>col_src) {
966 result_cols[
n]=col_src;
967 result_data[
n]=f*src_data[i_src++];
969 result_cols[
n]=col_dest;
970 result_data[
n]=dest_data[i_dest++]+f*src_data[i_src++];
972 if(result_data[n] !=0.0) {
974 Fatal(
"AddMSparse",
"Nan detected %d %d %d",
988 delete[] result_data;
989 delete[] result_rows;
990 delete[] result_cols;
1015 Fatal(
"InvertMSparseSymmPos",
"inconsistent matrix row/col %d!=%d",
1032 for(
Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
1033 Int_t jA=a_cols[indexA];
1035 if(!(a_data[indexA]>=0.0)) nError++;
1036 aII(iA)=a_data[indexA];
1041 Fatal(
"InvertMSparseSymmPos",
1042 "Matrix has %d negative elements on the diagonal", nError);
1058 for(
Int_t iStart=0;iStart<iBlock;iStart++) {
1060 for(
Int_t i=iStart;i<iBlock;i++) {
1064 Int_t tmp=swap[iStart];
1065 swap[iStart]=swap[i];
1071 Int_t iA=swap[iStart];
1072 for(
Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
1073 Int_t jA=a_cols[indexA];
1082 for(
Int_t i=iStart+1;i<iBlock;) {
1083 if(isZero[swap[i]]) {
1087 Int_t tmp=swap[iBlock];
1088 swap[iBlock]=swap[i];
1100 #ifdef CONDITION_BLOCK_PART 1102 for(
int inc=(nn+1)/2;inc;inc /= 2) {
1103 for(
int i=inc;i<
nn;i++) {
1104 int itmp=swap[i+iBlock];
1106 for(j=i;(j>=inc)&&(aII(swap[j-inc+iBlock])<aII(itmp));j -=inc) {
1107 swap[j+iBlock]=swap[j-inc+iBlock];
1109 swap[j+iBlock]=itmp;
1116 swapBack[swap[i]]=i;
1120 std::cout<<
" "<<i<<
" "<<swap[i]<<
" "<<swapBack[i]<<
"\n";
1122 std::cout<<
"after sorting\n";
1124 if(i==iDiagonal) std::cout<<
"iDiagonal="<<i<<
"\n";
1125 if(i==iBlock) std::cout<<
"iBlock="<<i<<
"\n";
1126 std::cout<<
" "<<swap[i]<<
" "<<aII(swap[i])<<
"\n";
1140 for(
Int_t indexA=a_rows[row];indexA<a_rows[row+1];indexA++) {
1141 Int_t j=swapBack[a_cols[indexA]];
1143 else if((i<iDiagonal)||(j<iDiagonal)) nError1++;
1144 else if((i<iBlock)&&(j<iBlock)) nError2++;
1145 else if((i<iBlock)||(j<iBlock)) nBlock++;
1149 if(nError1+nError2>0) {
1150 Fatal(
"InvertMSparseSymmPos",
"sparse matrix analysis failed %d %d %d %d %d",
1151 iDiagonal,iBlock,A->
GetNrows(),nError1,nError2);
1156 Info(
"InvertMSparseSymmPos",
"iDiagonal=%d iBlock=%d nRow=%d",
1216 for(
Int_t i=0;i<iDiagonal;++i) {
1221 rEl_data[rNumEl]=1./aII(iA);
1226 if((!rankPtr)&&(rankD1!=iDiagonal)) {
1227 Fatal(
"InvertMSparseSymmPos",
1228 "diagonal part 1 has rank %d != %d, matrix can not be inverted",
1236 Int_t nD2=iBlock-iDiagonal;
1238 if((rNumEl>=0)&&(nD2>0)) {
1243 for(
Int_t i=0;i<nD2;++i) {
1244 Int_t iA=swap[i+iDiagonal];
1246 D2inv_col[D2invNumEl]=i;
1247 D2inv_row[D2invNumEl]=i;
1248 D2inv_data[D2invNumEl]=1./aII(iA);
1252 if(D2invNumEl==nD2) {
1255 }
else if(!rankPtr) {
1256 Fatal(
"InvertMSparseSymmPos",
1257 "diagonal part 2 has rank %d != %d, matrix can not be inverted",
1261 delete [] D2inv_data;
1262 delete [] D2inv_col;
1263 delete [] D2inv_row;
1273 if((rNumEl>=0)&&(nF>0)&&((nD2==0)||D2inv)) {
1282 Int_t nBmax=nF*(nD2+1);
1288 for(
Int_t i=0;i<nF;i++) {
1289 Int_t iA=swap[i+iBlock];
1290 for(
Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
1291 Int_t jA=a_cols[indexA];
1292 Int_t j0=swapBack[jA];
1297 F_data[FnumEl]=a_data[indexA];
1299 }
else if(j0>=iDiagonal) {
1300 Int_t j=j0-iDiagonal;
1303 B_data[BnumEl]=a_data[indexA];
1310 #ifndef FORCE_EIGENVALUE_DECOMPOSITION 1330 for(
Int_t i=0;i<mbd2_nMax;i++) {
1331 mbd2_data[i] = - mbd2_data[i];
1335 if(minusBD2inv && F) {
1350 for(
Int_t i=0;i<nF;i++) {
1351 for(
Int_t indexF=f_rows[i];indexF<f_rows[i+1];indexF++) {
1352 if(f_cols[indexF]>=i) c(f_cols[indexF],i)=f_data[indexF];
1356 for(
Int_t j=0;j<i;j++) {
1367 for(
Int_t j=i+1;j<nF;j++) {
1369 for(
Int_t k=0;k<i;k++) {
1370 c_ji -= c(i,k)*c(j,k);
1379 for(
Int_t i=1;i<nF;i++) {
1384 std::cout<<
"dmin,dmax: "<<dmin<<
" "<<dmax<<
"\n";
1386 if(dmin/dmax<epsilonF2*nF) nErrorF=2;
1392 for(
Int_t i=0;i<nF;i++) {
1393 cinv(i,i)=1./c(i,i);
1395 for(
Int_t i=0;i<nF;i++) {
1396 for(
Int_t j=i+1;j<nF;j++) {
1398 for(
Int_t k=i+1;k<j;k++) {
1399 tmp -= cinv(k,i)*c(j,k);
1401 cinv(j,i)=tmp*cinv(j,j);
1406 (&cInvSparse,&cInvSparse);
1417 Int_t rankD2Block=0;
1419 if( ((nD2==0)||D2inv) && ((nF==0)||Finv) ) {
1429 if(Finv && minusBD2inv) {
1434 if(G && minusBD2inv) {
1441 E=minusBD2invTransG;
1450 Int_t iA=swap[iE+iDiagonal];
1451 for(
Int_t indexE=e_rows[iE];indexE<e_rows[iE+1];++indexE) {
1452 Int_t jE=e_cols[indexE];
1453 Int_t jA=swap[jE+iDiagonal];
1456 rEl_data[rNumEl]=e_data[indexE];
1468 Int_t iA=swap[iG+iBlock];
1469 for(
Int_t indexG=g_rows[iG];indexG<g_rows[iG+1];++indexG) {
1470 Int_t jG=g_cols[indexG];
1471 Int_t jA=swap[jG+iDiagonal];
1475 rEl_data[rNumEl]=g_data[indexG];
1480 rEl_data[rNumEl]=g_data[indexG];
1492 Int_t iA=swap[iF+iBlock];
1493 for(
Int_t indexF=finv_rows[iF];indexF<finv_rows[iF+1];++indexF) {
1494 Int_t jF=finv_cols[indexF];
1495 Int_t jA=swap[jF+iBlock];
1498 rEl_data[rNumEl]=finv_data[indexF];
1504 }
else if(!rankPtr) {
1506 Fatal(
"InvertMSparseSymmPos",
1507 "non-trivial part has rank < %d, matrix can not be inverted",
1514 Info(
"InvertMSparseSymmPos",
1515 "cholesky-decomposition failed, try eigenvalue analysis");
1517 std::cout<<
"nEV="<<nEV<<
" iDiagonal="<<iDiagonal<<
"\n";
1520 for(
Int_t i=0;i<nEV;i++) {
1521 Int_t iA=swap[i+iDiagonal];
1522 for(
Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
1523 Int_t jA=a_cols[indexA];
1524 Int_t j0=swapBack[jA];
1526 Int_t j=j0-iDiagonal;
1528 if((i<0)||(j<0)||(i>=nEV)||(j>=nEV)) {
1529 std::cout<<
" error "<<nEV<<
" "<<i<<
" "<<j<<
"\n";
1533 Fatal(
"InvertMSparseSymmPos",
1534 "non-finite number detected element %d %d\n",
1537 EV(i,j)=a_data[indexA];
1544 std::cout<<
"Eigenvalues\n";
1554 if(condition<-epsilonEV2) {
1559 Error(
"InvertMSparseSymmPos",
1560 "Largest Eigenvalue is negative %f",
1563 Error(
"InvertMSparseSymmPos",
1564 "Some Eigenvalues are negative (EV%d/EV0=%g epsilon=%g)",
1574 for(
Int_t i=0;i<nEV;i++) {
1577 inverseEV(i,0)=1./
x;
1586 const Int_t *vdvt_rows=VDVt->GetRowIndexArray();
1587 const Int_t *vdvt_cols=VDVt->GetColIndexArray();
1588 const Double_t *vdvt_data=VDVt->GetMatrixArray();
1589 for(
Int_t iVDVt=0;iVDVt<VDVt->GetNrows();iVDVt++) {
1590 Int_t iA=swap[iVDVt+iDiagonal];
1591 for(
Int_t indexVDVt=vdvt_rows[iVDVt];
1592 indexVDVt<vdvt_rows[iVDVt+1];++indexVDVt) {
1593 Int_t jVDVt=vdvt_cols[indexVDVt];
1594 Int_t jA=swap[jVDVt+iDiagonal];
1597 rEl_data[rNumEl]=vdvt_data[indexVDVt];
1605 *rankPtr=rankD1+rankD2Block;
1620 rEl_row,rEl_col,rEl_data) : 0;
1648 std::cout<<
"Ar is not symmetric Ar("<<i<<
","<<j<<
")="<<ar(i,j)
1649 <<
" Ar("<<j<<
","<<i<<
")="<<ar(j,i)<<
"\n";
1654 std::cout<<
"ArA is not equal A ArA("<<i<<
","<<j<<
")="<<ara(i,j)
1655 <<
" A("<<i<<
","<<j<<
")="<<
a(i,j)<<
"\n";
1660 std::cout<<
"rAr is not equal r rAr("<<i<<
","<<j<<
")="<<rar(i,j)
1661 <<
" r("<<i<<
","<<j<<
")="<<
R(i,j)<<
"\n";
1665 if(rankPtr) std::cout<<
"rank="<<*rankPtr<<
"\n";
1667 std::cout<<
"Matrix is not positive\n";
1757 for (
Int_t ix = 0; ix < nx0; ix++) {
1762 for (
Int_t iy = 0; iy <
ny; iy++) {
1800 Int_t underflowBin=0,overflowBin=0;
1801 for (
Int_t ix = 0; ix <
nx; ix++) {
1803 if(ibinx<1) underflowBin=1;
1805 if(ibinx>hist_A->
GetNbinsX()) overflowBin=1;
1807 if(ibinx>hist_A->
GetNbinsY()) overflowBin=1;
1812 Int_t ixfirst=-1,ixlast=-1;
1814 int nDisconnected=0;
1815 for (
Int_t ix = 0; ix < nx0; ix++) {
1826 if(((
fHistToX[ix]>=0)&&(ixlast>=0))||
1827 (nprint==nskipped)) {
1828 if(ixlast>ixfirst) {
1835 if(nprint==nskipped) {
1839 if(nskipped==(2-underflowBin-overflowBin)) {
1840 Info(
"TUnfold",
"underflow and overflow bin " 1841 "do not depend on the input data");
1843 Warning(
"TUnfold",
"%d output bins " 1844 "do not depend on the input data %s",nDisconnected,
1845 static_cast<const char *>(binlist));
1856 for (
Int_t iy = 0; iy <
ny; iy++) {
1857 for (
Int_t ix = 0; ix <
nx; ix++) {
1873 if(underflowBin && overflowBin) {
1874 Info(
"TUnfold",
"%d input bins and %d output bins (includes 2 underflow/overflow bins)",ny,nx);
1875 }
else if(underflowBin) {
1876 Info(
"TUnfold",
"%d input bins and %d output bins (includes 1 underflow bin)",ny,nx);
1877 }
else if(overflowBin) {
1878 Info(
"TUnfold",
"%d input bins and %d output bins (includes 1 overflow bin)",ny,nx);
1880 Info(
"TUnfold",
"%d input bins and %d output bins",ny,nx);
1884 Error(
"TUnfold",
"too few (ny=%d) input bins for nx=%d output bins",ny,nx);
1886 Warning(
"TUnfold",
"too few (ny=%d) input bins for nx=%d output bins",ny,nx);
1898 "%d regularisation conditions have been skipped",nError);
1901 "One regularisation condition has been skipped");
1991 for(
Int_t k=l0_rows[row];k<l0_rows[row+1];k++) {
1993 l_col[nF]=l0_cols[k];
1994 l_data[nF]=l0_data[k];
2006 for(
Int_t i=0;i<nEle;i++) {
2014 l_data[nF]=rowData[i];
2138 (left_bin,-scale_left,
2139 center_bin,scale_left+scale_right,
2140 right_bin,-scale_right)
2187 Error(
"RegularizeBins",
"regmode = %d is not valid",regmode);
2189 for (
Int_t i = nSkip; i < nbin; i++) {
2226 int step2,
int nbin2,
ERegMode regmode)
2239 for (
Int_t i1 = 0; i1 < nbin1; i1++) {
2240 nError +=
RegularizeBins(start_bin + step1 * i1, step2, nbin2, regmode);
2242 for (
Int_t i2 = 0; i2 < nbin2; i2++) {
2243 nError +=
RegularizeBins(start_bin + step2 * i2, step1, nbin1, regmode);
2305 const TH2 *hist_vyy_inv)
2327 Int_t nVarianceZero=0;
2328 Int_t nVarianceForced=0;
2338 if(oneOverZeroError>0.0) {
2339 dy2 = 1./ ( oneOverZeroError*oneOverZeroError);
2351 rowVyyN[nVyyN] = iy;
2352 colVyyN[nVyyN] = iy;
2353 rowVyy1[nVyy1] = iy;
2355 dataVyyDiag[iy] = dy2;
2357 dataVyyN[nVyyN++] = dy2;
2358 dataVyy1[nVyy1++] = dy2;
2363 Int_t nOffDiagNonzero=0;
2366 if(dataVyyDiag[iy]<=0.0) {
2376 if(iy==jy)
continue;
2378 if(dataVyyDiag[jy]<=0.0)
continue;
2380 rowVyyN[nVyyN] = iy;
2381 colVyyN[nVyyN] = jy;
2383 if(dataVyyN[nVyyN] == 0.0)
continue;
2389 "inverse of input covariance is taken from user input");
2396 rowVyyInv[nVyyInv] = iy;
2397 colVyyInv[nVyyInv] = jy;
2398 dataVyyInv[nVyyInv]= hist_vyy_inv->
GetBinContent(iy+1,jy+1);
2399 if(dataVyyInv[nVyyInv] == 0.0)
continue;
2404 (
GetNy(),
GetNy(),nVyyInv,rowVyyInv,colVyyInv,dataVyyInv);
2405 delete [] rowVyyInv;
2406 delete [] colVyyInv;
2407 delete [] dataVyyInv;
2409 if(nOffDiagNonzero) {
2411 "input covariance has elements C(X,Y)!=0 where V(X)==0");
2417 (
GetNy(),
GetNy(),nVyyN,rowVyyN,colVyyN,dataVyyN);
2424 (
GetNy(),1,nVyy1,rowVyy1,colVyy1, dataVyy1);
2447 if(nVarianceForced) {
2448 if(nVarianceForced>1) {
2449 Warning(
"SetInput",
"%d/%d input bins have zero error," 2450 " 1/error set to %lf.",
2451 nVarianceForced,
GetNy(),oneOverZeroError);
2453 Warning(
"SetInput",
"One input bin has zero error," 2454 " 1/error set to %lf.",oneOverZeroError);
2458 if(nVarianceZero>1) {
2459 Warning(
"SetInput",
"%d/%d input bins have zero error," 2460 " and are ignored.",nVarianceZero,
GetNy());
2462 Warning(
"SetInput",
"One input bin has zero error," 2463 " and is ignored.");
2469 if(oneOverZeroError<=0.0) {
2475 TString binlist(
"no data to constrain output bin ");
2486 Warning(
"SetInput",
"%s",(
char const *)binlist);
2491 Error(
"SetInput",
"%d/%d output bins are not constrained by any data.",
2494 Error(
"SetInput",
"One output bins is not constrained by any data.");
2499 delete[] dataVyyDiag;
2501 return nVarianceForced+nVarianceZero+10000*nError2;
2556 typedef std::map<Double_t,std::pair<Double_t,Double_t> > XYtau_t;
2581 if((tauMin<=0)||(tauMax<=0.0)||(tauMin>=tauMax)) {
2591 Error(
"ScanLcurve",
"too few input bins, NDF<=0 %d",
GetNdf());
2596 Info(
"ScanLcurve",
"logtau=-Infinity X=%lf Y=%lf",x0,y0);
2598 Fatal(
"ScanLcurve",
"problem (too few input bins?) X=%f",x0);
2601 Fatal(
"ScanLcurve",
"problem (missing regularisation?) Y=%f",y0);
2610 Fatal(
"ScanLcurve",
"problem (missing regularisation?) X=%f Y=%f",
2614 Info(
"ScanLcurve",
"logtau=%lf X=%lf Y=%lf",
2617 if((*curve.begin()).second.first<x0) {
2629 Fatal(
"ScanLcurve",
"problem (missing regularisation?) X=%f Y=%f",
2633 Info(
"ScanLcurve",
"logtau=%lf X=%lf Y=%lf",
2636 while(((
int)curve.size()<(nPoint-1)/2)&&
2637 ((*curve.begin()).second.first<x0));
2644 while(((
int)curve.size()<nPoint-1)&&
2645 (((*curve.begin()).second.first-x0>0.00432)||
2646 ((*curve.begin()).second.second-y0>0.00432)||
2647 (curve.size()<2))) {
2651 Fatal(
"ScanLcurve",
"problem (missing regularisation?) X=%f Y=%f",
2655 Info(
"ScanLcurve",
"logtau=%lf X=%lf Y=%lf",
2666 Fatal(
"ScanLcurve",
"problem (missing regularisation?) X=%f Y=%f",
2669 Info(
"ScanLcurve",
"logtau=%lf X=%lf Y=%lf",
2676 Fatal(
"ScanLcurve",
"problem (missing regularisation?) X=%f Y=%f",
2679 Info(
"ScanLcurve",
"logtau=%lf X=%lf Y=%lf",
2689 while(
int(curve.size())<nPoint-1) {
2692 XYtau_t::const_iterator i0,i1;
2697 for(i1++;i1!=curve.end();i1++) {
2698 const std::pair<Double_t,Double_t> &xy0=(*i0).second;
2699 const std::pair<Double_t,Double_t> &xy1=(*i1).second;
2705 logTau=0.5*((*i0).first+(*i1).first);
2711 Fatal(
"ScanLcurve",
"problem (missing regularisation?) X=%f Y=%f",
2723 XYtau_t::const_iterator i0,i1;
2728 if( ((
int)curve.size())<nPoint) {
2737 for( XYtau_t::const_iterator i=curve.begin();i!=curve.end();i++) {
2738 lXi[
n]=(*i).second.first;
2739 lYi[
n]=(*i).second.second;
2747 for(
Int_t i=0;i<n-1;i++) {
2749 splineX->
GetCoeff(i,ltau,xy,bi,ci,di);
2750 Double_t tauBar=0.5*(lTi[i]+lTi[i+1]);
2751 Double_t dTau=0.5*(lTi[i+1]-lTi[i]);
2752 Double_t dx1=bi+dTau*(2.*ci+3.*di*dTau);
2754 splineY->
GetCoeff(i,ltau,xy,bi,ci,di);
2755 Double_t dy1=bi+dTau*(2.*ci+3.*di*dTau);
2758 cCi[i]=(dy2*dx1-dy1*dx2)/
TMath::Power(dx1*dx1+dy1*dy1,1.5);
2778 for(
Int_t i=iskip;i<n-2-iskip;i++) {
2801 xx = m_p_half + discr;
2803 xx = m_p_half - discr;
2807 if((xx>0.0)&&(xx<dx)) {
2808 y=splineC->
Eval(x+xx);
2821 if((xx>0.0)&&(xx<dx)) {
2822 y=splineC->
Eval(x+xx);
2835 if(logTauCurvature) {
2836 *logTauCurvature=splineC;
2845 Fatal(
"ScanLcurve",
"problem (missing regularisation?) X=%f Y=%f",
2848 Info(
"ScanLcurve",
"Result logtau=%lf X=%lf Y=%lf",
2858 Int_t bestChoice=-1;
2859 if(curve.size()>0) {
2864 for( XYtau_t::const_iterator i=curve.begin();i!=curve.end();i++) {
2865 if(logTauFin==(*i).first) {
2868 x[
n]=(*i).second.first;
2869 y[
n]=(*i).second.second;
2874 (*lCurve)=
new TGraph(n,x,y);
2875 (*lCurve)->SetTitle(
"L curve");
2877 if(logTauX) (*logTauX)=
new TSpline3(
"log(chi**2)%log(tau)",logT,x,n);
2878 if(logTauY) (*logTauY)=
new TSpline3(
"log(reg.cond)%log(tau)",logT,y,n);
2965 Int_t destI = binMap ? binMap[i+1] : i+1;
2966 if(destI<0)
continue;
2970 Int_t index_a=rows_A[i];
2971 Int_t index_av=rows_AVxx[i];
2972 while((index_a<rows_A[i+1])&&(index_av<rows_AVxx[i+1])) {
2973 Int_t j_a=cols_A[index_a];
2974 Int_t j_av=cols_AVxx[index_av];
2977 }
else if(j_a>j_av) {
2980 e2 += data_AVxx[index_av] * data_A[index_a];
3008 for(
Int_t indexA=rows_A[iy];indexA<rows_A[iy+1];indexA++) {
3009 Int_t ix = cols_A[indexA];
3043 Int_t destI=binMap ? binMap[i+1] : i+1;
3044 if(destI<0)
continue;
3049 for(
int index=rows_Vyy[i];index<rows_Vyy[i+1];index++) {
3050 if(cols_Vyy[index]==i) {
3074 Warning(
"GetInputInverseEmatrix",
"input covariance matrix has rank %d expect %d",
3078 Error(
"GetInputInverseEmatrix",
"number of parameters %d > %d (rank of input covariance). Problem can not be solved",
GetNpar(),rank);
3079 }
else if(
fNdf==0) {
3080 Warning(
"GetInputInverseEmatrix",
"number of parameters %d = input rank %d. Problem is ill posed",
GetNpar(),rank);
3089 for(
int i=0;i<=out->
GetNbinsX()+1;i++) {
3090 for(
int j=0;j<=out->
GetNbinsY()+1;j++) {
3096 for(
int index=rows_VyyInv[i];index<rows_VyyInv[i+1];index++) {
3097 Int_t j=cols_VyyInv[index];
3127 for (
Int_t cindex = rows[i]; cindex < rows[i+1]; cindex++) {
3128 Int_t j=cols[cindex];
3163 for (
Int_t cindex = rows[row]; cindex < rows[row+1]; cindex++) {
3164 Int_t col=cols[cindex];
3277 std::map<Int_t,Double_t> e2;
3284 for(
Int_t i=0;i<binMapSize;i++) {
3285 Int_t destBinI=binMap ? binMap[i] : i;
3287 if((destBinI>=0)&&(srcBinI>=0)) {
3295 Int_t index_vxx=rows_Vxx[srcBinI];
3297 while((j<binMapSize)&&(index_vxx<rows_Vxx[srcBinI+1])) {
3298 Int_t destBinJ=binMap ? binMap[j] : j;
3299 if(destBinI!=destBinJ) {
3308 if(cols_Vxx[index_vxx]<srcBinJ) {
3311 }
else if(cols_Vxx[index_vxx]>srcBinJ) {
3316 e2[destBinI] += data_Vxx[index_vxx];
3326 for(std::map<Int_t,Double_t>::const_iterator i=e2.begin();
3352 for(
Int_t i=0;i<nbin+2;i++) {
3353 for(
Int_t j=0;j<nbin+2;j++) {
3366 for(
Int_t i=0;i<binMapSize;i++) {
3367 Int_t destBinI=binMap ? binMap[i] : i;
3369 if((destBinI>=0)&&(destBinI<nbin+2)&&(srcBinI>=0)) {
3375 Int_t index_vxx=rows_emat[srcBinI];
3376 while((j<binMapSize)&&(index_vxx<rows_emat[srcBinI+1])) {
3377 Int_t destBinJ=binMap ? binMap[j] : j;
3379 if((destBinJ<0)||(destBinJ>=nbin+2)||(srcBinJ<0)) {
3383 if(cols_emat[index_vxx]<srcBinJ) {
3386 }
else if(cols_emat[index_vxx]>srcBinJ) {
3392 + data_emat[index_vxx];
3434 for(
Int_t i=0;i<nbin+2;i++) {
3437 for(
Int_t i=0;i<nbin+2;i++) {
3438 for(
Int_t j=0;j<nbin+2;j++) {
3439 if((e[i]>0.0)&&(e[j]>0.0)) {
3493 for(
int index_vxx=rows_Vxx[i];index_vxx<rows_Vxx[i+1];index_vxx++) {
3494 if(cols_Vxx[index_vxx]==i) {
3495 e_ii=data_Vxx[index_vxx];
3499 for(
int index_vxxinv=rows_VxxInv[i];index_vxxinv<rows_VxxInv[i+1];
3501 if(cols_VxxInv[index_vxxinv]==i) {
3502 einv_ii=data_VxxInv[index_vxxinv];
3507 if((einv_ii>0.0)&&(e_ii>0.0)) rho=1.-1./(einv_ii*e_ii);
3533 const Int_t *binMap,
TH2 *invEmat)
const 3545 std::map<int,int> histToLocalBin;
3547 for(
Int_t i=0;i<binMapSize;i++) {
3548 Int_t mapped_i=binMap ? binMap[i] : i;
3550 if(histToLocalBin.find(mapped_i)==histToLocalBin.end()) {
3551 histToLocalBin[mapped_i]=nBin;
3561 for(std::map<int,int>::const_iterator i=histToLocalBin.begin();
3562 i!=histToLocalBin.end();i++) {
3563 localBinToHist[(*i).second]=(*i).first;
3580 Int_t destI=binMap ? binMap[origI] : origI;
3581 if(destI<0)
continue;
3582 Int_t ematBinI=histToLocalBin[destI];
3583 for(
int index_eOrig=rows_eOrig[i];index_eOrig<rows_eOrig[i+1];
3586 Int_t j=cols_eOrig[index_eOrig];
3590 Int_t destJ=binMap ? binMap[origJ] : origJ;
3591 if(destJ<0)
continue;
3592 Int_t ematBinJ=histToLocalBin[destJ];
3593 eRemap(ematBinI,ematBinJ) += data_eOrig[index_eOrig];
3601 Warning(
"GetRhoIFormMatrix",
"Covariance matrix has rank %d expect %d",
3612 for(
Int_t index_einv=rows_eInv[i];index_einv<rows_eInv[i+1];
3614 Int_t j=cols_eInv[index_einv];
3616 einv_ii=data_eInv[index_einv];
3620 data_eInv[index_einv]);
3624 if((einv_ii>0.0)&&(e_ii>0.0)) rho=1.-1./(einv_ii*e_ii);
3635 delete [] localBinToHist;
3656 for(
int i=0;i<3;i++) ixyz[i]=0;
3657 while((ixyz[0]<=nxyz[0])&&
3658 (ixyz[1]<=nxyz[1])&&
3659 (ixyz[2]<=nxyz[2])){
3663 for(
Int_t i=0;i<3;i++) {
3665 if(ixyz[i]<=nxyz[i])
break;
void GetNormalisationVector(TH1 *s, const Int_t *binMap=0) const
Histogram of truth bins, determined from summing over the response matrix.
virtual const Element * GetMatrixArray() const
void SetBias(const TH1 *bias)
Set bias vector.
EConstraint fConstraint
type of constraint to use for the unfolding
static long int sum(long int i)
TMatrixDSparse * InvertMSparseSymmPos(const TMatrixDSparse *A, Int_t *rank) const
Get the inverse or pseudo-inverse of a positive, sparse matrix.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
static void DeleteMatrix(TMatrixD **m)
delete matrix and invalidate pointer
Int_t GetNdf(void) const
get number of degrees of freedom determined in recent unfolding
TUnfold(void)
Only for use by root streamer or derived classes.
virtual const Int_t * GetRowIndexArray() const
virtual Int_t ScanLcurve(Int_t nPoint, Double_t tauMin, Double_t tauMax, TGraph **lCurve, TSpline **logTauX=0, TSpline **logTauY=0, TSpline **logTauCurvature=0)
Scan the L curve, determine tau and unfold at the final value of tau.
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
Int_t fNdf
number of degrees of freedom
const Double_t * GetArray() const
Double_t GetRhoIFromMatrix(TH1 *rhoi, const TMatrixDSparse *eOrig, const Int_t *binMap, TH2 *invEmat) const
Get global correlation coefficients with arbitrary min map.
TArrayI fHistToX
mapping of histogram bins to matrix indices
Base class for spline implementation containing the Draw/Paint methods.
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
TMatrixD * fX
unfolding result x
virtual Int_t GetNbinsZ() const
no regularisation, or defined later by RegularizeXXX() methods
virtual TMatrixTBase< Element > & SetMatrixArray(const Element *data, Option_t *="")
Copy array data to matrix .
Short_t Min(Short_t a, Short_t b)
TMatrixDSparse * fDXDtauSquared
derivative of the result wrt tau squared
Int_t RegularizeBins2D(int start_bin, int step1, int nbin1, int step2, int nbin2, ERegMode regmode)
Add regularisation conditions for 2d unfolding.
TMatrixDSparse * MultiplyMSparseMSparse(const TMatrixDSparse *a, const TMatrixDSparse *b) const
Multiply two sparse matrices.
TMatrixDSparse * MultiplyMSparseM(const TMatrixDSparse *a, const TMatrixD *b) const
Multiply sparse matrix and a non-sparse matrix.
TMatrixDSparse * MultiplyMSparseMSparseTranspVector(const TMatrixDSparse *m1, const TMatrixDSparse *m2, const TMatrixTBase< Double_t > *v) const
Calculate a sparse matrix product where the diagonal matrix V is given by a vector.
TMatrixD * fX0
bias vector x0
void GetInputInverseEmatrix(TH2 *ematrix)
Get inverse of the measurement's covariance matrix.
TMatrixDSparse * CreateSparseMatrix(Int_t nrow, Int_t ncol, Int_t nele, Int_t *row, Int_t *col, Double_t *data) const
Create a sparse matrix, given the nonzero elements.
TMatrixDSparse * fDXDAZ[2]
vector contribution to the of derivative dx_k/dA_ij
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Class to create third splines to interpolate knots Arbitrary conditions can be introduced for first a...
TMatrixDSparse * fL
regularisation conditions L
Double_t GetRhoI(TH1 *rhoi, const Int_t *binMap=0, TH2 *invEmat=0) const
Get global correlation coefficients, possibly cumulated over several bins.
virtual Int_t GetDimension() const
Bool_t AddRegularisationCondition(Int_t i0, Double_t f0, Int_t i1=-1, Double_t f1=0., Int_t i2=-1, Double_t f2=0.)
Add a row of regularisation conditions to the matrix L.
ERegMode fRegMode
type of regularisation
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
truth level on x-axis of the response matrix
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t tau
TMatrixDSparse * fDXDAM[2]
matrix contribution to the of derivative dx_k/dA_ij
TArrayD fSumOverY
truth vector calculated from the non-normalized response matrix
regularise the amplitude of the output distribution
EHistMap
arrangement of axes for the response matrix (TH2 histogram)
EConstraint
type of extra constraint
Double_t Log10(Double_t x)
virtual Double_t GetLcurveY(void) const
Get value on y-axis of L-curve determined in recent unfolding.
TMatrixDSparse * MultiplyMSparseTranspMSparse(const TMatrixDSparse *a, const TMatrixDSparse *b) const
Multiply a transposed Sparse matrix with another sparse matrix,.
Int_t RegularizeCurvature(int left_bin, int center_bin, int right_bin, Double_t scale_left=1.0, Double_t scale_right=1.0)
Add a regularisation condition on the curvature of three truth bin.
TArrayI fXToHist
mapping of matrix indices to histogram bins
Double_t fChi2A
chi**2 contribution from (y-Ax)Vyy-1(y-Ax)
void Set(Int_t n)
Set size of this array to n ints.
void SetEpsMatrix(Double_t eps)
set numerical accuracy for Eigenvalue analysis when inverting matrices with rank problems ...
virtual void SetBinError(Int_t bin, Double_t error)
See convention for numbering bins in TH1::GetBin.
TMatrixTSparse< Double_t > TMatrixDSparse
ERegMode
choice of regularisation scheme
TMatrixT< Double_t > TMatrixD
TMatrixDSparse * fVxxInv
inverse of covariance matrix Vxx-1
void GetBias(TH1 *bias, const Int_t *binMap=0) const
Get bias vector including bias scale.
Double_t fRhoMax
maximum global correlation coefficient
TMatrixDSparse * fAx
result x folded back A*x
virtual Int_t SetInput(const TH1 *hist_y, Double_t scaleBias=0.0, Double_t oneOverZeroError=0.0, const TH2 *hist_vyy=0, const TH2 *hist_vyy_inv=0)
Define input data for subsequent calls to DoUnfold(tau).
TMatrixDSparse * fVyyInv
inverse of the input covariance matrix Vyy-1
virtual TString GetOutputBinName(Int_t iBinX) const
Get bin name of an output bin.
virtual Double_t DoUnfold(void)
Core unfolding algorithm.
TMatrixDSparse * fDXDY
derivative of the result wrt dx/dy
Service class for 2-Dim histogram classes.
void GetLsquared(TH2 *lsquared) const
Get matrix of regularisation conditions squared.
Double_t fBiasScale
scale factor for the bias
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
void ClearHistogram(TH1 *h, Double_t x=0.) const
Initialize bin contents and bin errors for a given histogram.
virtual Double_t GetLcurveX(void) const
Get value on x-axis of L-curve determined in recent unfolding.
void InitTUnfold(void)
Initialize data members, for use in constructors.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
static const char * GetTUnfoldVersion(void)
Return a string describing the TUnfold version.
TMatrixD * fY
input (measured) data y
regularize the 1st derivative of the output distribution
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
const TMatrixD & GetEigenVectors() const
Double_t fTauSquared
regularisation parameter tau squared
TMatrixDSparse * fVyy
covariance matrix Vyy corresponding to y
virtual const Int_t * GetColIndexArray() const
Int_t GetNx(void) const
returns internal number of output (truth) matrix rows
const TVectorD & GetEigenValues() const
Int_t GetNr(void) const
Get number of regularisation conditions.
mixed regularisation pattern
TMatrixDSparse * fEinv
matrix E^(-1)
virtual void ClearResults(void)
Reset all results.
void GetProbabilityMatrix(TH2 *A, EHistMap histmap) const
Get matrix of probabilities.
Double_t fRhoAvg
average global correlation coefficient
void SetConstraint(EConstraint constraint)
Set type of area constraint.
Double_t fLXsquared
chi**2 contribution from (x-s*x0)TLTL(x-s*x0)
void GetFoldedOutput(TH1 *folded, const Int_t *binMap=0) const
Get unfolding result on detector level.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
void GetInput(TH1 *inputData, const Int_t *binMap=0) const
Input vector of measurements.
Int_t RegularizeBins(int start, int step, int nbin, ERegMode regmode)
Add regularisation conditions for a group of bins.
you should not use this method at all Int_t Int_t z
TMatrixDSparse * fA
response matrix A
void GetCoeff(Int_t i, Double_t &x, Double_t &y, Double_t &b, Double_t &c, Double_t &d)
void GetRhoIJ(TH2 *rhoij, const Int_t *binMap=0) const
Get correlation coefficients, possibly cumulated over several bins.
Int_t fIgnoredBins
number of input bins which are dropped because they have error=0
Int_t RegularizeDerivative(int left_bin, int right_bin, Double_t scale=1.0)
Add a regularisation condition on the difference of two truth bin.
An algorithm to unfold distributions from detector to truth level.
double f2(const double *x)
#define dest(otri, vertexptr)
Short_t Max(Short_t a, Short_t b)
Double_t fEpsMatrix
machine accuracy used to determine matrix rank after eigenvalue analysis
void GetOutput(TH1 *output, const Int_t *binMap=0) const
Get output distribution, possibly cumulated over several bins.
TMatrixDSparse * fE
matrix E
A Graph is a graphics object made of two arrays X and Y with npoints each.
TMatrixDSparse * fVxx
covariance matrix Vxx
void ErrorMatrixToHist(TH2 *ematrix, const TMatrixDSparse *emat, const Int_t *binMap, Bool_t doClear) const
Add up an error matrix, also respecting the bin mapping.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Int_t GetNy(void) const
returns the number of measurement bins
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
void AddMSparse(TMatrixDSparse *dest, Double_t f, const TMatrixDSparse *src) const
Add a sparse matrix, scaled by a factor, to another scaled matrix.
Double_t GetChi2L(void) const
Get contribution determined in recent unfolding.
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content.
void GetL(TH2 *l) const
Get matrix of regularisation conditions.
virtual Int_t GetNbinsX() const
Double_t Sqrt(Double_t x)
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
regularize the 2nd derivative of the output distribution
Double_t Eval(Double_t x) const
Eval this spline at x.
Int_t RegularizeSize(int bin, Double_t scale=1.0)
Add a regularisation condition on the magnitude of a truth bin.
Int_t GetNpar(void) const
Get number of truth parameters determined in recent unfolding.
void Set(Int_t n)
Set size of this array to n doubles.
void GetEmatrix(TH2 *ematrix, const Int_t *binMap=0) const
Get output covariance matrix, possibly cumulated over several bins.
Double_t GetTau(void) const
Return regularisation parameter.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual Int_t GetNbinsY() const
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.