STK::Qr Class Reference
[Subproject STKAlgebra::Algebra]

The class Qr perform the QR decomposition of a Matrix. More...

#include <STK_Qr.h>

List of all members.

Public Member Functions

 Qr (const Matrix &A=Matrix(), const bool &ref=false)
 ~Qr ()
void clearQ ()
void clear ()
void compQr ()
void compQ ()
void NewQr (const Matrix &A)
Qroperator= (const Qr &S)
bool isCompQ () const
 < Is Q computed ?
const MatrixgetQ () const
const MatrixUpperTriangulargetR () const
QrpopBackCols (const Integer &n=1)
QreraseCol (const Integer &pos)
QrpushBackCol (const Vector &T)
QrinsertCol (const Vector &T, const Integer &pos)

Protected Attributes

Matrix Q_
 Array2D Q.
MatrixUpperTriangular R_
 Array2D R.
Integer ncolr_
 Number of cols of R actually computed.
Integer ncolq_
 Number of cols used by Q and Number of rows of R_.
Integer nrowq_
 Number of rows used by Q.
bool compq_
 is Q computed ?

Private Member Functions

void qr ()
 Private function for computing the qr.


Detailed Description

The user have to take care to the behavior of the class if withq_ is false: in this case the QR decompostion cannot be updated if he want to add a col.

Also the Addcol or insertCols methods will fail if ncolmax is not large enough.

Definition at line 71 of file STK_Qr.h.


Constructor & Destructor Documentation

STK::Qr::Qr ( const Matrix A = Matrix(),
const bool &  ref = false 
)

Default constructor.

Parameters:
A the matrix to decompose
ref true if we overwrite A

Definition at line 72 of file STK_Qr.cpp.

References compQr().

00073       : Q_(A, ref)      // Creating Q
00074       , R_()            // Creating R
00075 { compQr();}

STK::Qr::~Qr (  ) 

Dtor

Definition at line 227 of file STK_Qr.cpp.

00227 { ;}


Member Function Documentation

void STK::Qr::qr (  )  [private]

Definition at line 115 of file STK_Qr.cpp.

References beta(), STK::dot(), STK::ITContainer1D< TYPE, TContainer1D >::front(), STK::house(), STK::min(), ncolq_, ncolr_, nrowq_, Q_, R_, and STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::resize().

Referenced by compQr().

00116 {
00117   Integer niter = min(nrowq_,ncolr_);   // number of iterations
00118   R_.resize(nrowq_, ncolr_);
00119   R_ = 0.0;                   // initialize to 0.0
00120   
00121   /*------------------------------------------------------------------*/
00122   /* Main loop.                                                       */
00123   for (Integer iter=1, iter1=2; iter<=niter; iter++, iter1++)
00124   { 
00125     // A ref on the row of the matrix R_
00126     Point  Rrow0(R_, Inx(iter, ncolr_), iter);
00127     // A ref on the row of the matrix R_
00128     Point  Qrow0(Q_, Inx(iter, ncolq_), iter);
00129     // A ref on the col iter of the matrix Q_ : will contain the
00130     // Householder vector
00131     Vector u(Q_, Inx(iter, nrowq_), iter);
00132     // compute the Householder vector of the current col
00133     Rrow0[iter] = house(u);
00134     // get beta
00135     Real beta = u.front();
00136     if (beta)
00137     {
00138       // ref on the essential part of the Householder vector
00139       Vector v(u, Inx(iter1, nrowq_));
00140       // Apply Householder to next cols
00141       for (Integer j=iter1; j<=ncolr_; j++)
00142       {
00143         // Auxiliary data
00144         Real aux;
00145         // a ref on the jth column of Q_
00146         Vector Z(Q_, Inx(iter1, nrowq_), j);
00147         // save the  current row of R_
00148         Rrow0[j] = Qrow0[j] + (aux = ( Qrow0[j] + dot(v, Z)) * beta);
00149         // update the next cols of Q_ 
00150         Z += v * aux;
00151       }
00152     }
00153     else
00154     {
00155       // just copy the row iter in R_
00156       for (Integer j=iter1; j<=ncolr_; j++)
00157       {
00158         Rrow0[j] = Qrow0[j];
00159       }
00160     }
00161   }
00162 }

void STK::Qr::clearQ (  ) 

clear Q_.

Definition at line 231 of file STK_Qr.cpp.

References STK::IArray2D< TYPE, TArray2D >::clear(), compq_, nrowq_, and Q_.

00232 { Q_.clear(); nrowq_ = 0; compq_ = false;}

void STK::Qr::clear (  ) 

clear Q_ and R_.

Definition at line 236 of file STK_Qr.cpp.

References STK::IArray2D< TYPE, TArray2D >::clear(), Q_, and R_.

Referenced by NewQr().

00237 {
00238   Q_.clear();
00239   R_.clear();
00240 }

void STK::Qr::compQr (  ) 

Compute the QR decomposition.

Definition at line 90 of file STK_Qr.cpp.

References compq_, STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::empty(), ncolq_, ncolr_, nrowq_, Q_, qr(), STK::IArray2D< TYPE, TArray2D >::shift(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::sizeHo(), and STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::sizeVe().

Referenced by NewQr(), and Qr().

00091 {
00092   if (Q_.empty())     // if the container is empty
00093   {
00094     ncolr_ =0;
00095     ncolq_ =0;
00096     nrowq_ =0;
00097     compq_  = true;  // Q_ is computed
00098 
00099     return;
00100   }
00101 
00102   Q_.shift(1,1);      // translate the beg to 1
00103   ncolr_ = Q_.sizeHo(); // Number of cols of R
00104   ncolq_ = Q_.sizeHo(); // Number of col of Q
00105   nrowq_ = Q_.sizeVe(); // Number of rows of Q
00106 
00107   compq_  = false;    // Q_ is not computed
00108 
00109   // compute QR decomposition
00110   qr();
00111 }

void STK::Qr::compQ (  ) 

Compute Q (to use after compQr). Without effect compq_ == true

Definition at line 166 of file STK_Qr.cpp.

References beta(), compq_, STK::dot(), STK::min(), ncolq_, nrowq_, STK::IArray2D< TYPE, TArray2D >::popBackCols(), STK::IArray2D< TYPE, TArray2D >::pushBackCols(), and Q_.

Referenced by eraseCol(), insertCol(), and pushBackCol().

00167 {
00168   // if Q_ is computed yet
00169   if (compq_) return;
00170   // number of non zero cols of Q_  
00171   Integer ncol  = min(nrowq_, ncolq_);
00172   // Q_ is square
00173   if (nrowq_ < ncolq_)
00174   {
00175      Q_.popBackCols(ncolq_-nrowq_);
00176   }
00177   else
00178   { 
00179     Q_.pushBackCols(nrowq_-ncolq_);
00180     // initialization of the remaining cols of Q_ to 0.0
00181     Q_[Inx(ncol+1,nrowq_)] = 0.0;
00182   }
00183   // the number of col_ is equal to the number of row
00184   ncolq_ = nrowq_;
00185   // Computation of Q_.
00186   // compute added col
00187   for (Integer iter=ncolq_; iter> ncol; --iter)
00188   { Q_(iter, iter) = 1.0;}
00189   // compute other cols
00190   for (Integer iter=ncol, iter1=ncol+1; iter>=1; iter--, iter1--)
00191   {
00192     // Get beta and test
00193     Real beta = Q_(iter,iter);
00194     if (beta)
00195     {
00196       // ref of the row iter
00197       Point P(Q_, Inx(iter,ncolq_), iter);
00198       // ref of the col iter
00199       Vector X(Q_, Inx(iter1,nrowq_), iter);
00200       // Update the cols from iter+1 to ncol
00201       for (Integer j=iter1; j<=ncolq_; j++)
00202       { Real aux;
00203         Vector Y(Q_, Inx(iter1,nrowq_), j); // ref on the col j
00204         // Q_(iter, j) = beta * X'Y
00205         P[j] = (aux = dot( X, Y) * beta);
00206         // Q^j += aux * Q^iter
00207         Y += X * aux;
00208       }
00209       P[iter] = 1.0 + beta;
00210       // Q^iter *= beta
00211       X *= beta;
00212     }
00213     else // Q^iter = identity
00214     {
00215       Q_(iter, iter) = 1.0;
00216       Q_(Inx(iter1,nrowq_), iter) = 0.0;
00217     }
00218     // update the col iter
00219     Q_(Inx(1,iter-1), iter) = 0.0;
00220   }
00221   // Q_ is now computed
00222   compq_ = true;
00223 }

void STK::Qr::NewQr ( const Matrix A  ) 

Compute the QR decomposition of the Matrix A.

Parameters:
A the matrix to decompose

Definition at line 79 of file STK_Qr.cpp.

References clear(), compQr(), and Q_.

00080 {
00081   clear();  // clearing old QR
00082   Q_ = A;   // Copy A in Q
00083 
00084   // compute QR decompositionn
00085   compQr();
00086 }

Qr & STK::Qr::operator= ( const Qr S  ) 

Operator = : overwrite the Qr with S.

Definition at line 244 of file STK_Qr.cpp.

References compq_, ncolq_, ncolr_, nrowq_, Q_, and R_.

00245 {
00246   ncolr_ = S.ncolr_;       //< Number of cols of R actually computed
00247   ncolq_ = S.ncolq_;       //< Number of cols used by Q
00248   nrowq_ = S.nrowq_;       //< Number of rows used by Q
00249     
00250   compq_ = S.compq_;       //< Is Q computed ?
00251 
00252   Q_ = S.Q_;               //< Matrix V
00253   R_ = S.R_;               //< Singular values
00254 
00255   return *this;
00256 }

bool STK::Qr::isCompQ (  )  const [inline]

Definition at line 126 of file STK_Qr.h.

References compq_.

00127     { return compq_;}

const Matrix& STK::Qr::getQ (  )  const [inline]

give Q.

Definition at line 130 of file STK_Qr.h.

References Q_.

00131     { return Q_;}

const MatrixUpperTriangular& STK::Qr::getR (  )  const [inline]

give R.

Definition at line 134 of file STK_Qr.h.

References R_.

00135     { return R_;}

Qr & STK::Qr::popBackCols ( const Integer n = 1  ) 

Delete the n last cols and update the QR decomposition.

Definition at line 262 of file STK_Qr.cpp.

References ncolr_, STK::IArray2D< TYPE, TArray2D >::popBackCols(), and R_.

00263 {
00264   // delete n cols
00265   R_.popBackCols(n);
00266   ncolr_ -= n;
00267   return *this;
00268 }

Qr & STK::Qr::eraseCol ( const Integer pos  ) 

Delete the col pos and update the QR decomposition.

Definition at line 270 of file STK_Qr.cpp.

References STK::compGivens(), compQ(), compq_, STK::IArray2D< TYPE, TArray2D >::eraseCols(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::firstCol(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::getSizeHo(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::getSizeVe(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::lastCol(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::lastRow(), STK::leftGivens(), STK::min(), ncolr_, Q_, R_, STK::rightGivens(), and STK::IArray2D< TYPE, TArray2D >::update().

00271 {
00272 #ifdef STK_BOUNDS_CHECK
00273   if (pos < R_.firstCol())
00274   { throw std::out_of_range("Qr::eraseCol(pos) "
00275                        "pos < R_.firstCol()");
00276   }
00277   if (R_.lastCol() < pos)
00278   { throw std::out_of_range("Qr::eraseCol(pos) "
00279                        "R_.lastCol() < pos");
00280   }
00281 #endif
00282   // if Q_ is not computed yet
00283   if (!compq_) compQ();
00284   // compute the number of iteration for updating to zeroed
00285   Integer niter = R_.firstCol()-1+min(R_.getSizeVe(), R_.getSizeHo());
00286   // Zeroed the unwanted elements (z)
00287   for (Integer iter = pos+1; iter<=niter; iter++)
00288   {
00289     Real sinus, cosinus;
00290     // compute the Givens rotation
00291     R_(iter-1, iter) = compGivens( R_(iter-1, iter)
00292                                  , R_(iter, iter)
00293                                  , cosinus
00294                                  , sinus
00295                                  );
00296     R_(iter, iter)   = 0.0;
00297     // if necessary update R_ and Q_
00298     if (sinus)
00299     {
00300       // Update the next rows (iter1:ncolr_) of R_
00301       leftGivens(R_[Inx(iter+1, R_.lastCol())]
00302                 , iter-1
00303                 , iter
00304                 , cosinus
00305                 , sinus
00306                 );
00307       // Update the cols of Q_
00308       rightGivens(Q_, iter-1, iter, cosinus, sinus);
00309     }
00310   }
00311   // erase the col pos
00312   R_.eraseCols(pos);
00313   ncolr_--;
00314   
00315   // update the range of the remaining cols of the container
00316   R_.update(Inx(pos, min(R_.lastRow(), R_.lastCol())));
00317 
00318   return *this;
00319 }

Qr & STK::Qr::pushBackCol ( const Vector T  ) 

Add a col with value T and update th QR decomposition.

Definition at line 323 of file STK_Qr.cpp.

References STK::compGivens(), compQ(), compq_, STK::MatrixUpperTriangular::compRangeVe(), STK::dot(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::firstCol(), STK::ITContainer1D< TYPE, TContainer1D >::getRange(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::getRangeVe(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::lastCol(), ncolq_, ncolr_, STK::IArray2D< TYPE, TArray2D >::pushBackCols(), Q_, R_, and STK::rightGivens().

00324 {
00325   // check conditions
00326   if (T.getRange() != Q_.getRangeVe())
00327   { throw std::runtime_error("Qr::pushBackCol(T) "
00328                         "T.range() != Q_.getRangeVe()");
00329   }
00330   // if Q_ is not computed yet
00331   if (!compq_) compQ();
00332   // Adding a col to R
00333   R_.pushBackCols();
00334   ncolr_++;
00335   // Create an auxiliary container
00336   Vector Rncolr(Q_.getRangeVe());
00337   // Multipliate T by Q'and put the result in Rncolr
00338   for (Integer j=Q_.firstCol(); j<=Q_.lastCol(); j++)
00339     Rncolr[j] = dot(Q_[j], T);
00340   // update Q_
00341   for (Integer iter = ncolq_-1, iter1 = ncolq_; iter>=ncolr_; iter--, iter1--)
00342   { 
00343     Real sinus, cosinus, y = Rncolr[iter], z = Rncolr[iter1] ;
00344     // compute the Givens rotition
00345     Rncolr[iter]  = compGivens(y, z, cosinus, sinus);
00346     // apply Givens rotation if necessary
00347     if (sinus)
00348     {
00349       // Update the cols of Q_
00350       rightGivens(Q_, iter, iter1, cosinus, sinus);
00351     }
00352   }
00353   // update R_
00354   R_[ncolr_] = Rncolr[R_.compRangeVe(ncolr_)];
00355   //
00356   return *this;
00357 }

Qr & STK::Qr::insertCol ( const Vector T,
const Integer pos 
)

Add a col with value T at the position pos and update the QR decomposition.

Adding the jth col and update the QR decomposition.

Definition at line 361 of file STK_Qr.cpp.

References STK::compGivens(), compQ(), compq_, STK::MatrixUpperTriangular::compRangeVe(), STK::dot(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::firstCol(), STK::ITContainer1D< TYPE, TContainer1D >::getRange(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::getRangeVe(), STK::IArray2D< TYPE, TArray2D >::insertCols(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::lastCol(), STK::ITContainer2D< TYPE, TContainerHo, TContainerVe, TContainer2D >::lastRow(), STK::leftGivens(), STK::min(), ncolq_, ncolr_, Q_, R_, STK::rightGivens(), and STK::IArray2D< TYPE, TArray2D >::update().

00362 {
00363 #ifdef STK_BOUNDS_CHECK
00364   if (pos < 1)
00365   { throw std::out_of_range("Qr::insertCol(T, pos) "
00366                        "j < 1");
00367   }
00368   if (ncolr_ < pos)
00369   { throw std::out_of_range("Qr::insertCol(T, pos) "
00370                        "ncolr_ < j");
00371   }
00372 #endif
00373   if (T.getRange() != Q_.getRangeVe())
00374   { throw std::runtime_error("Qr::insertCol(T) "
00375                         "T.range() != Q_.getRangeVe()");
00376   }
00377   // if Q_ is not computed yet
00378   if (!compq_) compQ();
00379   // Adding a col to R
00380   R_.insertCols(pos);
00381   ncolr_++;
00382   // update the range of the remaining cols of R_
00383   R_.update(Inx(pos+1, min(R_.lastRow(), R_.lastCol())));
00384   for (Integer i=pos+1; i<= min(R_.lastRow(), R_.lastCol()); ++i)
00385     R_(i,i) = 0.0;
00386   // A ref on the last col of R_
00387   Vector Rpos(Q_.getRangeVe());
00388   // Multipliate T by Q'
00389   // we cannot use mult as we are using ncolq_ cols.
00390   for (Integer j=Q_.firstCol(); j<=Q_.lastCol(); j++)
00391     Rpos[j] = dot(Q_[j],T);
00392   // Zeroed the unwanted elements
00393   for (Integer iter= ncolq_-1, iter1= ncolq_; iter>=pos; iter--, iter1--)
00394   { 
00395     Real sinus, cosinus, y = Rpos[iter], z = Rpos[iter1] ;
00396     // compute the Givens rotation
00397     Rpos[iter]  = compGivens(y, z, cosinus, sinus);
00398     // apply Givens rotation if necessary
00399     if (sinus)
00400     {
00401       // Update the next rows (iter1:ncolr_) of R_
00402       leftGivens( R_[Inx(iter1, R_.lastCol())]
00403                        , iter
00404                        , iter1
00405                        , cosinus
00406                        , sinus
00407                        );
00408       // Update the cols of Q_
00409       rightGivens(Q_, iter, iter1, cosinus, sinus);
00410     }
00411   }
00412   // update R_
00413   R_[pos] = Rpos[R_.compRangeVe(pos)];
00414   R_.update(pos);
00415 
00416   //
00417   return *this;
00418 }


Member Data Documentation

Matrix STK::Qr::Q_ [protected]

Definition at line 77 of file STK_Qr.h.

Referenced by clear(), clearQ(), compQ(), compQr(), eraseCol(), getQ(), insertCol(), NewQr(), operator=(), pushBackCol(), and qr().

Definition at line 78 of file STK_Qr.h.

Referenced by clear(), eraseCol(), getR(), insertCol(), operator=(), popBackCols(), pushBackCol(), and qr().

Integer STK::Qr::ncolr_ [protected]

Definition at line 80 of file STK_Qr.h.

Referenced by compQr(), eraseCol(), insertCol(), operator=(), popBackCols(), pushBackCol(), and qr().

Integer STK::Qr::ncolq_ [protected]

Definition at line 81 of file STK_Qr.h.

Referenced by compQ(), compQr(), insertCol(), operator=(), pushBackCol(), and qr().

Integer STK::Qr::nrowq_ [protected]

Definition at line 82 of file STK_Qr.h.

Referenced by clearQ(), compQ(), compQr(), operator=(), and qr().

bool STK::Qr::compq_ [protected]

Definition at line 84 of file STK_Qr.h.

Referenced by clearQ(), compQ(), compQr(), eraseCol(), insertCol(), isCompQ(), operator=(), and pushBackCol().


The documentation for this class was generated from the following files:

Generated on Fri Sep 25 10:31:00 2009 for STK++ by  doxygen 1.5.8