48 TDecompQRH::TDecompQRH(Int_t nrows,Int_t ncols)
51 Error(
"TDecompQRH(Int_t,Int_t",
"matrix rows should be >= columns");
55 fQ.ResizeTo(nrows,ncols);
56 fR.ResizeTo(ncols,ncols);
69 TDecompQRH::TDecompQRH(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb)
71 const Int_t nrows = row_upb-row_lwb+1;
72 const Int_t ncols = col_upb-col_lwb+1;
75 Error(
"TDecompQRH(Int_t,Int_t,Int_t,Int_t",
"matrix rows should be >= columns");
82 fQ.ResizeTo(nrows,ncols);
83 fR.ResizeTo(ncols,ncols);
96 TDecompQRH::TDecompQRH(
const TMatrixD &a,Double_t tol)
98 R__ASSERT(a.IsValid());
99 if (a.GetNrows() < a.GetNcols()) {
100 Error(
"TDecompQRH(const TMatrixD &",
"matrix rows should be >= columns");
105 fCondition = a.Norm1();
110 fRowLwb = a.GetRowLwb();
111 fColLwb = a.GetColLwb();
112 const Int_t nRow = a.GetNrows();
113 const Int_t nCol = a.GetNcols();
115 fQ.ResizeTo(nRow,nCol);
116 memcpy(fQ.GetMatrixArray(),a.GetMatrixArray(),nRow*nCol*
sizeof(Double_t));
117 fR.ResizeTo(nCol,nCol);
130 TDecompQRH::TDecompQRH(
const TDecompQRH &another) : TDecompBase(another)
143 Bool_t TDecompQRH::Decompose()
145 if (TestBit(kDecomposed))
return kTRUE;
147 if ( !TestBit(kMatrixSet) ) {
148 Error(
"Decompose()",
"Matrix has not been set");
152 const Int_t nRow = this->GetNrows();
153 const Int_t nCol = this->GetNcols();
154 const Int_t rowLwb = this->GetRowLwb();
155 const Int_t colLwb = this->GetColLwb();
158 Double_t work[kWorkMax];
159 if (nCol > kWorkMax) diagR.ResizeTo(nCol);
160 else diagR.Use(nCol,work);
162 if (QRH(fQ,diagR,fUp,fW,fTol)) {
163 for (Int_t i = 0; i < nRow; i++) {
164 const Int_t ic = (i < nCol) ? i : nCol;
165 for (Int_t j = ic ; j < nCol; j++)
168 TMatrixDDiag diag(fR); diag = diagR;
182 Bool_t TDecompQRH::QRH(TMatrixD &q,TVectorD &diagR,TVectorD &up,TVectorD &w,Double_t tol)
184 const Int_t nRow = q.GetNrows();
185 const Int_t nCol = q.GetNcols();
187 const Int_t n = (nRow <= nCol) ? nRow-1 : nCol;
189 for (Int_t k = 0 ; k < n ; k++) {
190 const TVectorD qc_k = TMatrixDColumn_const(q,k);
191 if (!DefHouseHolder(qc_k,k,k+1,up(k),w(k),tol))
193 diagR(k) = qc_k(k)-up(k);
196 for (Int_t j = k+1; j < nCol; j++) {
197 TMatrixDColumn qc_j = TMatrixDColumn(q,j);
198 ApplyHouseHolder(qc_k,up(k),w(k),k,k+1,qc_j);
204 diagR(nRow-1) = q(nRow-1,nRow-1);
215 void TDecompQRH::SetMatrix(
const TMatrixD &a)
217 R__ASSERT(a.IsValid());
220 if (a.GetNrows() < a.GetNcols()) {
221 Error(
"TDecompQRH(const TMatrixD &",
"matrix rows should be >= columns");
226 fCondition = a.Norm1();
228 fRowLwb = a.GetRowLwb();
229 fColLwb = a.GetColLwb();
230 const Int_t nRow = a.GetNrows();
231 const Int_t nCol = a.GetNcols();
233 fQ.ResizeTo(nRow,nCol);
234 memcpy(fQ.GetMatrixArray(),a.GetMatrixArray(),nRow*nCol*
sizeof(Double_t));
235 fR.ResizeTo(nCol,nCol);
249 Bool_t TDecompQRH::Solve(TVectorD &b)
251 R__ASSERT(b.IsValid());
252 if (TestBit(kSingular)) {
253 Error(
"Solve()",
"Matrix is singular");
256 if ( !TestBit(kDecomposed) ) {
258 Error(
"Solve()",
"Decomposition failed");
263 if (fQ.GetNrows() != b.GetNrows() || fQ.GetRowLwb() != b.GetLwb()) {
264 Error(
"Solve(TVectorD &",
"vector and matrix incompatible");
268 const Int_t nQRow = fQ.GetNrows();
269 const Int_t nQCol = fQ.GetNcols();
272 const Int_t nQ = (nQRow <= nQCol) ? nQRow-1 : nQCol;
273 for (Int_t k = 0; k < nQ; k++) {
274 const TVectorD qc_k = TMatrixDColumn_const(fQ,k);
275 ApplyHouseHolder(qc_k,fUp(k),fW(k),k,k+1,b);
278 const Int_t nRCol = fR.GetNcols();
280 const Double_t *pR = fR.GetMatrixArray();
281 Double_t *pb = b.GetMatrixArray();
284 for (Int_t i = nRCol-1; i >= 0; i--) {
285 const Int_t off_i = i*nRCol;
287 for (Int_t j = i+1; j < nRCol; j++)
288 r -= pR[off_i+j]*pb[j];
289 if (TMath::Abs(pR[off_i+i]) < fTol)
291 Error(
"Solve(TVectorD &)",
"R[%d,%d]=%.4e < %.4e",i,i,pR[off_i+i],fTol);
294 pb[i] = r/pR[off_i+i];
304 Bool_t TDecompQRH::Solve(TMatrixDColumn &cb)
306 TMatrixDBase *b =
const_cast<TMatrixDBase *
>(cb.GetMatrix());
307 R__ASSERT(b->IsValid());
308 if (TestBit(kSingular)) {
309 Error(
"Solve()",
"Matrix is singular");
312 if ( !TestBit(kDecomposed) ) {
314 Error(
"Solve()",
"Decomposition failed");
319 if (fQ.GetNrows() != b->GetNrows() || fQ.GetRowLwb() != b->GetRowLwb())
321 Error(
"Solve(TMatrixDColumn &",
"vector and matrix incompatible");
325 const Int_t nQRow = fQ.GetNrows();
326 const Int_t nQCol = fQ.GetNcols();
329 const Int_t nQ = (nQRow <= nQCol) ? nQRow-1 : nQCol;
330 for (Int_t k = 0; k < nQ; k++) {
331 const TVectorD qc_k = TMatrixDColumn_const(fQ,k);
332 ApplyHouseHolder(qc_k,fUp(k),fW(k),k,k+1,cb);
335 const Int_t nRCol = fR.GetNcols();
337 const Double_t *pR = fR.GetMatrixArray();
338 Double_t *pcb = cb.GetPtr();
339 const Int_t inc = cb.GetInc();
342 for (Int_t i = nRCol-1; i >= 0; i--) {
343 const Int_t off_i = i*nRCol;
344 const Int_t off_i2 = i*inc;
345 Double_t r = pcb[off_i2];
346 for (Int_t j = i+1; j < nRCol; j++)
347 r -= pR[off_i+j]*pcb[j*inc];
348 if (TMath::Abs(pR[off_i+i]) < fTol)
350 Error(
"Solve(TMatrixDColumn &)",
"R[%d,%d]=%.4e < %.4e",i,i,pR[off_i+i],fTol);
353 pcb[off_i2] = r/pR[off_i+i];
363 Bool_t TDecompQRH::TransSolve(TVectorD &b)
365 R__ASSERT(b.IsValid());
366 if (TestBit(kSingular)) {
367 Error(
"TransSolve()",
"Matrix is singular");
370 if ( !TestBit(kDecomposed) ) {
372 Error(
"TransSolve()",
"Decomposition failed");
377 if (fQ.GetNrows() != fQ.GetNcols() || fQ.GetRowLwb() != fQ.GetColLwb()) {
378 Error(
"TransSolve(TVectorD &",
"matrix should be square");
382 if (fR.GetNrows() != b.GetNrows() || fR.GetRowLwb() != b.GetLwb()) {
383 Error(
"TransSolve(TVectorD &",
"vector and matrix incompatible");
387 const Double_t *pR = fR.GetMatrixArray();
388 Double_t *pb = b.GetMatrixArray();
390 const Int_t nRCol = fR.GetNcols();
393 for (Int_t i = 0; i < nRCol; i++) {
394 const Int_t off_i = i*nRCol;
396 for (Int_t j = 0; j < i; j++) {
397 const Int_t off_j = j*nRCol;
398 r -= pR[off_j+i]*pb[j];
400 if (TMath::Abs(pR[off_i+i]) < fTol)
402 Error(
"TransSolve(TVectorD &)",
"R[%d,%d]=%.4e < %.4e",i,i,pR[off_i+i],fTol);
405 pb[i] = r/pR[off_i+i];
408 const Int_t nQRow = fQ.GetNrows();
411 for (Int_t k = nQRow-1; k >= 0; k--) {
412 const TVectorD qc_k = TMatrixDColumn_const(fQ,k);
413 ApplyHouseHolder(qc_k,fUp(k),fW(k),k,k+1,b);
423 Bool_t TDecompQRH::TransSolve(TMatrixDColumn &cb)
425 TMatrixDBase *b =
const_cast<TMatrixDBase *
>(cb.GetMatrix());
426 R__ASSERT(b->IsValid());
427 if (TestBit(kSingular)) {
428 Error(
"TransSolve()",
"Matrix is singular");
431 if ( !TestBit(kDecomposed) ) {
433 Error(
"TransSolve()",
"Decomposition failed");
438 if (fQ.GetNrows() != fQ.GetNcols() || fQ.GetRowLwb() != fQ.GetColLwb()) {
439 Error(
"TransSolve(TMatrixDColumn &",
"matrix should be square");
443 if (fR.GetNrows() != b->GetNrows() || fR.GetRowLwb() != b->GetRowLwb()) {
444 Error(
"TransSolve(TMatrixDColumn &",
"vector and matrix incompatible");
448 const Double_t *pR = fR.GetMatrixArray();
449 Double_t *pcb = cb.GetPtr();
450 const Int_t inc = cb.GetInc();
452 const Int_t nRCol = fR.GetNcols();
455 for (Int_t i = 0; i < nRCol; i++) {
456 const Int_t off_i = i*nRCol;
457 const Int_t off_i2 = i*inc;
458 Double_t r = pcb[off_i2];
459 for (Int_t j = 0; j < i; j++) {
460 const Int_t off_j = j*nRCol;
461 r -= pR[off_j+i]*pcb[j*inc];
463 if (TMath::Abs(pR[off_i+i]) < fTol)
465 Error(
"TransSolve(TMatrixDColumn &)",
"R[%d,%d]=%.4e < %.4e",i,i,pR[off_i+i],fTol);
468 pcb[off_i2] = r/pR[off_i+i];
471 const Int_t nQRow = fQ.GetNrows();
474 for (Int_t k = nQRow-1; k >= 0; k--) {
475 const TVectorD qc_k = TMatrixDColumn_const(fQ,k);
476 ApplyHouseHolder(qc_k,fUp(k),fW(k),k,k+1,cb);
486 void TDecompQRH::Det(Double_t &d1,Double_t &d2)
488 if ( !TestBit(kDetermined) ) {
489 if ( !TestBit(kDecomposed) )
491 if (TestBit(kSingular)) {
495 TDecompBase::Det(d1,d2);
508 Bool_t TDecompQRH::Invert(TMatrixD &inv)
510 if (inv.GetNrows() != GetNrows() || inv.GetNcols() != GetNrows() ||
511 inv.GetRowLwb() != GetRowLwb() || inv.GetColLwb() != GetColLwb()) {
512 Error(
"Invert(TMatrixD &",
"Input matrix has wrong shape");
517 const Bool_t status = MultiSolve(inv);
526 TMatrixD TDecompQRH::Invert(Bool_t &status)
528 const Int_t rowLwb = GetRowLwb();
529 const Int_t colLwb = GetColLwb();
530 const Int_t rowUpb = rowLwb+GetNrows()-1;
531 TMatrixD inv(rowLwb,rowUpb,colLwb,colLwb+GetNrows()-1);
533 status = MultiSolve(inv);
534 inv.ResizeTo(rowLwb,rowLwb+GetNcols()-1,colLwb,colLwb+GetNrows()-1);
542 void TDecompQRH::Print(Option_t *opt)
const
544 TDecompBase::Print(opt);
554 TDecompQRH &TDecompQRH::operator=(
const TDecompQRH &source)
556 if (
this != &source) {
557 TDecompBase::operator=(source);
558 fQ.ResizeTo(source.fQ);
559 fR.ResizeTo(source.fR);
560 fUp.ResizeTo(source.fUp);
561 fW.ResizeTo(source.fW);