11 Matrix<double,10,10>
temp = mat;
12 outvec.head<10>() = temp.ldlt().solve(invec.head<10>());
17 Matrix<double,9,9>
temp = mat.topLeftCorner<9,9>();
18 outvec.head<9>() = temp.ldlt().solve(invec.head<9>());
23 Matrix<double,8,8>
temp = mat.topLeftCorner<8,8>();
24 outvec.head<8>() = temp.ldlt().solve(invec.head<8>());
29 Matrix<double,7,7>
temp = mat.topLeftCorner<7,7>();
30 outvec.head<7>() = temp.ldlt().solve(invec.head<7>());
35 Matrix<double,6,6>
temp = mat.topLeftCorner<6,6>();
36 outvec.head<6>() = temp.ldlt().solve(invec.head<6>());
41 Matrix<double,5,5>
temp = mat.topLeftCorner<5,5>();
42 outvec.head<5>() = temp.ldlt().solve(invec.head<5>());
47 Matrix<double,4,4>
temp = mat.topLeftCorner<4,4>();
48 outvec.head<4>() = temp.ldlt().solve(invec.head<4>());
53 Matrix<double,3,3>
temp = mat.topLeftCorner<3,3>();
54 outvec.head<3>() = temp.ldlt().solve(invec.head<3>());
59 Matrix<double,2,2>
temp = mat.topLeftCorner<2,2>();
60 outvec.head<2>() = temp.ldlt().solve(invec.head<2>());
65 Matrix<double,1,1>
temp = mat.topLeftCorner<1,1>();
66 outvec.head<1>() = temp.ldlt().solve(invec.head<1>());
71 <<
"Weird number of pulses encountered in multifit, module is configured incorrectly!";
79 _maxiterwarnings(
true)
82 Eigen::initParallel();
106 if (
_bxs.rows()==1) {
114 for (
unsigned int ipulse=0; ipulse<
_npulsetot; ++ipulse) {
115 int bx =
_bxs.coeff(ipulse);
122 _pulsemat.col(ipulse) = fullpulse.segment<SampleVector::RowsAtCompileTime>(
offset);
130 if (!status)
return status;
135 bool foundintime =
false;
136 unsigned int ipulseintime = 0;
137 for (
unsigned int ipulse=0; ipulse<
_npulsetot; ++ipulse) {
138 if (
_bxs.coeff(ipulse)==0) {
139 ipulseintime = ipulse;
144 if (!foundintime)
return status;
146 const unsigned int ipulseintimemin = ipulseintime;
153 if (ipulseintime<
_nP) {
157 ipulseintime =
_nP - 1;
166 double xplus100 = x0 + approxerr;
167 _ampvec.coeffRef(ipulseintime) = xplus100;
169 status &=
Minimize(samplecor,pederr,fullpulsecov);
170 if (!status)
return status;
173 double sigmaplus =
std::abs(xplus100-x0)/
sqrt(chisqplus100-chisq0);
176 if ( (x0/sigmaplus) > 0.5 ) {
177 for (
unsigned int ipulse=0; ipulse<
_npulsetot; ++ipulse) {
178 if (
_bxs.coeff(ipulse)==0) {
179 ipulseintime = ipulse;
183 double xminus100 =
std::max(0.,x0-approxerr);
184 _ampvec.coeffRef(ipulseintime) = xminus100;
186 status &=
Minimize(samplecor,pederr,fullpulsecov);
187 if (!status)
return status;
190 double sigmaminus =
std::abs(xminus100-x0)/
sqrt(chisqminus100-chisq0);
191 _errvec[ipulseintimemin] = 0.5*(sigmaplus + sigmaminus);
195 _errvec[ipulseintimemin] = sigmaplus;
206 const unsigned int npulse =
_bxs.rows();
214 edm::LogWarning(
"PulseChiSqSNNLS::Minimize") <<
"Max Iterations reached at iter " << iter << std::endl;
219 status =
updateCov(samplecor,pederr,fullpulsecov);
231 double deltachisq = chisqnow-
_chisq;
246 const unsigned int nsample = SampleVector::RowsAtCompileTime;
247 const unsigned int npulse =
_bxs.rows();
249 const double pederr2 = pederr*pederr;
252 for (
unsigned int ipulse=0; ipulse<npulse; ++ipulse) {
253 if (
_ampvec.coeff(ipulse)==0.)
continue;
254 int bx =
_bxs.coeff(ipulse);
255 int firstsamplet =
std::max(0,bx + 3);
258 const double ampveccoef =
_ampvec.coeff(ipulse);
259 const double ampsq = ampveccoef*ampveccoef;
261 const unsigned int nsamplepulse = nsample-firstsamplet;
262 _invcov.block(firstsamplet,firstsamplet,nsamplepulse,nsamplepulse) +=
263 ampsq*fullpulsecov.block(firstsamplet+offset,firstsamplet+offset,nsamplepulse,nsamplepulse);
295 const unsigned int npulse =
_bxs.rows();
309 if (iter>0 ||
_nP==0) {
310 if (
_nP==npulse )
break;
312 const unsigned int nActive = npulse -
_nP;
315 Index idxwmaxprev = idxwmax;
316 double wmaxprev = wmax;
317 wmax =
updatework.tail(nActive).maxCoeff(&idxwmax);
320 if (wmax<threshold || (idxwmax==idxwmaxprev && wmax==wmaxprev))
break;
324 edm::LogWarning(
"PulseChiSqSNNLS::NNLS()") <<
"Max Iterations reached at iter " << iter << std::endl;
329 Index idxp = _nP + idxwmax;
335 std::swap(_ampvec.coeffRef(_nP),_ampvec.coeffRef(idxp));
358 if ( ampvecpermhead.minCoeff()>0. ) {
368 for (
unsigned int ipulse=0; ipulse<
_nP; ++ipulse) {
370 const double c_ampvec =
_ampvec.coeff(ipulse);
371 const double ratio = c_ampvec/(c_ampvec-
ampvecpermtest.coeff(ipulse));
372 if (ratio<minratio) {
374 minratioidx = ipulse;
379 _ampvec.head(_nP) += minratio*(ampvecpermhead -
_ampvec.head(_nP));
382 _ampvec.coeffRef(minratioidx) = 0.;
419 _ampvec.coeffRef(0) =
std::max(0.,aTbvecval.coeff(0)/aTamatval.coeff(0));
Eigen::Matrix< double, 10, 1 > SampleVector
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 10, 1 > PulseVector
PulseVector ampvecpermtest
Eigen::Matrix< double, 19, 19 > FullSampleMatrix
SamplePulseMatrix _pulsemat
bool updateCov(const SampleMatrix &samplecor, double pederr, const FullSampleMatrix &fullpulsecov)
double ComputeApproxUncertainty(unsigned int ipulse)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
Eigen::Matrix< double, 1, 1 > SingleVector
SampleDecompLLT _covdecomp
Abs< T >::type abs(const T &t)
Eigen::Matrix< double, 19, 1 > FullSampleVector
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 10, 10 > PulseMatrix
bool Minimize(const SampleMatrix &samplecor, double pederr, const FullSampleMatrix &fullpulsecov)
void eigen_solve_submatrix(PulseMatrix &mat, PulseVector &invec, PulseVector &outvec, unsigned NP)
Eigen::Matrix< double, 10, 10 > SampleMatrix
Eigen::Matrix< double, 1, 1 > SingleMatrix
SamplePulseMatrix invcovp
bool DoFit(const SampleVector &samples, const SampleMatrix &samplecor, double pederr, const BXVector &bxs, const FullSampleVector &fullpulse, const FullSampleMatrix &fullpulsecov)