125 ClassImp(TDecompBase);
130 TDecompBase::TDecompBase()
132 fTol = std::numeric_limits<double>::epsilon();
143 TDecompBase::TDecompBase(
const TDecompBase &another) : TObject(another)
150 Int_t TDecompBase::Hager(Double_t &est,Int_t iter)
161 const TMatrixDBase &m = GetDecompMatrix();
165 const Int_t n = m.GetNrows();
167 TVectorD b(n); TVectorD y(n); TVectorD z(n);
169 Double_t inv_norm1 = 0.0;
170 Bool_t stop = kFALSE;
175 const Double_t ynorm1 = y.Norm1();
176 if ( ynorm1 <= inv_norm1 ) {
181 for (i = 0; i < n; i++)
182 z(i) = ( y(i) >= 0.0 ? 1.0 : -1.0 );
186 Double_t maxz = TMath::Abs(z(0));
187 for (i = 1; i < n; i++) {
188 const Double_t absz = TMath::Abs(z(i));
194 stop = (maxz <= b*z);
201 }
while (!stop && iter);
209 void TDecompBase::DiagProd(
const TVectorD &diag,Double_t tol,Double_t &d1,Double_t &d2)
216 const Double_t zero = 0.0;
217 const Double_t one = 1.0;
218 const Double_t four = 4.0;
219 const Double_t sixteen = 16.0;
220 const Double_t sixteenth = 0.0625;
222 const Int_t n = diag.GetNrows();
228 for (Int_t i = 0; (((i < n) && (t1 !=zero ))); i++) {
229 if (TMath::Abs(diag(i)) > tol) {
230 t1 *= (Double_t) diag(i);
231 while ( TMath::Abs(t1) < one) {
235 if ( niter2>100)
break;
237 while ( TMath::Abs(t1) < sixteenth) {
241 if (niter3>100)
break;
257 Double_t TDecompBase::Condition()
259 if ( !TestBit(kCondition) ) {
261 if (TestBit(kSingular))
263 if ( !TestBit(kDecomposed) ) {
269 fCondition *= invNorm;
271 Error(
"Condition()",
"Hager procedure did NOT converge");
280 Bool_t TDecompBase::MultiSolve(TMatrixD &B)
282 const TMatrixDBase &m = GetDecompMatrix();
283 R__ASSERT(m.IsValid() && B.IsValid());
285 const Int_t colLwb = B.GetColLwb();
286 const Int_t colUpb = B.GetColUpb();
287 Bool_t status = kTRUE;
288 for (Int_t icol = colLwb; icol <= colUpb && status; icol++) {
289 TMatrixDColumn b(B,icol);
299 void TDecompBase::Det(Double_t &d1,Double_t &d2)
301 if ( !TestBit(kDetermined) ) {
302 if ( !TestBit(kDecomposed) )
304 if (TestBit(kSingular) ) {
308 const TMatrixDBase &m = GetDecompMatrix();
309 R__ASSERT(m.IsValid());
310 TVectorD diagv(m.GetNrows());
311 for (Int_t i = 0; i < diagv.GetNrows(); i++)
313 DiagProd(diagv,fTol,fDet1,fDet2);
324 void TDecompBase::Print(Option_t * )
const
326 printf(
"fTol = %.4e\n",fTol);
327 printf(
"fDet1 = %.4e\n",fDet1);
328 printf(
"fDet2 = %.4e\n",fDet2);
329 printf(
"fCondition = %.4e\n",fCondition);
330 printf(
"fRowLwb = %d\n",fRowLwb);
331 printf(
"fColLwb = %d\n",fColLwb);
337 TDecompBase &TDecompBase::operator=(
const TDecompBase &source)
339 if (
this != &source) {
340 TObject::operator=(source);
342 fDet1 = source.fDet1;
343 fDet2 = source.fDet2;
344 fCondition = source.fCondition;
345 fRowLwb = source.fRowLwb;
346 fColLwb = source.fColLwb;
354 Bool_t DefHouseHolder(
const TVectorD &vc,Int_t lp,Int_t l,Double_t &up,Double_t &beta,
357 const Int_t n = vc.GetNrows();
358 const Double_t *
const vp = vc.GetMatrixArray();
360 Double_t c = TMath::Abs(vp[lp]);
362 for (i = l; i < n; i++)
363 c = TMath::Max(TMath::Abs(vp[i]),c);
372 Double_t sd = vp[lp]/c; sd *= sd;
373 for (i = l; i < n; i++) {
374 const Double_t tmp = vp[i]/c;
378 Double_t vpprim = c*TMath::Sqrt(sd);
379 if (vp[lp] > 0.) vpprim = -vpprim;
381 beta = 1./(vpprim*up);
389 void ApplyHouseHolder(
const TVectorD &vc,Double_t up,Double_t beta,
390 Int_t lp,Int_t l,TMatrixDRow &cr)
392 const Int_t nv = vc.GetNrows();
393 const Int_t nc = (cr.GetMatrix())->GetNcols();
396 Error(
"ApplyHouseHolder(const TVectorD &,..,TMatrixDRow &)",
"matrix row too short");
400 const Int_t inc_c = cr.GetInc();
401 const Double_t *
const vp = vc.GetMatrixArray();
402 Double_t * cp = cr.GetPtr();
404 Double_t s = cp[lp*inc_c]*up;
406 for (i = l; i < nv; i++)
407 s += cp[i*inc_c]*vp[i];
410 cp[lp*inc_c] += s*up;
411 for (i = l; i < nv; i++)
412 cp[i*inc_c] += s*vp[i];
418 void ApplyHouseHolder(
const TVectorD &vc,Double_t up,Double_t beta,
419 Int_t lp,Int_t l,TMatrixDColumn &cc)
421 const Int_t nv = vc.GetNrows();
422 const Int_t nc = (cc.GetMatrix())->GetNrows();
425 Error(
"ApplyHouseHolder(const TVectorD &,..,TMatrixDRow &)",
"matrix column too short");
429 const Int_t inc_c = cc.GetInc();
430 const Double_t *
const vp = vc.GetMatrixArray();
431 Double_t * cp = cc.GetPtr();
433 Double_t s = cp[lp*inc_c]*up;
435 for (i = l; i < nv; i++)
436 s += cp[i*inc_c]*vp[i];
439 cp[lp*inc_c] += s*up;
440 for (i = l; i < nv; i++)
441 cp[i*inc_c] += s*vp[i];
447 void ApplyHouseHolder(
const TVectorD &vc,Double_t up,Double_t beta,
448 Int_t lp,Int_t l,TVectorD &cv)
450 const Int_t nv = vc.GetNrows();
451 const Int_t nc = cv.GetNrows();
454 Error(
"ApplyHouseHolder(const TVectorD &,..,TVectorD &)",
"vector too short");
458 const Double_t *
const vp = vc.GetMatrixArray();
459 Double_t * cp = cv.GetMatrixArray();
461 Double_t s = cp[lp]*up;
463 for (i = l; i < nv; i++)
468 for (i = l; i < nv; i++)
476 void DefGivens(Double_t v1,Double_t v2,Double_t &c,Double_t &s)
478 const Double_t a1 = TMath::Abs(v1);
479 const Double_t a2 = TMath::Abs(v2);
481 const Double_t w = v2/v1;
482 const Double_t q = TMath::Hypot(1.,w);
488 const Double_t w = v1/v2;
489 const Double_t q = TMath::Hypot(1.,w);
505 void DefAplGivens(Double_t &v1,Double_t &v2,Double_t &c,Double_t &s)
507 const Double_t a1 = TMath::Abs(v1);
508 const Double_t a2 = TMath::Abs(v2);
510 const Double_t w = v2/v1;
511 const Double_t q = TMath::Hypot(1.,w);
519 const Double_t w = v1/v2;
520 const Double_t q = TMath::Hypot(1.,w);
537 void ApplyGivens(Double_t &z1,Double_t &z2,Double_t c,Double_t s)
539 const Double_t w = z1*c+z2*s;