liblapackwrap 0.1

lapackwrap_real_double.c

Go to the documentation of this file.
00001 /*
00002  * Wrapper for a variety of LAPACK routines, to provide a unified interface.
00003 
00004  Copyright (C) 2010 Joseph Pingenot
00005 
00006  This program is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU Lesser General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  This program is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  GNU Lesser General Public License for more details.
00015 
00016  You should have received a copy of the GNU Lesser General Public License
00017  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include "liblapackwrap/lapackwrap_real_double.h"
00025 #include "liblapackwrap/lapackwrap_functions_real_double.c"
00026 
00027 #define ACML 0
00028 #define CELL 1
00029 
00030 /*These follow the FORTRAN calling semantics.*/
00031 #if LAPACK == CELL
00032 #define FCALL
00033 #endif
00034 
00035 int llw_real_double_stegr_a(char jobz, char range, int N, LLW_CONST LLW_real_double_REAL *D, LLW_CONST LLW_real_double_REAL *E, LLW_real_double_REAL VL, LLW_real_double_REAL VU, int IL, int IU, int *M, LLW_real_double_REAL** W, LLW_real_double_COMPLEX** Z, int *LDZ, int** ISUPPZ) {
00036   *W = malloc(sizeof(LLW_real_double_REAL)*N);
00037   if(*W == NULL) {
00038     return 100;
00039   }
00040   /*Right now, we're just doing N.*/
00041   *LDZ = N;
00042   *Z = malloc(sizeof(LLW_real_double_COMPLEX)*(*LDZ)*N);
00043   if(*Z == NULL) {
00044     free(*W);
00045     *W = NULL;
00046     return 100;
00047   }
00048   *ISUPPZ = malloc(sizeof(LLW_real_double_REAL)*2*N);
00049   if(*ISUPPZ == NULL) {
00050     free(*W);
00051     *W = NULL;
00052     free(*Z);
00053     *Z = NULL;
00054     return 100;
00055   }
00056   int info = llw_real_double_stegr(jobz, range, N, D, E, VL, VU, IL, IU, M, *W, *Z, *LDZ, *ISUPPZ);
00057   if(info != 0) {
00058     free(*W);
00059     *W = NULL;
00060     free(*Z);
00061     *Z = NULL;
00062     free(*ISUPPZ);
00063     *ISUPPZ = NULL;
00064   }
00065   return info;
00066 }
00067 
00068 int llw_real_double_stegr(char jobz, char range, int N, LLW_CONST LLW_real_double_REAL *D, LLW_CONST LLW_real_double_REAL *E, LLW_real_double_REAL VL, LLW_real_double_REAL VU, int IL, int IU, int *M, LLW_real_double_REAL* W, LLW_real_double_COMPLEX* Z, int LDZ, int* ISUPPZ) {
00069   /*
00070   fprintf(stderr, "llw_real_double_stegr: %c %c %d %p %p %g %g %d %d %p %p %p %d %p\n", jobz, range, N, (void*)D, (void*)E, VL, VU, IL, IU, (void*)M, (void*)W, (void*)Z, LDZ, (void*)ISUPPZ);
00071   */
00072   /*Now do our STEGR call*/
00073   /*NOTE e_in is of length N. We copy only N-1 (since E is N-1 values; it's the first subdiagonal. HOWEVER, e_in[N-1] (i.e., the Nth element) is used internally by LAPACK as a workspace, so we need it in here.*/
00074   LLW_real_double_REAL *e_in;
00075   LLW_real_double_REAL *d_in;
00076   #ifdef LLW_CONST
00077   e_in = malloc(N*sizeof(LLW_real_double_REAL));
00078   d_in = malloc(N*sizeof(LLW_real_double_REAL));
00079   if((e_in == NULL) || (d_in == NULL)) {
00080     if(e_in != NULL) free(e_in);
00081     if(d_in != NULL) free(d_in);
00082     return 100;
00083   }
00084   memcpy(e_in, E, (N-1)*sizeof(LLW_real_double_REAL));
00085   memcpy(d_in, D, N*sizeof(LLW_real_double_REAL));
00086   #else
00087   e_in = E;
00088   d_in = D;
00089   #endif
00090   /*Initialize our output storage*/
00091   /*
00092   *M = 0;
00093   for(int i=0; i<N; i++) {
00094     W[i] = 0;
00095     for(int j=0; j<LDZ; j++) {
00096       Z[j + i*LDZ] = 0;
00097     }
00098     ISUPPZ[2*i] = ISUPPZ[2*i + 1] = 0;
00099   }
00100   for(int i=0; i<N-1; i++) {
00101     fprintf(stderr, "d[%d]=", i);
00102     fprintf(stderr, "%g ", d_in[i]);
00103     fprintf(stderr, "e[%d]=", i);
00104     fprintf(stderr, "=%g\n", e_in[i]);
00105     fprintf(stderr, "D[%d]=", i);
00106     fprintf(stderr, "%g ", D[i]);
00107     fprintf(stderr, "E[%d]=", i);
00108     fprintf(stderr, "=%g\n", E[i]);
00109   }
00110   fprintf(stderr, "D[%d]=%g\n", N, D[N-1]);
00111   fprintf(stderr, "d[%d]=%g\n", N, d_in[N-1]);
00112   */
00113   /*First, query optimal work size*/
00114   /*
00115   for(int i=0; i<N; i++) {
00116     fprintf(stderr, "D[%d]=%g d_in=%g E=%g e_in=%g\n", 
00117       i, 
00118       D[i], 
00119       d_in[i], 
00120       E[i], 
00121       (i == (N-1))?0:e_in[1]);
00122   }
00123   */
00124   int info;
00125 #if LAPACK == ACML
00126   /*ACML's C interface doesn't require the work and iwork arrays.
00127    *So with ACML, we just dive right in.
00128    */
00129   STEGR(jobz, range, N, d_in, e_in, VL, VU, IL, IU, 1e-12, M, W, (LAPACK_COMPLEX_TYPENAME*)Z, LDZ, ISUPPZ, &info);
00130 #else
00131   /*The rest of the LAPACK implementations require work and iwork,
00132    *  so we'll query the optimal values before making the real call.
00133    */
00134   LLW_real_double_REAL opt_lwork;
00135   int opt_liwork;
00136 #ifdef FCALL
00137   /*Look at all the fun in a FORTRAN call. Whee!*/
00138   LLW_real_double_REAL EPSILON=1e-12;
00139   int MONE = -1;
00140   STEGR(&jobz, &range, &N, d_in, e_in, &VL, &VU, &IL, &IU, &EPSILON, M, W, (LAPACK_COMPLEX_TYPENAME*)Z, &LDZ, ISUPPZ, &opt_lwork, &MONE, &opt_liwork, &MONE, &info);
00141 #else
00142   STEGR(jobz, range, N, d_in, e_in, VL, VU, IL, IU, 1e-12, M, W, (LAPACK_COMPLEX_TYPENAME*)Z, LDZ, ISUPPZ, &opt_lwork, -1, &opt_liwork, -1, &info);
00143 #endif
00144   if(info != 0) {
00145     #ifdef LLW_CONST
00146     free(e_in);
00147     free(d_in);
00148     #endif
00149     return info;
00150   }
00151   LLW_real_double_REAL *work = malloc(sizeof(LLW_real_double_REAL)*((int)opt_lwork));
00152   int *iwork = malloc(sizeof(int)*opt_liwork);
00153   #ifdef FCALL
00154   int LWORK = opt_lwork;
00155   STEGR(&jobz, &range, &N, d_in, e_in, &VL, &VU, &IL, &IU, &EPSILON, M, W, (LAPACK_COMPLEX_TYPENAME*)Z, &LDZ, ISUPPZ, work, &LWORK, iwork, &opt_liwork, &info);
00156   #else
00157   STEGR(jobz, range, N, d_in, e_in, VL, VU, IL, IU, 1e-12, M, W, (LAPACK_COMPLEX_TYPENAME*)Z, LDZ, ISUPPZ, work, opt_lwork, iwork, opt_liwork, &info);
00158   #endif
00159   free(work);
00160   free(iwork);
00161   #endif
00162   #ifdef LLW_CONST
00163   free(e_in);
00164   free(d_in);
00165   #endif
00166   return info;
00167 }
00168 
00169 
00170 
00171 int llw_real_double_sbtrd_a(char vect, char uplo, int N, int KD, LLW_CONST LLW_real_double_COMPLEX* A, int LDAB, LLW_real_double_REAL** D, LLW_real_double_REAL **E, LLW_real_double_COMPLEX** Q) {
00172   *D = (LLW_real_double_REAL*)malloc(N*sizeof(LLW_real_double_REAL));
00173   if(*D == NULL) return 100;
00174   *E = (LLW_real_double_REAL*)malloc((N-1)*sizeof(LLW_real_double_REAL));
00175   if(*E == NULL) {
00176     free(D);
00177     return 100;
00178   }
00179   *Q = (LLW_real_double_COMPLEX*)malloc(N*N*sizeof(LLW_real_double_COMPLEX));
00180   if(*Q == NULL) {
00181     free(D);
00182     free(E);
00183     return 100;
00184   }
00185   return llw_real_double_sbtrd(vect, uplo, N, KD, A, LDAB, *D, *E, *Q, N);
00186 }
00187 
00188 int llw_real_double_sbtrd(char vect, char uplo, int N, int KD, LLW_CONST LLW_real_double_COMPLEX* AB, int LDAB, LLW_real_double_REAL* D, LLW_real_double_REAL* E, LLW_real_double_COMPLEX* Q, int LDQ) {
00189   LLW_real_double_COMPLEX *ab;
00190   #ifdef LLW_CONST
00191   ab = (LLW_real_double_COMPLEX*)malloc(N*(KD+1)*sizeof(LLW_real_double_COMPLEX));
00192   if(ab == NULL) return 100;
00193   memcpy(ab, AB, N*(KD+1)*sizeof(LLW_real_double_COMPLEX));
00194   #else
00195   ab = AB;
00196   #endif
00197   int info;
00198   #if LAPACK == ACML
00199   SBTRD(vect, uplo, N, KD, (LAPACK_COMPLEX_TYPENAME*)ab, LDAB, D, E,  (LAPACK_COMPLEX_TYPENAME*)Q, LDQ, &info);
00200   #else
00201   LLW_real_double_COMPLEX *work = (LLW_real_double_COMPLEX*)malloc(N*sizeof(LLW_real_double_COMPLEX));
00202   if(work == NULL) {
00203     #ifdef LLW_CONST
00204     free(ab);
00205     #endif
00206     return 100;
00207   }
00208   #ifdef FCALL
00209   SBTRD(&vect, &uplo, &N, &KD,  (LAPACK_COMPLEX_TYPENAME*)ab, &LDAB, D, E,  (LAPACK_COMPLEX_TYPENAME*)Q, &LDQ,  (LAPACK_COMPLEX_TYPENAME*)work, &info);
00210   #else
00211   SBTRD(vect, uplo, N, KD,  (LAPACK_COMPLEX_TYPENAME*)ab, LDAB, D, E,  (LAPACK_COMPLEX_TYPENAME*)Q, LDQ,  (LAPACK_COMPLEX_TYPENAME*)work, &info);
00212   #endif
00213   free(work);
00214   #endif
00215   return info;
00216 }
00217 
00218 
00219 
00220 /**LAPACK wrapper for DSYTRD.
00221  *\return the resulting INFO
00222  */
00223 int llw_real_double_sytrd(char uplo, int N, LLW_CONST LLW_real_double_COMPLEX* A, LLW_real_double_REAL* D, LLW_real_double_REAL* E, LLW_real_double_COMPLEX* TAU, LLW_real_double_COMPLEX** a_out) {
00224   LLW_real_double_COMPLEX **aa;
00225   LLW_real_double_COMPLEX *a;
00226   if(a_out != NULL) {
00227     a = *a_out;
00228   }else{
00229     /*Point aa to a LLW_real_double_COMPLEX pointer on the stack if the user doesn't want it*/
00230     aa = &a;
00231   }
00232   *aa = malloc(sizeof(LLW_real_double_COMPLEX)*N*N);
00233   if(a == NULL) return 100;
00234   memcpy(*aa, A, N*N*sizeof(LLW_real_double_COMPLEX));
00235   int info;
00236   #if LAPACK == ACML
00237   SYTRD(uplo, N,  (LAPACK_COMPLEX_TYPENAME*)*aa, N, D, E,  (LAPACK_COMPLEX_TYPENAME*)TAU, &info);
00238   #else
00239   LLW_real_double_COMPLEX opt_work;
00240   #ifdef FCALL
00241   int MONE = -1;
00242   SYTRD(&uplo, &N,  (LAPACK_COMPLEX_TYPENAME*)*aa, &N, D, E,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)&opt_work, &MONE, &info);
00243   #else
00244   SYTRD(uplo, N,  (LAPACK_COMPLEX_TYPENAME*)*aa, N, D, E,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)&opt_work, -1, &info);
00245   #endif
00246   if(info != 0) {
00247     if(a_out != NULL) free(a);
00248     return info;
00249   }
00250   int OWORK = (int)
00251       #ifdef LLW_real_double_IS_COMPLEX
00252               opt_work.re
00253       #else
00254               opt_work
00255             #endif
00256     ;
00257   LLW_real_double_COMPLEX* work = malloc(sizeof(LLW_real_double_COMPLEX)*(OWORK));
00258   #ifdef FCALL
00259   SYTRD(&uplo, &N,  (LAPACK_COMPLEX_TYPENAME*)*aa, &N, D, E,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)work, &OWORK, &info);
00260   #else
00261   SYTRD(uplo, N,  (LAPACK_COMPLEX_TYPENAME*)*aa, N, D, E,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)work, OWORK, &info);
00262   #endif
00263   #endif
00264   if(a_out != NULL) free(a);
00265   return info;
00266 }
00267 
00268 
00269 
00270 int llw_real_double_orgtr(char uplo, int N, LLW_real_double_COMPLEX* A, LLW_real_double_COMPLEX* TAU) {
00271   int info;
00272   #if LAPACK == ACML
00273   ORGTR(uplo, N, (LAPACK_COMPLEX_TYPENAME*)A, N, (LAPACK_COMPLEX_TYPENAME*)TAU, &info);
00274   #else
00275   LLW_real_double_COMPLEX opt_work;
00276   #ifdef FCALL
00277   int MONE = -1;
00278   ORGTR(&uplo, &N,  (LAPACK_COMPLEX_TYPENAME*)A, &N,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)&opt_work, &MONE, &info);
00279   #else
00280   ORGTR(uplo, N,  (LAPACK_COMPLEX_TYPENAME*)A, N,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)&opt_work, -1, &info);
00281   #endif
00282   if(info != 0) {
00283     return info;
00284   }
00285   int OWORK = (int)
00286       #ifdef LLW_real_double_IS_COMPLEX
00287               opt_work.re
00288       #else
00289               opt_work
00290             #endif
00291     ;
00292   LLW_real_double_COMPLEX* work = (LLW_real_double_COMPLEX*)malloc(sizeof(LLW_real_double_COMPLEX)*OWORK);
00293   #ifdef FCALL
00294   ORGTR(&uplo, &N,  (LAPACK_COMPLEX_TYPENAME*)A, &N,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)work, &OWORK, &info);
00295   #else
00296   ORGTR(uplo, N,  (LAPACK_COMPLEX_TYPENAME*)A, N,  (LAPACK_COMPLEX_TYPENAME*)TAU,  (LAPACK_COMPLEX_TYPENAME*)work, OWORK, &info);
00297   #endif
00298   #endif
00299   return info;
00300 }
00301 
00302 
00303 
 All Classes Files Functions Variables Defines