uselapack.h

00001 /* MLPACK 0.2
00002  *
00003  * Copyright (c) 2008, 2009 Alexander Gray,
00004  *                          Garry Boyer,
00005  *                          Ryan Riegel,
00006  *                          Nikolaos Vasiloglou,
00007  *                          Dongryeol Lee,
00008  *                          Chip Mappus, 
00009  *                          Nishant Mehta,
00010  *                          Hua Ouyang,
00011  *                          Parikshit Ram,
00012  *                          Long Tran,
00013  *                          Wee Chin Wong
00014  *
00015  * Copyright (c) 2008, 2009 Georgia Institute of Technology
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of the
00020  * License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful, but
00023  * WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  * General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00030  * 02110-1301, USA.
00031  */
00038 #ifndef LA_USELAPACK_H
00039 #define LA_USELAPACK_H
00040 
00041 #include "fastlib/la/matrix.h"
00042 //#include "matrix.h"
00043 #include "fastlib/col/arraylist.h"
00044 
00045 #define DEBUG_VECSIZE(a, b) \
00046     DEBUG_SAME_SIZE((a).length(), (b).length())
00047 #define DEBUG_MATSIZE(a, b) \
00048     DEBUG_SAME_SIZE((a).n_rows(), (b).n_rows());\
00049     DEBUG_SAME_SIZE((a).n_cols(), (b).n_cols())
00050 #define DEBUG_MATSQUARE(a) \
00051     DEBUG_SAME_SIZE((a).n_rows(), (a).n_cols())
00052 
00053 /*
00054  * TODO: this could an overhaul; LAPACK failures may mean either input
00055  * problems or just some linear algebra result (e.g. singular matrix).
00056  *
00057  * Perhaps extend success_t?
00058  */
00059 #define SUCCESS_FROM_LAPACK(info) \
00060     (likely((info) == 0) ? SUCCESS_PASS : SUCCESS_FAIL)
00061 
00062 #ifndef NO_LAPACK
00063 #define USE_LAPACK
00064 #define USE_BLAS_L1
00065 #endif
00066 
00067 #if defined(DOXYGEN) && !defined(USE_LAPACK)
00068 /* Use the doxygen from the blas level 1 code. */
00069 #define USE_LAPACK
00070 #endif
00071 
00072 #ifdef USE_LAPACK
00073 #include "fastlib/la/blas.h"
00074 #include "fastlib/la/clapack.h"
00075 //#include "blas.h"
00076 //#include "clapack.h"
00077 #endif
00078 
00131 namespace la {
00136   inline void ScaleRows(index_t n_rows, index_t n_cols,
00137       const double *scales, double *matrix) {
00138     do {
00139       for (index_t i = 0; i < n_rows; i++) {
00140         matrix[i] *= scales[i];
00141       }
00142       matrix += n_rows;
00143     } while (--n_cols);
00144   }
00145 
00146 #if defined(USE_LAPACK) && defined(USE_BLAS_L1)
00147   /* --- Wrappers for BLAS level 1 --- */
00148   /*
00149    * TODO: Add checking to ensure arrays are non-overlapping.
00150    */
00151 
00155   inline double LengthEuclidean(index_t length, const double *x) {
00156     return F77_FUNC(dnrm2)(length, x, 1);
00157   }
00158 
00163   inline double Dot(index_t length, const double *x, const double *y) {
00164     return F77_FUNC(ddot)(length, x, 1, y, 1);
00165   }
00166 
00171   inline void Scale(index_t length, double alpha, double *x) {
00172     F77_FUNC(dscal)(length, alpha, x, 1);
00173   }
00178   inline void ScaleOverwrite(index_t length,
00179       double alpha, const double *x, double *y) {
00180     mem::Copy(y, x, length);
00181     Scale(length, alpha, y);
00182   }
00183 
00188   inline void AddExpert(index_t length,
00189       double alpha, const double *x, double *y) {
00190     F77_FUNC(daxpy)(length, alpha, x, 1, y, 1);
00191   }
00192 
00197   inline void AddTo(index_t length, const double *x, double *y) {
00198     AddExpert(length, 1.0, x, y);
00199   }
00204   inline void AddOverwrite(index_t length,
00205       const double *x, const double *y, double *z) {
00206     mem::Copy(z, y, length);
00207     AddTo(length, x, z);
00208   }
00209 
00214   inline void SubFrom(index_t length, const double *x, double *y) {
00215     AddExpert(length, -1.0, x, y);
00216   }
00221   inline void SubOverwrite(index_t length,
00222       const double *x, const double *y, double *z) {
00223     mem::Copy(z, y, length);
00224     SubFrom(length, x, z);
00225   }
00226 #else
00227   /* --- Equivalent to BLAS level 1 --- */
00228   /* These functions steal their comments from the previous versons */
00229   
00230   inline double LengthEuclidean(index_t length, const double *x) {
00231     double sum = 0;
00232     do {
00233       sum += *x * *x;
00234       x++;
00235     } while (--length);
00236     return sqrt(sum);
00237   }
00238 
00239   inline double Dot(index_t length, const double *x, const double *y) {
00240     double sum = 0;
00241     const double *end = x + length;
00242     while (x != end) {
00243       sum += *x++ * *y++;
00244     }
00245     return sum;
00246   }
00247 
00248   inline void Scale(index_t length, double alpha, double *x) {
00249     const double *end = x + length;
00250     while (x != end) {
00251       *x++ *= alpha;
00252     }
00253   }
00254 
00255   inline void ScaleOverwrite(index_t length,
00256       double alpha, const double *x, double *y) {
00257     const double *end = x + length;
00258     while (x != end) {
00259       *y++ = alpha * *x++;
00260     }
00261   }
00262 
00263   inline void AddExpert(index_t length,
00264       double alpha, const double *x, double *y) {
00265     const double *end = x + length;
00266     while (x != end) {
00267       *y++ += alpha * *x++;
00268     }
00269   }
00270 
00271   inline void AddTo(index_t length, const double *x, double *y) {
00272     const double *end = x + length;
00273     while (x != end) {
00274       *y++ += *x++;
00275     }
00276   }
00277 
00278   inline void AddOverwrite(index_t length,
00279       const double *x, const double *y, double *z) {
00280     for (index_t i = 0; i < length; i++) {
00281       z[i] = y[i] + x[i];
00282     }
00283   }
00284 
00285   inline void SubFrom(index_t length, const double *x, double *y) {
00286     const double *end = x + length;
00287     while (x != end) {
00288       *y++ -= *x++;
00289     }
00290   }
00291 
00292   inline void SubOverwrite(index_t length,
00293       const double *x, const double *y, double *z) {
00294     for (index_t i = 0; i < length; i++) {
00295       z[i] = y[i] - x[i];
00296     }
00297   }
00298 #endif
00299 
00304   inline double LengthEuclidean(const Vector &x) {
00305     return LengthEuclidean(x.length(), x.ptr());
00306   }
00307 
00312   inline double Dot(const Vector &x, const Vector &y) {
00313     DEBUG_SAME_SIZE(x.length(), y.length());
00314     return Dot(x.length(), x.ptr(), y.ptr());
00315   }
00322   inline double Dot(const Matrix &x, const Matrix &y) {
00323     DEBUG_SAME_SIZE(x.n_rows(), y.n_rows());
00324     DEBUG_SAME_SIZE(x.n_cols(), y.n_cols());
00325     return Dot(x.n_elements(), x.ptr(), y.ptr());
00326   }
00327 
00328   /* --- Matrix/Vector Scaling --- */
00329 
00334   inline void Scale(double alpha, Vector *x) {
00335     Scale(x->length(), alpha, x->ptr());
00336   }
00341   inline void Scale(double alpha, Matrix *X) {
00342     Scale(X->n_elements(), alpha, X->ptr());
00343   }
00352   inline void ScaleRows(const Vector& d, Matrix *X) {
00353     DEBUG_SAME_SIZE(d.length(), X->n_rows());
00354     ScaleRows(d.length(), X->n_cols(), d.ptr(), X->ptr());
00355   }
00364   inline void ScaleRows(const Matrix& d, Matrix *X) {
00365     DEBUG_SAME_SIZE(min(d.n_cols(), d.n_rows()), 1);
00366     DEBUG_SAME_SIZE(max(d.n_cols(), d.n_rows()), X->n_rows());
00367     ScaleRows(X->n_rows(), X->n_cols(), d.ptr(), X->ptr());
00368   }
00373   inline void ScaleOverwrite(double alpha, const Vector &x, Vector *y) {
00374     DEBUG_SAME_SIZE(x.length(), y->length());
00375     ScaleOverwrite(x.length(), alpha, x.ptr(), y->ptr());
00376   }
00381   inline void ScaleOverwrite(double alpha, const Matrix &X, Matrix *Y) {
00382     DEBUG_SAME_SIZE(X.n_rows(), Y->n_rows());
00383     DEBUG_SAME_SIZE(X.n_cols(), Y->n_cols());
00384     ScaleOverwrite(X.n_elements(), alpha, X.ptr(), Y->ptr());
00385   }
00386 
00391   inline void ScaleInit(double alpha, const Vector &x, Vector *y) {
00392     y->Init(x.length());
00393     ScaleOverwrite(alpha, x, y);
00394   }
00399   inline void ScaleInit(double alpha, const Matrix &X, Matrix *Y) {
00400     Y->Init(X.n_rows(), X.n_cols());
00401     ScaleOverwrite(alpha, X, Y);
00402   }
00403 
00404   /* --- Scaled Matrix/Vector Addition --- */
00405 
00410   inline void AddExpert(double alpha, const Vector &x, Vector *y) {
00411     DEBUG_SAME_SIZE(x.length(), y->length());
00412     AddExpert(x.length(), alpha, x.ptr(), y->ptr());
00413   }
00418   inline void AddExpert(double alpha, const Matrix &X, Matrix *Y) {
00419     DEBUG_SAME_SIZE(X.n_rows(), Y->n_rows());
00420     DEBUG_SAME_SIZE(X.n_cols(), Y->n_cols());
00421     AddExpert(X.n_elements(), alpha, X.ptr(), Y->ptr());
00422   }
00423 
00424   /* --- Matrix/Vector Addition --- */
00425 
00430   inline void AddTo(const Vector &x, Vector *y) {
00431     DEBUG_SAME_SIZE(x.length(), y->length());
00432     AddTo(x.length(), x.ptr(), y->ptr());
00433   }
00438   inline void AddTo(const Matrix &X, Matrix *Y) {
00439     DEBUG_SAME_SIZE(X.n_rows(), Y->n_rows());
00440     DEBUG_SAME_SIZE(X.n_cols(), Y->n_cols());
00441     AddTo(X.n_elements(), X.ptr(), Y->ptr());
00442   }
00443 
00448   inline void AddOverwrite(const Vector &x, const Vector &y, Vector *z) {
00449     DEBUG_SAME_SIZE(x.length(), y.length());
00450     DEBUG_SAME_SIZE(z->length(), y.length());
00451     AddOverwrite(x.length(), x.ptr(), y.ptr(), z->ptr());
00452   }
00457   inline void AddOverwrite(const Matrix &X, const Matrix &Y, Matrix *Z) {
00458     DEBUG_SAME_SIZE(X.n_rows(), Y.n_rows());
00459     DEBUG_SAME_SIZE(X.n_cols(), Y.n_cols());
00460     DEBUG_SAME_SIZE(Z->n_rows(), Y.n_rows());
00461     DEBUG_SAME_SIZE(Z->n_cols(), Y.n_cols());
00462     AddOverwrite(X.n_elements(), X.ptr(), Y.ptr(), Z->ptr());
00463   }
00464 
00469   inline void AddInit(const Vector &x, const Vector &y, Vector *z) {
00470     z->Init(x.length());
00471     AddOverwrite(x, y, z);
00472   }
00477   inline void AddInit(const Matrix &X, const Matrix &Y, Matrix *Z) {
00478     Z->Init(X.n_rows(), X.n_cols());
00479     AddOverwrite(X, Y, Z);
00480   }
00481 
00482   /* --- Matrix/Vector Subtraction --- */
00483 
00488   inline void SubFrom(const Vector &x, Vector *y) {
00489     DEBUG_SAME_SIZE(x.length(), y->length());
00490     SubFrom(x.length(), x.ptr(), y->ptr());
00491   }
00496   inline void SubFrom(const Matrix &X, Matrix *Y) {
00497     DEBUG_SAME_SIZE(X.n_rows(), Y->n_rows());
00498     DEBUG_SAME_SIZE(X.n_cols(), Y->n_cols());
00499     SubFrom(X.n_elements(), X.ptr(), Y->ptr());
00500   }
00501 
00506   inline void SubOverwrite(const Vector &x, const Vector &y, Vector *z) {
00507     DEBUG_SAME_SIZE(x.length(), y.length());
00508     DEBUG_SAME_SIZE(z->length(), y.length());
00509     SubOverwrite(x.length(), x.ptr(), y.ptr(), z->ptr());
00510   }
00515   inline void SubOverwrite(const Matrix &X, const Matrix &Y, Matrix *Z) {
00516     DEBUG_SAME_SIZE(X.n_rows(), Y.n_rows());
00517     DEBUG_SAME_SIZE(X.n_cols(), Y.n_cols());
00518     DEBUG_SAME_SIZE(Z->n_rows(), Y.n_rows());
00519     DEBUG_SAME_SIZE(Z->n_cols(), Y.n_cols());
00520     SubOverwrite(X.n_elements(), X.ptr(), Y.ptr(), Z->ptr());
00521   }
00522 
00527   inline void SubInit(const Vector &x, const Vector &y, Vector *z) {
00528     z->Init(x.length());
00529     SubOverwrite(x, y, z);
00530   }
00535   inline void SubInit(const Matrix &X, const Matrix &Y, Matrix *Z) {
00536     Z->Init(X.n_rows(), X.n_cols());
00537     SubOverwrite(X, Y, Z);
00538   }
00539 
00540   /* --- Matrix Transpose --- */
00541 
00542   /*
00543    * TODO: These could be an order of magnitude faster if we use the
00544    * cache-efficient Morton layout matrix transpose algoritihm.
00545    */
00546 
00551   inline void TransposeSquare(Matrix *X) {
00552     DEBUG_MATSQUARE(*X);
00553     index_t nr = X->n_rows();
00554     for (index_t r = 1; r < nr; r++) {
00555       for (index_t c = 0; c < r; c++) {
00556         double temp = X->get(r, c);
00557         X->set(r, c, X->get(c, r));
00558         X->set(c, r, temp);        
00559       }
00560     }
00561   }
00562 
00567   inline void TransposeOverwrite(const Matrix &X, Matrix *Y) {
00568     DEBUG_SAME_SIZE(X.n_rows(), Y->n_cols());
00569     DEBUG_SAME_SIZE(X.n_cols(), Y->n_rows());
00570     index_t nr = X.n_rows();
00571     index_t nc = X.n_cols();
00572     for (index_t r = 0; r < nr; r++) {
00573       for (index_t c = 0; c < nc; c++) {
00574         Y->set(c, r, X.get(r, c));
00575       }
00576     }
00577   }
00582   inline void TransposeInit(const Matrix &X, Matrix *Y) {
00583     Y->Init(X.n_cols(), X.n_rows());
00584     TransposeOverwrite(X, Y);
00585   }
00586 
00587 
00588 
00589 #ifdef USE_LAPACK
00590   /* --- Wrappers for BLAS level 2 --- */
00591 
00602   inline void MulExpert(
00603       double alpha, const Matrix &A, const Vector &x,
00604       double beta, Vector *y) {
00605     DEBUG_ASSERT(x.ptr() != y->ptr());
00606     DEBUG_SAME_SIZE(A.n_cols(), x.length());
00607     DEBUG_SAME_SIZE(A.n_rows(), y->length());
00608     F77_FUNC(dgemv)("N", A.n_rows(), A.n_cols(),
00609         alpha, A.ptr(), A.n_rows(), x.ptr(), 1,
00610         beta, y->ptr(), 1);
00611   }
00612 
00632   inline void MulOverwrite(const Matrix &A, const Vector &x, Vector *y) {
00633     MulExpert(1.0, A, x, 0.0, y);
00634   }
00644   inline void MulInit(const Matrix &A, const Vector &x, Vector *y) {
00645     y->Init(A.n_rows());
00646     MulOverwrite(A, x, y);
00647   }
00648 
00661   inline void MulExpert(
00662       double alpha, const Vector &x, const Matrix &A,
00663       double beta, Vector *y) {
00664     DEBUG_ASSERT(x.ptr() != y->ptr());
00665     DEBUG_SAME_SIZE(A.n_rows(), x.length());
00666     DEBUG_SAME_SIZE(A.n_cols(), y->length());
00667     F77_FUNC(dgemv)("T", A.n_rows(), A.n_cols(),
00668         alpha, A.ptr(), A.n_rows(), x.ptr(), 1,
00669         beta, y->ptr(), 1);
00670   }
00671 
00680   inline void MulOverwrite(const Vector &x, const Matrix &A, Vector *y) {
00681     MulExpert(1.0, x, A, 0.0, y);
00682   }
00692   inline void MulInit(const Vector &x, const Matrix &A, Vector *y) {
00693     y->Init(A.n_cols());
00694     MulOverwrite(x, A, y);
00695   }
00696 
00697 
00698 
00699   /* --- Wrappers for BLAS level 3 --- */
00700 
00713   inline void MulExpert(
00714       double alpha,
00715       bool trans_A, const Matrix &A,
00716       bool trans_B, const Matrix &B,
00717       double beta, Matrix *C) {
00718     DEBUG_ASSERT(A.ptr() != C->ptr());
00719     DEBUG_ASSERT(B.ptr() != C->ptr());
00720     DEBUG_SAME_SIZE(trans_A ? A.n_rows() : A.n_cols(),
00721                    trans_B ? B.n_cols() : B.n_rows());
00722     DEBUG_SAME_SIZE(trans_A ? A.n_cols() : A.n_rows(), C->n_rows());
00723     DEBUG_SAME_SIZE(trans_B ? B.n_rows() : B.n_cols(), C->n_cols());
00724     F77_FUNC(dgemm)(trans_A ? "T" : "N", trans_B ? "T" : "N",
00725         C->n_rows(), C->n_cols(), trans_A ? A.n_rows() : A.n_cols(),
00726         alpha, A.ptr(), A.n_rows(), B.ptr(), B.n_rows(),
00727         beta, C->ptr(), C->n_rows());
00728   }
00739   inline void MulExpert(
00740       double alpha, const Matrix &A, const Matrix &B,
00741       double beta, Matrix *C) {
00742     MulExpert(alpha, false, A, false, B, beta, C);
00743   }
00744 
00764   inline void MulOverwrite(const Matrix &A, const Matrix &B, Matrix *C) {
00765     MulExpert(1.0, A, B, 0.0, C);
00766   }
00776   inline void MulInit(const Matrix &A, const Matrix &B, Matrix *C) {
00777     C->Init(A.n_rows(), B.n_cols());
00778     MulOverwrite(A, B, C);
00779   }
00780 
00789   inline void MulTransAOverwrite(
00790       const Matrix &A, const Matrix &B, Matrix *C) {
00791     MulExpert(1.0, true, A, false, B, 0.0, C);
00792   }
00802   inline void MulTransAInit(
00803       const Matrix &A, const Matrix &B, Matrix *C) {
00804     C->Init(A.n_cols(), B.n_cols());
00805     MulTransAOverwrite(A, B, C);
00806   }
00807 
00816   inline void MulTransBOverwrite(
00817       const Matrix &A, const Matrix &B, Matrix *C) {
00818     MulExpert(1.0, false, A, true, B, 0.0, C);
00819   }
00829   inline void MulTransBInit(
00830       const Matrix &A, const Matrix &B, Matrix *C) {
00831     C->Init(A.n_rows(), B.n_rows());
00832     MulTransBOverwrite(A, B, C);
00833   }
00834 
00835 
00836 
00837   /* --- Wrappers for LAPACK --- */
00838 
00839   extern int dgetri_block_size;
00840   extern int dgeqrf_block_size;
00841   extern int dorgqr_block_size;
00842   extern int dgeqrf_dorgqr_block_size;
00843 
00854   inline success_t PLUExpert(f77_integer *pivots, Matrix *A_in_LU_out) {
00855     f77_integer info;
00856     F77_FUNC(dgetrf)(A_in_LU_out->n_rows(), A_in_LU_out->n_cols(),
00857         A_in_LU_out->ptr(), A_in_LU_out->n_rows(), pivots, &info);
00858     return SUCCESS_FROM_LAPACK(info);
00859   }
00872   success_t PLUInit(const Matrix &A,
00873       ArrayList<f77_integer> *pivots, Matrix *L, Matrix *U);
00874 
00882   inline success_t InverseExpert(f77_integer *pivots, Matrix *LU_in_B_out) {
00883     f77_integer info;
00884     f77_integer n = LU_in_B_out->n_rows();
00885     f77_integer lwork = dgetri_block_size * n;
00886     double work[lwork];
00887     DEBUG_MATSQUARE(*LU_in_B_out);
00888     F77_FUNC(dgetri)(n, LU_in_B_out->ptr(), n, pivots, work, lwork, &info);
00889     return SUCCESS_FROM_LAPACK(info);
00890   }
00905   success_t Inverse(Matrix *A);
00923   success_t InverseOverwrite(const Matrix &A, Matrix *B);
00933   inline success_t InverseInit(const Matrix &A, Matrix *B) {
00934     B->Init(A.n_rows(), A.n_cols());
00935     return InverseOverwrite(A, B);
00936   }
00937 
00952   long double Determinant(const Matrix &A);
00964   double DeterminantLog(const Matrix &A, int *sign_out);
00965 
00980   inline success_t SolveExpert(
00981       f77_integer *pivots, Matrix *A_in_LU_out,
00982       index_t k, double *B_in_X_out) {
00983     DEBUG_MATSQUARE(*A_in_LU_out);
00984     f77_integer info;
00985     f77_integer n = A_in_LU_out->n_rows();
00986     F77_FUNC(dgesv)(n, k, A_in_LU_out->ptr(), n, pivots,
00987         B_in_X_out, n, &info);
00988     return SUCCESS_FROM_LAPACK(info);
00989   }
01013   inline success_t SolveInit(const Matrix &A, const Matrix &B, Matrix *X) {
01014     DEBUG_MATSQUARE(A);
01015     DEBUG_SAME_SIZE(A.n_rows(), B.n_rows());
01016     Matrix tmp;
01017     index_t n = B.n_rows();
01018     f77_integer pivots[n];
01019     tmp.Copy(A);
01020     X->Copy(B);
01021     return SolveExpert(pivots, &tmp, B.n_cols(), X->ptr());
01022   }
01046   inline success_t SolveInit(const Matrix &A, const Vector &b, Vector *x) {
01047     DEBUG_MATSQUARE(A);
01048     DEBUG_SAME_SIZE(A.n_rows(), b.length());
01049     Matrix tmp;
01050     index_t n = b.length();
01051     f77_integer pivots[n];
01052     tmp.Copy(A);
01053     x->Copy(b);
01054     return SolveExpert(pivots, &tmp, 1, x->ptr());
01055   }
01056 
01070   success_t QRExpert(Matrix *A_in_Q_out, Matrix *R);
01097   success_t QRInit(const Matrix &A, Matrix *Q, Matrix *R);
01098 
01112   success_t SchurExpert(Matrix *A_in_T_out,
01113       double *w_real, double *w_imag, double *Z);
01128   inline success_t SchurInit(const Matrix &A,
01129       Vector *w_real, Vector *w_imag, Matrix *T, Matrix *Z) {
01130     index_t n = A.n_rows();
01131     T->Copy(A);
01132     w_real->Init(n);
01133     w_imag->Init(n);
01134     Z->Init(n, n);
01135     return SchurExpert(T, w_real->ptr(), w_imag->ptr(), Z->ptr());
01136   }
01137 
01152   success_t EigenExpert(Matrix *A_garbage,
01153       double *w_real, double *w_imag, double *V_raw);
01154 
01165   inline success_t EigenvaluesInit(const Matrix &A,
01166       Vector *w_real, Vector *w_imag) {
01167     DEBUG_MATSQUARE(A);
01168     int n = A.n_rows();
01169     w_real->Init(n);
01170     w_imag->Init(n);
01171     Matrix tmp;
01172     tmp.Copy(A);
01173     return SchurExpert(&tmp, w_real->ptr(), w_imag->ptr(), NULL);
01174   }
01193   success_t EigenvaluesInit(const Matrix &A, Vector *w);
01194 
01222   success_t EigenvectorsInit(const Matrix &A,
01223       Vector *w_real, Vector *w_imag, Matrix *V_real, Matrix *V_imag);
01224 
01238   success_t EigenvectorsInit(const Matrix &A, Vector *w, Matrix *V);
01239 
01260   success_t GenEigenSymmetric(int itype, Matrix *A_eigenvec, Matrix *B_chol, double *w);
01261 
01293   success_t GenEigenNonSymmetric(Matrix *A_garbage, Matrix *B_garbage,
01294       double *alpha_real, double *alpha_imag, double *beta, double *V_raw);
01295 
01311   success_t SVDExpert(Matrix* A_garbage, double *s, double *U, double *VT);
01312 
01321   inline success_t SVDInit(const Matrix &A, Vector *s) {
01322     s->Init(std::min(A.n_rows(), A.n_cols()));
01323     Matrix tmp;
01324     tmp.Copy(A);
01325     return SVDExpert(&tmp, s->ptr(), NULL, NULL);
01326   }
01327 
01359   inline success_t SVDInit(const Matrix &A, Vector *s, Matrix *U, Matrix *VT) {
01360     index_t k = std::min(A.n_rows(), A.n_cols());
01361     s->Init(k);
01362     U->Init(A.n_rows(), k);
01363     VT->Init(k, A.n_cols());
01364     Matrix tmp;
01365     tmp.Copy(A);
01366     return SVDExpert(&tmp, s->ptr(), U->ptr(), VT->ptr());
01367   }
01368 
01377   success_t Cholesky(Matrix *A_in_U_out);
01378 
01399   inline success_t CholeskyInit(const Matrix &A, Matrix *U) {
01400     U->Copy(A);
01401     return Cholesky(U);
01402   }
01403 #endif
01404 
01405   /*
01406    * TODO:
01407    *   symmetric eigenvalue
01408    *   http://www.netlib.org/lapack/lug/node71.html
01409    *   dgels for least-squares problems
01410    *   dgesv for linear equations
01411    */
01412 };
01413 
01414 #endif
Generated on Mon Jan 24 12:04:37 2011 for FASTlib by  doxygen 1.6.3