lapack.cpp

Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 1999-2009 Soeren Sonnenburg
00008  * Written (W) 1999-2008 Gunnar Raetsch
00009  * Written (W) 2006-2007 Mikio L. Braun
00010  * Written (W) 2008 Jochen Garcke
00011  * Written (W) 2011 Sergey Lisitsyn
00012  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00013  */
00014 
00015 #include <shogun/lib/config.h>
00016 
00017 #ifdef HAVE_LAPACK
00018 #include <shogun/mathematics/lapack.h>
00019 #include <shogun/lib/common.h>
00020 #include <shogun/io/SGIO.h>
00021 
00022 using namespace shogun;
00023 
00024 #if defined(HAVE_MKL) || defined(HAVE_ACML) 
00025 #define DSYEV dsyev
00026 #define DGESVD dgesvd
00027 #define DPOSV dposv
00028 #define DPOTRF dpotrf
00029 #define DPOTRI dpotri
00030 #define DGETRI dgetri
00031 #define DGETRF dgetrf
00032 #define DGEQRF dgeqrf
00033 #define DORGQR dorgqr
00034 #define DSYEVR dsyevr
00035 #define DPOTRS dpotrs
00036 #define DGETRS dgetrs
00037 #define DSYGVX dsygvx
00038 #else
00039 #define DSYEV dsyev_
00040 #define DGESVD dgesvd_
00041 #define DPOSV dposv_
00042 #define DPOTRF dpotrf_
00043 #define DPOTRI dpotri_
00044 #define DGETRI dgetri_
00045 #define DGETRF dgetrf_
00046 #define DGEQRF dgeqrf_
00047 #define DORGQR dorgqr_
00048 #define DSYEVR dsyevr_
00049 #define DGETRS dgetrs_
00050 #define DPOTRS dpotrs_
00051 #define DSYGVX dsygvx_
00052 #endif
00053 
00054 #ifndef HAVE_ATLAS
00055 int clapack_dpotrf(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo,
00056         const int N, double *A, const int LDA)
00057 {
00058     char uplo = 'U';
00059     int info = 0;
00060     if (Order==CblasRowMajor)
00061     {//A is symmetric, we switch Uplo to get result for CblasRowMajor
00062         if (Uplo==CblasUpper)
00063             uplo='L';
00064     }
00065     else if (Uplo==CblasLower)
00066     {
00067         uplo='L';
00068     }
00069 #ifdef HAVE_ACML
00070     DPOTRF(uplo, N, A, LDA, &info);
00071 #else
00072     int n=N;
00073     int lda=LDA;
00074     DPOTRF(&uplo, &n, A, &lda, &info);
00075 #endif
00076     return info;
00077 }
00078 #undef DPOTRF
00079 
00080 int clapack_dpotri(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo,
00081         const int N, double *A, const int LDA)
00082 {
00083     char uplo = 'U';
00084     int info = 0;
00085     if (Order==CblasRowMajor)
00086     {//A is symmetric, we switch Uplo to get result for CblasRowMajor
00087         if (Uplo==CblasUpper)
00088             uplo='L';
00089     }
00090     else if (Uplo==CblasLower)
00091     {
00092         uplo='L';
00093     }
00094 #ifdef HAVE_ACML
00095     DPOTRI(uplo, N, A, LDA, &info);
00096 #else
00097     int n=N;
00098     int lda=LDA;
00099     DPOTRI(&uplo, &n, A, &lda, &info);
00100 #endif
00101     return info;
00102 }
00103 #undef DPOTRI
00104 
00105 /* DPOSV computes the solution to a real system of linear equations
00106  * A * X = B,
00107  * where A is an N-by-N symmetric positive definite matrix and X and B
00108  * are N-by-NRHS matrices
00109  */
00110 int clapack_dposv(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo,
00111         const int N, const int NRHS, double *A, const int lda,
00112         double *B, const int ldb)
00113 {
00114     char uplo = 'U';
00115     int info=0;
00116     if (Order==CblasRowMajor)
00117     {//A is symmetric, we switch Uplo to achieve CblasColMajor
00118         if (Uplo==CblasUpper)
00119             uplo='L';
00120     }
00121     else if (Uplo==CblasLower)
00122     {
00123         uplo='L';
00124     }
00125 #ifdef HAVE_ACML
00126     DPOSV(uplo,N,NRHS,A,lda,B,ldb,&info);
00127 #else
00128     int n=N;
00129     int nrhs=NRHS;
00130     int LDA=lda;
00131     int LDB=ldb;
00132     DPOSV(&uplo, &n, &nrhs, A, &LDA, B, &LDB, &info);
00133 #endif
00134     return info;
00135 }
00136 #undef DPOSV
00137 
00138 int clapack_dgetrf(const CBLAS_ORDER Order, const int M, const int N,
00139                    double *A, const int lda, int *ipiv)
00140 {
00141     // no rowmajor?
00142     int info=0;
00143 #ifdef HAVE_ACML
00144     DGETRF(M,N,A,lda,ipiv,&info);
00145 #else
00146     int m=M;
00147     int n=N;
00148     int LDA=lda;
00149     DGETRF(&m,&n,A,&LDA,ipiv,&info);
00150 #endif
00151     return info;
00152 }
00153 #undef DGETRF
00154 
00155 // order not supported (yet?)
00156 int clapack_dgetri(const CBLAS_ORDER Order, const int N, double *A,
00157                    const int lda, int* ipiv)
00158 {
00159     int info=0;
00160     double* work = SG_MALLOC(double, 1);
00161 #ifdef HAVE_ACML
00162     DGETRI(N,A,lda,ipiv,&info);
00163 #else
00164     int n=N;
00165     int LDA=lda;
00166     int lwork = -1;
00167     double work1 = 0;
00168     DGETRI(&n,A,&LDA,ipiv,&work1,&lwork,&info);
00169     lwork = (int) work1;
00170     SG_FREE(work);
00171     work = SG_MALLOC(double, lwork);
00172     DGETRI(&n,A,&LDA,ipiv,work,&lwork,&info);
00173 #endif
00174     return info;
00175 }
00176 #undef DGETRI
00177 
00178 // order not supported (yet?)
00179 int clapack_dgetrs(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE Transpose,
00180                    const int N, const int NRHS, double *A, const int lda, 
00181                    int *ipiv, double *B, const int ldb)
00182 {
00183     int info = 0;
00184     char trans = 'N';
00185     if (Transpose==CblasTrans) 
00186     {
00187         trans = 'T';
00188     }
00189 #ifdef HAVE_ACML
00190     DGETRS(trans,N,NRHS,A,lda,ipiv,B,ldb,info);
00191 #else
00192     int n=N;
00193     int nrhs=NRHS;
00194     int LDA=lda;
00195     int LDB=ldb;
00196     DGETRS(&trans,&n,&nrhs,A,&LDA,ipiv,B,&LDB,&info);
00197 #endif
00198     return info;
00199 }
00200 #undef DGETRS
00201 
00202 // order not supported (yet?)
00203 int clapack_dpotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
00204                    const int N, const int NRHS, double *A, const int lda,
00205                    double *B, const int ldb)
00206 {
00207     int info=0;
00208     char uplo = 'U';
00209     if (Uplo==CblasLower)
00210     {
00211         uplo = 'L';
00212     }
00213 #ifdef HAVE_ACML
00214     DPOTRS(uplo,N,NRHS,A,lda,B,ldb,info);
00215 #else
00216     int n=N;
00217     int nrhs=NRHS;
00218     int LDA=lda;
00219     int LDB=ldb;
00220     DPOTRS(&uplo,&n,&nrhs,A,&LDA,B,&LDB,&info);
00221 #endif
00222     return info;
00223 }
00224 #undef DPOTRS
00225 
00226 #endif //HAVE_ATLAS
00227 
00228 namespace shogun
00229 {
00230 
00231 void wrap_dsyev(char jobz, char uplo, int n, double *a, int lda, double *w, int *info)
00232 {
00233 #ifdef HAVE_ACML
00234     DSYEV(jobz, uplo, n, a, lda, w, info);
00235 #else
00236     int lwork=-1;
00237     double work1;
00238     DSYEV(&jobz, &uplo, &n, a, &lda, w, &work1, &lwork, info);
00239     ASSERT(*info==0);
00240     ASSERT(work1>0);
00241     lwork=(int) work1;
00242     double* work=SG_MALLOC(double, lwork);
00243     DSYEV(&jobz, &uplo, &n, a, &lda, w, work, &lwork, info);
00244     SG_FREE(work);
00245 #endif
00246 }
00247 #undef DSYEV
00248 
00249 void wrap_dgesvd(char jobu, char jobvt, int m, int n, double *a, int lda, double *sing, 
00250         double *u, int ldu, double *vt, int ldvt, int *info)
00251 {
00252 #ifdef HAVE_ACML
00253     DGESVD(jobu, jobvt, m, n, a, lda, sing, u, ldu, vt, ldvt, info);
00254 #else
00255     int lwork=-1;
00256     double work1;
00257     DGESVD(&jobu, &jobvt, &m, &n, a, &lda, sing, u, &ldu, vt, &ldvt, &work1, &lwork, info);
00258     ASSERT(*info==0);
00259     ASSERT(work1>0);
00260     lwork=(int) work1;
00261     double* work=SG_MALLOC(double, lwork);
00262     DGESVD(&jobu, &jobvt, &m, &n, a, &lda, sing, u, &ldu, vt, &ldvt, work, &lwork, info);
00263     SG_FREE(work);
00264 #endif
00265 }
00266 #undef DGESVD
00267 
00268 void wrap_dgeqrf(int m, int n, double *a, int lda, double *tau, int *info)
00269 {
00270 #ifdef HAVE_ACML
00271     DGEQRF(m, n, a, lda, tau, info);
00272 #else
00273     int lwork = -1;
00274     double work1 = 0;
00275     DGEQRF(&m, &n, a, &lda, tau, &work1, &lwork, info);
00276     ASSERT(*info==0);
00277     lwork = (int)work1;
00278     ASSERT(lwork>0)
00279     double* work = SG_MALLOC(double, lwork);
00280     DGEQRF(&m, &n, a, &lda, tau, work, &lwork, info);
00281     SG_FREE(work);
00282 #endif
00283 }
00284 #undef DGEQRF
00285 
00286 void wrap_dorgqr(int m, int n, int k, double *a, int lda, double *tau, int *info)
00287 {
00288 #ifdef HAVE_ACML
00289     DORGQR(m, n, k, a, lda, tau, info);
00290 #else
00291     int lwork = -1;
00292     double work1 = 0;
00293     DORGQR(&m, &n, &k, a, &lda, tau, &work1, &lwork, info);
00294     ASSERT(*info==0);
00295     lwork = (int)work1;
00296     ASSERT(lwork>0);
00297     double* work = SG_MALLOC(double, lwork);
00298     DORGQR(&m, &n, &k, a, &lda, tau, work, &lwork, info);
00299     SG_FREE(work);
00300 #endif
00301 }
00302 #undef DORGQR
00303 
00304 void wrap_dsyevr(char jobz, char uplo, int n, double *a, int lda, int il, int iu, 
00305                  double *eigenvalues, double *eigenvectors, int *info)
00306 {
00307     int m;
00308     double vl,vu; 
00309     double abstol = 0.0;
00310     char I = 'I';
00311     int* isuppz = SG_MALLOC(int, n);
00312 #ifdef HAVE_ACML
00313     DSYEVR(jobz,I,uplo,n,a,lda,vl,vu,il,iu,abstol,m,
00314            eigenvalues,eigenvectors,n,isuppz,info);
00315 #else
00316     int lwork = -1;
00317     int liwork = -1;
00318     double work1 = 0;
00319     int* iwork = SG_MALLOC(int, 1);
00320     DSYEVR(&jobz,&I,&uplo,&n,a,&lda,&vl,&vu,&il,&iu,&abstol,
00321                &m,eigenvalues,eigenvectors,&n,isuppz,
00322                &work1,&lwork,iwork,&liwork,info);
00323     ASSERT(*info==0);
00324     lwork = (int)work1;
00325     liwork = iwork[0];
00326     SG_FREE(iwork);
00327     double* work = SG_MALLOC(double, lwork);
00328     iwork = SG_MALLOC(int, liwork);
00329     DSYEVR(&jobz,&I,&uplo,&n,a,&lda,&vl,&vu,&il,&iu,&abstol,
00330                &m,eigenvalues,eigenvectors,&n,isuppz,
00331                work,&lwork,iwork,&liwork,info);
00332     ASSERT(*info==0);
00333     SG_FREE(work);
00334     SG_FREE(iwork);
00335     SG_FREE(isuppz);
00336 #endif
00337 }
00338 #undef DSYEVR
00339 
00340 void wrap_dsygvx(int itype, char jobz, char uplo, int n, double *a, int lda, double *b,
00341                  int ldb, int il, int iu, double *eigenvalues, double *eigenvectors, int *info)
00342 {
00343     int m;
00344     double abstol = 0.0;
00345     double vl,vu;
00346     int* ifail = SG_MALLOC(int, n);
00347     char I = 'I';
00348 #ifdef HAVE_ACML
00349     DSYGVX(itype,jobz,I,uplo,n,a,lda,b,ldb,vl,vu,
00350                il,iu,abstol,m,eigenvalues,
00351                eigenvectors,n,ifail,info);
00352 #else
00353     int lwork = -1;
00354     double work1 = 0;
00355     int* iwork = SG_MALLOC(int, 5*n);
00356     DSYGVX(&itype,&jobz,&I,&uplo,&n,a,&lda,b,&ldb,&vl,&vu,
00357                &il,&iu,&abstol,&m,eigenvalues,eigenvectors,
00358                &n,&work1,&lwork,iwork,ifail,info);
00359     lwork = (int)work1;
00360     double* work = SG_MALLOC(double, lwork);
00361     DSYGVX(&itype,&jobz,&I,&uplo,&n,a,&lda,b,&ldb,&vl,&vu,
00362                &il,&iu,&abstol,&m,eigenvalues,eigenvectors,
00363                &n,work,&lwork,iwork,ifail,info);
00364     SG_FREE(work);
00365     SG_FREE(iwork);
00366     SG_FREE(ifail);
00367 #endif
00368 }
00369 #undef DSYGVX
00370 
00371 }
00372 #endif //HAVE_LAPACK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation