computation/interfaces/Lapack_LeastSquares.cxx

00001 // Copyright (C) 2003-2009 Marc Duruflé
00002 // Copyright (C) 2001-2009 Vivien Mallet
00003 //
00004 // This file is part of the linear-algebra library Seldon,
00005 // http://seldon.sourceforge.net/.
00006 //
00007 // Seldon is free software; you can redistribute it and/or modify it under the
00008 // terms of the GNU Lesser General Public License as published by the Free
00009 // Software Foundation; either version 2.1 of the License, or (at your option)
00010 // any later version.
00011 //
00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00015 // more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public License
00018 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00019 
00020 
00021 #ifndef SELDON_FILE_LAPACK_LEAST_SQUARES_CXX
00022 
00023 
00024 #include "Lapack_LeastSquares.hxx"
00025 
00026 
00027 namespace Seldon
00028 {
00029 
00030 
00032   // GETQR //
00033 
00034 
00035   /*** ColMajor ***/
00036 
00037 
00038   template<class Prop0, class Allocator0,
00039            class Allocator1>
00040   void GetQR(Matrix<float, Prop0, ColMajor, Allocator0>& A,
00041              Vector<float, VectFull, Allocator1>& tau,
00042              LapackInfo& info)
00043   {
00044     int m = A.GetM();
00045     int n = A.GetN();
00046     int lwork = max(m,n);
00047     Vector<float, VectFull, Allocator1> work(lwork);
00048     tau.Reallocate(min(m, n));
00049     sgeqrf_(&m, &n, A.GetData(), &m, tau.GetData(),
00050             work.GetData(), &lwork, &info.GetInfoRef());
00051   }
00052 
00053 
00054   template<class Prop0, class Allocator0,
00055            class Allocator1>
00056   void GetQR(Matrix<double, Prop0, ColMajor, Allocator0>& A,
00057              Vector<double, VectFull, Allocator1>& tau,
00058              LapackInfo& info)
00059   {
00060     int m = A.GetM();
00061     int n = A.GetN();
00062     int lwork = max(m,n);
00063     Vector<double, VectFull, Allocator1> work(lwork);
00064     tau.Reallocate(min(m, n));
00065     dgeqrf_(&m, &n, A.GetData(), &m, tau.GetData(),
00066             work.GetData(), &lwork, &info.GetInfoRef());
00067   }
00068 
00069 
00070   template<class Prop0, class Allocator0,
00071            class Allocator1>
00072   void GetQR(Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
00073              Vector<complex<double>, VectFull, Allocator1>& tau,
00074              LapackInfo& info)
00075   {
00076     int m = A.GetM();
00077     int n = A.GetN();
00078     int lwork = max(m,n);
00079     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00080     tau.Reallocate(min(m, n));
00081     zgeqrf_(&m, &n, A.GetData(), &m, tau.GetData(),
00082             work.GetData(), &lwork, &info.GetInfoRef());
00083   }
00084 
00085 
00086   /*** RowMajor ***/
00087 
00088 
00089   template<class Prop0, class Allocator0,
00090            class Allocator1>
00091   void GetQR(Matrix<float, Prop0, RowMajor, Allocator0>& A,
00092              Vector<float, VectFull, Allocator1>& tau,
00093              LapackInfo& info)
00094   {
00095     int m = A.GetM();
00096     int n = A.GetN();
00097     int lwork = max(m,n);
00098     Vector<float, VectFull, Allocator1> work(lwork);
00099     tau.Reallocate(min(m, n));
00100     // Factorization LQ of A^t.
00101     sgelqf_(&n, &m, A.GetData(), &n, tau.GetData(),
00102             work.GetData(), &lwork, &info.GetInfoRef());
00103   }
00104 
00105 
00106   template<class Prop0, class Allocator0,
00107            class Allocator1>
00108   void GetQR(Matrix<double, Prop0, RowMajor, Allocator0>& A,
00109              Vector<double, VectFull, Allocator1>& tau,
00110              LapackInfo& info)
00111   {
00112     int m = A.GetM();
00113     int n = A.GetN();
00114     int lwork = max(m,n);
00115     Vector<double, VectFull, Allocator1> work(lwork);
00116     tau.Reallocate(min(m, n));
00117     // Factorization LQ of A^t.
00118     dgelqf_(&n, &m, A.GetData(), &n, tau.GetData(),
00119             work.GetData(), &lwork, &info.GetInfoRef());
00120   }
00121 
00122 
00123   template<class Prop0, class Allocator0,
00124            class Allocator1>
00125   void GetQR(Matrix<complex<double>, Prop0, RowMajor, Allocator0>& A,
00126              Vector<complex<double>, VectFull, Allocator1>& tau,
00127              LapackInfo& info)
00128   {
00129     int m = A.GetM();
00130     int n = A.GetN();
00131     int lwork = max(m,n);
00132     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00133     tau.Reallocate(min(m, n));
00134     // Factorization LQ of A^t.
00135     zgelqf_(&n, &m, A.GetData(), &n, tau.GetData(),
00136             work.GetData(), &lwork, &info.GetInfoRef());
00137   }
00138 
00139 
00140   // GETQR //
00142 
00143 
00145   // GETQR_PIVOT //
00146 
00147 
00148   /*** ColMajor ***/
00149 
00150 
00151   template<class Prop0, class Allocator0,
00152            class Allocator1>
00153   void GetQR_Pivot(Matrix<double, Prop0, ColMajor, Allocator0>& A,
00154                    Vector<double, VectFull, Allocator1>& tau,
00155                    Vector<int>& ipivot, LapackInfo& info)
00156   {
00157     int m = A.GetM();
00158     int n = A.GetN();
00159     int lwork = 4 * max(m, n);
00160     ipivot.Fill(0);
00161     Vector<double, VectFull, Allocator1> work(lwork);
00162     tau.Reallocate(min(m, n));
00163     dgeqp3_(&m, &n, A.GetData(), &m, ipivot.GetData(), tau.GetData(),
00164             work.GetData(), &lwork, &info.GetInfoRef());
00165   }
00166 
00167 
00168   // GETQR_PIVOT //
00170 
00171 
00173   // GETQ_FROMQR //
00174 
00175 
00176   /*** ColMajor ***/
00177 
00178   template<class Prop0, class Allocator0,
00179            class Allocator1>
00180   void GetQ_FromQR(Matrix<double, Prop0, ColMajor, Allocator0>& A,
00181                    Vector<double, VectFull, Allocator1>& tau,
00182                    LapackInfo& info)
00183   {
00184     int m = A.GetM();
00185     int n = A.GetN();
00186     int lwork = 2 * max(m, n);
00187     Vector<double, VectFull, Allocator1> work(lwork);
00188     dorgqr_(&m, &m, &n, A.GetData(), &m, tau.GetData(),
00189             work.GetData(), &lwork, &info.GetInfoRef());
00190   }
00191 
00192 
00193   template<class Prop0, class Allocator0,
00194            class Allocator1>
00195   void GetQ_FromQR(Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
00196                    Vector<complex<double>, VectFull, Allocator1>& tau,
00197                    LapackInfo& info)
00198   {
00199     int m = A.GetM();
00200     int n = A.GetN();
00201     int lwork = 2 * max(m, n);
00202     Vector<double, VectFull, Allocator1> work(lwork);
00203     zungqr_(&m, &m, &n, A.GetDataVoid(), &m, tau.GetData(),
00204             work.GetData(), &lwork, &info.GetInfoRef());
00205   }
00206 
00207 
00208   template<class Prop0, class Allocator0,
00209            class Allocator1, class Allocator2, class Side, class Trans>
00210   void MltQ_FromQR(const Side& side, const Trans& trans,
00211                    Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
00212                    Vector<complex<double>, VectFull, Allocator1>& tau,
00213                    Matrix<complex<double>, Prop0, ColMajor, Allocator2>& C,
00214                    LapackInfo& info)
00215   {
00216     int m = A.GetM();
00217     int n = A.GetN();
00218     int lwork = max(m, n);
00219     Vector<double, VectFull, Allocator1> work(lwork);
00220     char side_ = side.Char();
00221     char trans_ = trans.Char();
00222     int k = m;
00223     if (side_ == 'R')
00224       k = n;
00225 
00226     zunmqr_(&side, &trans, &m, &n, &k, A.GetDataVoid(), &m, tau.GetDataVoid(),
00227             C.GetDataVoid(), &m, work.GetData(), &lwork,
00228             &info.GetInfoRef());
00229   }
00230 
00231 
00232   // GETQ_FROMQR //
00234 
00235 
00237   // GETLQ //
00238 
00239 
00240   /*** ColMajor ***/
00241 
00242 
00243   template<class Prop0, class Allocator0,
00244            class Allocator1>
00245   void GetLQ(Matrix<float, Prop0, ColMajor, Allocator0>& A,
00246              Vector<float, VectFull, Allocator1>& tau,
00247              LapackInfo& info)
00248   {
00249     int m = A.GetM();
00250     int n = A.GetN();
00251     int lwork = max(m,n);
00252     Vector<float, VectFull, Allocator1> work(lwork);
00253     tau.Reallocate(min(m, n));
00254     sgelqf_(&m, &n, A.GetData(), &m, tau.GetData(),
00255             work.GetData(), &lwork, &info.GetInfoRef());
00256   }
00257 
00258 
00259   template<class Prop0, class Allocator0,
00260            class Allocator1>
00261   void GetLQ(Matrix<double, Prop0, ColMajor, Allocator0>& A,
00262              Vector<double, VectFull, Allocator1>& tau,
00263              LapackInfo& info)
00264   {
00265     int m = A.GetM();
00266     int n = A.GetN();
00267     int lwork = max(m,n);
00268     Vector<double, VectFull, Allocator1> work(lwork);
00269     tau.Reallocate(min(m, n));
00270     dgelqf_(&m, &n, A.GetData(), &m, tau.GetData(),
00271             work.GetData(), &lwork, &info.GetInfoRef());
00272   }
00273 
00274 
00275   template<class Prop0, class Allocator0,
00276            class Allocator1>
00277   void GetLQ(Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
00278              Vector<complex<double>, VectFull, Allocator1>& tau,
00279              LapackInfo& info)
00280   {
00281     int m = A.GetM();
00282     int n = A.GetN();
00283     int lwork = max(m,n);
00284     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00285     tau.Reallocate(min(m, n));
00286     zgelqf_(&m, &n, A.GetData(), &m, tau.GetData(),
00287             work.GetData(), &lwork, &info.GetInfoRef());
00288   }
00289 
00290 
00291   /*** RowMajor ***/
00292 
00293 
00294   template<class Prop0, class Allocator0,
00295            class Allocator1>
00296   void GetLQ(Matrix<float, Prop0, RowMajor, Allocator0>& A,
00297              Vector<float, VectFull, Allocator1>& tau,
00298              LapackInfo& info)
00299   {
00300     int m = A.GetM();
00301     int n = A.GetN();
00302     int lwork = max(m,n);
00303     Vector<float, VectFull, Allocator1> work(lwork);
00304     tau.Reallocate(min(m, n));
00305     // Factorization QR of A^t.
00306     sgeqrf_(&n, &m, A.GetData(), &n, tau.GetData(),
00307             work.GetData(), &lwork, &info.GetInfoRef());
00308   }
00309 
00310 
00311   template<class Prop0, class Allocator0,
00312            class Allocator1>
00313   void GetLQ(Matrix<double, Prop0, RowMajor, Allocator0>& A,
00314              Vector<double, VectFull, Allocator1>& tau,
00315              LapackInfo& info)
00316   {
00317     int m = A.GetM();
00318     int n = A.GetN();
00319     int lwork = max(m,n);
00320     Vector<double, VectFull, Allocator1> work(lwork);
00321     tau.Reallocate(min(m, n));
00322     // Factorization LQ of A^t.
00323     dgeqrf_(&n, &m, A.GetData(), &n, tau.GetData(),
00324             work.GetData(), &lwork, &info.GetInfoRef());
00325   }
00326 
00327 
00328   template<class Prop0, class Allocator0,
00329            class Allocator1>
00330   void GetLQ(Matrix<complex<double>, Prop0, RowMajor, Allocator0>& A,
00331              Vector<complex<double>, VectFull, Allocator1>& tau,
00332              LapackInfo& info)
00333   {
00334     int m = A.GetM();
00335     int n = A.GetN();
00336     int lwork = max(m,n);
00337     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00338     tau.Reallocate(min(m, n));
00339     // Factorization LQ of A^t.
00340     zgeqrf_(&n, &m, A.GetData(), &n, tau.GetData(),
00341             work.GetData(), &lwork, &info.GetInfoRef());
00342   }
00343 
00344 
00345   // GETLQ //
00347 
00348 
00350   // MLTQ_FROMQR //
00351 
00352 
00353   /*** ColMajor ***/
00354 
00355 
00356   template<class Prop0, class Allocator0,
00357            class Allocator1, class Allocator2, class IsTranspose>
00358   void MltQ_FromQR(Matrix<double, Prop0, ColMajor, Allocator0>& A,
00359                    const IsTranspose& trans,
00360                    Vector<double, VectFull, Allocator1>& tau,
00361                    Vector<double, VectFull, Allocator2>& b,
00362                    LapackInfo& info)
00363   {
00364     int m = b.GetM();
00365     int n = 1;
00366     int k = tau.GetM();
00367     int lwork = max(m,n);
00368     Vector<double, VectFull, Allocator1> work(lwork);
00369     char side('L');
00370     char trans_(trans);
00371     dormqr_(&side, &trans_, &m, &n, &k, A.GetData(), &m, tau.GetData(),
00372             b.GetData(), &m, work.GetData(), &lwork,
00373             &info.GetInfoRef());
00374   }
00375 
00376 
00377   // MLTQ_FROMQR //
00379 
00380 
00382   // SOLVEQR //
00383 
00384 
00385   /*** ColMajor ***/
00386 
00387 
00388   template <class Prop0, class Allocator0,
00389             class Allocator1,class Allocator2>
00390   void SolveQR(const Matrix<float, Prop0, ColMajor, Allocator0>& A,
00391                const Vector<float, VectFull, Allocator1>& tau,
00392                Vector<float, VectFull, Allocator2>& b,
00393                LapackInfo& info)
00394   {
00395     int m = A.GetM();
00396     int n = A.GetN();
00397     int k = tau.GetM();
00398     int nrhs = 1, nb = b.GetM();
00399     char side('L');
00400     char trans('T');
00401     int lwork = max(m, n);
00402     Vector<float, VectFull, Allocator1> work(lwork);
00403     // Computes Q^t b.
00404     sormqr_(&side, &trans, &m, &nrhs, &k, A.GetData(),
00405             &m, tau.GetData(), b.GetData(),
00406             &m, work.GetData(), &lwork, &info.GetInfoRef());
00407 
00408     b.Resize(n);
00409     for (int i = nb; i < n; i++)
00410       b(i) = 0;
00411 
00412     // Then solves R x = Q^t b.
00413     float alpha(1);
00414     cblas_strsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans,
00415                 CblasNonUnit, b.GetM(), nrhs,
00416                 alpha, A.GetData(), A.GetM(), b.GetData(), b.GetM());
00417   }
00418 
00419 
00420   template <class Prop0, class Allocator0,
00421             class Allocator1,class Allocator2>
00422   void SolveQR(const Matrix<double, Prop0, ColMajor, Allocator0>& A,
00423                const Vector<double, VectFull, Allocator1>& tau,
00424                Vector<double, VectFull, Allocator2>& b,
00425                LapackInfo& info)
00426   {
00427     int m = A.GetM();
00428     int n = A.GetN();
00429     int k = tau.GetM();
00430     int nrhs = 1, nb = b.GetM();
00431     char side('L');
00432     char trans('T');
00433     int lwork = max(m, n);
00434     Vector<double, VectFull, Allocator1> work(lwork);
00435     // Computes Q^t b.
00436     dormqr_(&side, &trans, &lwork, &nrhs, &k, A.GetData(),
00437             &m, tau.GetData(), b.GetData(),
00438             &lwork, work.GetData(), &lwork, &info.GetInfoRef());
00439 
00440     b.Resize(n);
00441     for (int i = nb; i < n; i++)
00442       b(i) = 0;
00443 
00444     // Then solves R x = Q^t b.
00445     double alpha(1);
00446     cblas_dtrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans,
00447                 CblasNonUnit, b.GetM(), nrhs,
00448                 alpha, A.GetData(), A.GetM(), b.GetData(), b.GetM());
00449   }
00450 
00451 
00452   template <class Prop0, class Allocator0,
00453             class Allocator1,class Allocator2>
00454   void SolveQR(const Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
00455                const Vector<complex<double>, VectFull, Allocator1>& tau,
00456                Vector<complex<double>, VectFull, Allocator2>& b,
00457                LapackInfo& info)
00458   {
00459     int m = A.GetM();
00460     int n = A.GetN();
00461     int k = tau.GetM();
00462     int nrhs = 1, nb = b.GetM();
00463     char side('L');
00464     char trans('C');
00465     int lwork = max(m, n);
00466     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00467     // Computes Q^t b.
00468     zunmqr_(&side, &trans, &m, &nrhs, &k, A.GetData(),
00469             &m, tau.GetData(), b.GetData(),
00470             &m, work.GetData(), &lwork, &info.GetInfoRef());
00471 
00472     b.Resize(n);
00473     for (int i = nb; i < n; i++)
00474       b(i) = 0;
00475 
00476     // Then solves R x = Q^t b.
00477     complex<double> alpha(1);
00478     cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans,
00479                 CblasNonUnit, b.GetM(), nrhs,
00480                 &alpha, A.GetData(), A.GetM(), b.GetData(), b.GetM());
00481   }
00482 
00483 
00484   /*** RowMajor ***/
00485 
00486 
00487   template <class Prop0, class Allocator0,
00488             class Allocator1,class Allocator2>
00489   void SolveQR(const Matrix<float, Prop0, RowMajor, Allocator0>& A,
00490                const Vector<float, VectFull, Allocator1>& tau,
00491                Vector<float, VectFull, Allocator2>& b,
00492                LapackInfo& info)
00493   {
00494     int m = A.GetM();
00495     int n = A.GetN();
00496     int k = tau.GetM();
00497     int nrhs = 1, nb = b.GetM();
00498     char side('L');
00499     char trans('N');
00500     int lwork = max(m, n);
00501     Vector<float, VectFull, Allocator1> work(lwork);
00502     // Computes Q b.
00503     sormlq_(&side, &trans, &m, &nrhs, &k, A.GetData(),
00504             &n, tau.GetData(), b.GetData(),
00505             &m, work.GetData(), &lwork, &info.GetInfoRef());
00506 
00507     b.Resize(n);
00508     for (int i = nb; i < n; i++)
00509       b(i) = 0;
00510 
00511     // Solves L^t y = b.
00512     float alpha(1);
00513     cblas_strsm(CblasColMajor, CblasLeft, CblasLower, CblasTrans,
00514                 CblasNonUnit, n, nrhs,
00515                 alpha, A.GetData(), n, b.GetData(), b.GetM());
00516   }
00517 
00518 
00519   template <class Prop0, class Allocator0,
00520             class Allocator1,class Allocator2>
00521   void SolveQR(const Matrix<double, Prop0, RowMajor, Allocator0>& A,
00522                const Vector<double, VectFull, Allocator1>& tau,
00523                Vector<double, VectFull, Allocator2>& b,
00524                LapackInfo& info)
00525   {
00526     int m = A.GetM();
00527     int n = A.GetN();
00528     int k = tau.GetM();
00529     int nrhs = 1, nb = b.GetM();
00530     char side('L');
00531     char trans('N');
00532     int lwork = max(m, n);
00533     Vector<double, VectFull, Allocator1> work(lwork);
00534     // Computes Q b.
00535     dormlq_(&side, &trans, &m, &nrhs, &k, A.GetData(),
00536             &n, tau.GetData(), b.GetData(),
00537             &m, work.GetData(), &lwork, &info.GetInfoRef());
00538 
00539     b.Resize(n);
00540     for (int i = nb; i < n; i++)
00541       b(i) = 0;
00542 
00543     // Solves L^t y = b.
00544     double alpha(1);
00545     cblas_dtrsm(CblasColMajor, CblasLeft, CblasLower, CblasTrans,
00546                 CblasNonUnit, n, nrhs,
00547                 alpha, A.GetData(), n, b.GetData(), b.GetM());
00548   }
00549 
00550 
00551   template <class Prop0, class Allocator0,
00552             class Allocator1,class Allocator2>
00553   void SolveQR(const Matrix<complex<double>, Prop0, RowMajor, Allocator0>& A,
00554                const Vector<complex<double>, VectFull, Allocator1>& tau,
00555                Vector<complex<double>, VectFull, Allocator2>& b,
00556                LapackInfo& info)
00557   {
00558     int m = A.GetM();
00559     int n = A.GetN();
00560     int k = tau.GetM();
00561     int nrhs = 1, nb = b.GetM();
00562     char side('L');
00563     char trans('N');
00564     int lwork = max(m, n);
00565     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00566     // Computes Q b.
00567     zunmlq_(&side, &trans, &m, &nrhs, &k, A.GetData(),
00568             &n, tau.GetData(), b.GetData(),
00569             &m, work.GetData(), &lwork, &info.GetInfoRef());
00570 
00571     b.Resize(n);
00572     for (int i = nb; i < n; i++)
00573       b(i) = 0;
00574 
00575     // Solves L^t y = b.
00576     complex<double> alpha(1);
00577     cblas_ztrsm(CblasColMajor, CblasLeft, CblasLower, CblasTrans,
00578                 CblasNonUnit, n, nrhs,
00579                 &alpha, A.GetData(), n, b.GetData(), b.GetM());
00580   }
00581 
00582 
00583   // SOLVEQR //
00585 
00586 
00588   // SOLVELQ //
00589 
00590 
00591   /*** ColMajor ***/
00592 
00593 
00594   template <class Prop0, class Allocator0,
00595             class Allocator1,class Allocator2>
00596   void SolveLQ(const Matrix<float, Prop0, ColMajor, Allocator0>& A,
00597                const Vector<float, VectFull, Allocator1>& tau,
00598                Vector<float, VectFull, Allocator2>& b,
00599                LapackInfo& info)
00600   {
00601     int m = A.GetM();
00602     int n = A.GetN();
00603     int k = tau.GetM();
00604     int nrhs = 1, nb = b.GetM();
00605     char side('L');
00606     char trans('T');
00607     int lwork = max(m, n);
00608     Vector<float, VectFull, Allocator1> work(lwork);
00609     // Solves L y = b.
00610     float alpha(1);
00611     cblas_strsm(CblasColMajor, CblasLeft, CblasLower, CblasNoTrans,
00612                 CblasNonUnit, m, nrhs,
00613                 alpha, A.GetData(), m, b.GetData(), b.GetM());
00614 
00615     b.Resize(n);
00616     for (int i = nb; i < n; i++)
00617       b(i) = 0;
00618 
00619     // Computes Q^t b.
00620     sormlq_(&side, &trans, &n, &nrhs, &k, A.GetData(),
00621             &m, tau.GetData(), b.GetData(),
00622             &n, work.GetData(), &lwork, &info.GetInfoRef());
00623   }
00624 
00625 
00626   template <class Prop0, class Allocator0,
00627             class Allocator1,class Allocator2>
00628   void SolveLQ(const Matrix<double, Prop0, ColMajor, Allocator0>& A,
00629                const Vector<double, VectFull, Allocator1>& tau,
00630                Vector<double, VectFull, Allocator2>& b,
00631                LapackInfo& info)
00632   {
00633     int m = A.GetM();
00634     int n = A.GetN();
00635     int k = tau.GetM();
00636     int nrhs = 1, nb = b.GetM();
00637     char side('L');
00638     char trans('T');
00639     int lwork = max(m, n);
00640     Vector<double, VectFull, Allocator1> work(lwork);
00641     // Solves L y = b.
00642     double alpha(1);
00643     cblas_dtrsm(CblasColMajor, CblasLeft, CblasLower, CblasNoTrans,
00644                 CblasNonUnit, m, nrhs,
00645                 alpha, A.GetData(), m, b.GetData(), b.GetM());
00646 
00647     b.Resize(n);
00648     for (int i = nb; i < n; i++)
00649       b(i) = 0;
00650 
00651     // Computes Q^t b.
00652     dormlq_(&side, &trans, &n, &nrhs, &k, A.GetData(),
00653             &m, tau.GetData(), b.GetData(),
00654             &n, work.GetData(), &lwork, &info.GetInfoRef());
00655   }
00656 
00657 
00658   template <class Prop0, class Allocator0,
00659             class Allocator1,class Allocator2>
00660   void SolveLQ(const Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
00661                const Vector<complex<double>, VectFull, Allocator1>& tau,
00662                Vector<complex<double>, VectFull, Allocator2>& b,
00663                LapackInfo& info)
00664   {
00665     int m = A.GetM();
00666     int n = A.GetN();
00667     int k = tau.GetM();
00668     int nrhs = 1, nb = b.GetM();
00669     char side('L');
00670     char trans('C');
00671     int lwork = max(m, n);
00672     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00673     // Solve L y = b.
00674     complex<double> alpha(1);
00675     cblas_ztrsm(CblasColMajor, CblasLeft, CblasLower, CblasNoTrans,
00676                 CblasNonUnit, m, nrhs,
00677                 &alpha, A.GetData(), m, b.GetData(), b.GetM());
00678 
00679     b.Resize(n);
00680     for (int i = nb; i < n; i++)
00681       b(i) = 0;
00682 
00683     // Computes Q^t.
00684     zunmlq_(&side, &trans, &n, &nrhs, &k, A.GetData(),
00685             &m, tau.GetData(), b.GetData(),
00686             &n, work.GetData(), &lwork, &info.GetInfoRef());
00687   }
00688 
00689 
00690   /*** RowMajor ***/
00691 
00692 
00693   template <class Prop0, class Allocator0,
00694             class Allocator1,class Allocator2>
00695   void SolveLQ(const Matrix<float, Prop0, RowMajor, Allocator0>& A,
00696                const Vector<float, VectFull, Allocator1>& tau,
00697                Vector<float, VectFull, Allocator2>& b,
00698                LapackInfo& info)
00699   {
00700     int m = A.GetM();
00701     int n = A.GetN();
00702     int k = tau.GetM();
00703     int nrhs = 1, nb = b.GetM();
00704     char side('L');
00705     char trans('N');
00706     int lwork = max(m, n);
00707     Vector<float, VectFull, Allocator1> work(lwork);
00708     // Solves R^t x = b.
00709     float alpha(1);
00710     cblas_strsm(CblasColMajor, CblasLeft, CblasUpper, CblasTrans,
00711                 CblasNonUnit, b.GetM(), nrhs,
00712                 alpha, A.GetData(), A.GetN(), b.GetData(), b.GetM());
00713 
00714     b.Resize(n);
00715     for (int i = nb; i < n; i++)
00716       b(i) = 0;
00717 
00718     // Multiplies by Q.
00719     sormqr_(&side, &trans, &n, &nrhs, &k, A.GetData(),
00720             &n, tau.GetData(), b.GetData(),
00721             &n, work.GetData(), &lwork, &info.GetInfoRef());
00722   }
00723 
00724 
00725   template <class Prop0, class Allocator0,
00726             class Allocator1,class Allocator2>
00727   void SolveLQ(const Matrix<double, Prop0, RowMajor, Allocator0>& A,
00728                const Vector<double, VectFull, Allocator1>& tau,
00729                Vector<double, VectFull, Allocator2>& b,
00730                LapackInfo& info)
00731   {
00732     int m = A.GetM();
00733     int n = A.GetN();
00734     int k = tau.GetM();
00735     int nrhs = 1, nb = b.GetM();
00736     char side('L');
00737     char trans('N');
00738     int lwork = max(m, n);
00739     Vector<double, VectFull, Allocator1> work(lwork);
00740     // Solves R^t x = b.
00741     double alpha(1);
00742     cblas_dtrsm(CblasColMajor, CblasLeft, CblasUpper, CblasTrans,
00743                 CblasNonUnit, b.GetM(), nrhs,
00744                 alpha, A.GetData(), A.GetN(), b.GetData(), b.GetM());
00745 
00746     b.Resize(n);
00747     for (int i = nb; i < n; i++)
00748       b(i) = 0;
00749 
00750     // Multiplies by Q.
00751     dormqr_(&side, &trans, &n, &nrhs, &k, A.GetData(),
00752             &n, tau.GetData(), b.GetData(),
00753             &n, work.GetData(), &lwork, &info.GetInfoRef());
00754   }
00755 
00756 
00757   template <class Prop0, class Allocator0,
00758             class Allocator1,class Allocator2>
00759   void SolveLQ(const Matrix<complex<double>, Prop0, RowMajor, Allocator0>& A,
00760                const Vector<complex<double>, VectFull, Allocator1>& tau,
00761                Vector<complex<double>, VectFull, Allocator2>& b,
00762                LapackInfo& info)
00763   {
00764     int m = A.GetM();
00765     int n = A.GetN();
00766     int k = tau.GetM();
00767     int nrhs = 1, nb = b.GetM();
00768     char side('L');
00769     char trans('C');
00770     int lwork = max(m, n);
00771     Vector<complex<double>, VectFull, Allocator1> work(lwork);
00772     // Solves R^t x = b.
00773     complex<double> alpha(1);
00774     cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasTrans,
00775                 CblasNonUnit, b.GetM(), nrhs,
00776                 &alpha, A.GetData(), A.GetN(), b.GetData(), b.GetM());
00777 
00778     b.Resize(n);
00779     for (int i = nb; i < n; i++)
00780       b(i) = 0;
00781 
00782     // Computes Q b.
00783     zunmqr_(&side, &trans, &n, &nrhs, &k, A.GetData(),
00784             &n, tau.GetData(), b.GetData(),
00785             &n, work.GetData(), &lwork, &info.GetInfoRef());
00786   }
00787 
00788 
00789   // SOLVELQ //
00791 
00792 
00793 } // end namespace
00794 
00795 #define SELDON_FILE_LAPACK_LEAST_SQUARES_CXX
00796 #endif