00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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 {
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 {
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
00106
00107
00108
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 {
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
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
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
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
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