Subversion Repositories slepc-dev

Rev

Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 dsic.upv.es!jroman 1
/*                      
683 dsic.upv.es!jroman 2
     This file contains routines for handling small-size dense problems.
3
     All routines are simply wrappers to LAPACK routines. Matrices passed in
4
     as arguments are assumed to be square matrices stored in column-major
5
     format with a leading dimension equal to the number of rows.
1376 slepc 6
 
7
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8
      SLEPc - Scalable Library for Eigenvalue Problem Computations
9
      Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain
10
 
11
      This file is part of SLEPc. See the README file for conditions of use
12
      and additional information.
13
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6 dsic.upv.es!jroman 14
*/
1376 slepc 15
 
1521 slepc 16
#include "private/epsimpl.h" /*I "slepceps.h" I*/
6 dsic.upv.es!jroman 17
#include "slepcblaslapack.h"
18
 
19
#undef __FUNCT__  
681 dsic.upv.es!antodo 20
#define __FUNCT__ "EPSDenseNHEP"
6 dsic.upv.es!jroman 21
/*@
683 dsic.upv.es!jroman 22
   EPSDenseNHEP - Solves a dense standard non-Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 23
 
24
   Not Collective
25
 
26
   Input Parameters:
681 dsic.upv.es!antodo 27
+  n  - dimension of the eigenproblem
28
-  A  - pointer to the array containing the matrix values
6 dsic.upv.es!jroman 29
 
681 dsic.upv.es!antodo 30
   Output Parameters:
31
+  w  - pointer to the array to store the computed eigenvalues
32
.  wi - imaginary part of the eigenvalues (only when using real numbers)
780 dsic.upv.es!jroman 33
.  V  - pointer to the array to store right eigenvectors
34
-  W  - pointer to the array to store left eigenvectors
6 dsic.upv.es!jroman 35
 
36
   Notes:
780 dsic.upv.es!jroman 37
   If either V or W are PETSC_NULL then the corresponding eigenvectors are
38
   not computed.
6 dsic.upv.es!jroman 39
 
681 dsic.upv.es!antodo 40
   Matrix A is overwritten.
41
 
42
   This routine uses LAPACK routines xGEEVX.
43
 
6 dsic.upv.es!jroman 44
   Level: developer
45
 
681 dsic.upv.es!antodo 46
.seealso: EPSDenseGNHEP(), EPSDenseHEP(), EPSDenseGHEP()
6 dsic.upv.es!jroman 47
@*/
1509 slepc 48
PetscErrorCode EPSDenseNHEP(PetscInt n_,PetscScalar *A,PetscScalar *w,PetscScalar *wi,PetscScalar *V,PetscScalar *W)
6 dsic.upv.es!jroman 49
{
806 dsic.upv.es!antodo 50
#if defined(SLEPC_MISSING_LAPACK_GEEVX)
817 dsic.upv.es!antodo 51
  PetscFunctionBegin;
806 dsic.upv.es!antodo 52
  SETERRQ(PETSC_ERR_SUP,"GEEVX - Lapack routine is unavailable.");
53
#else
476 dsic.upv.es!antodo 54
  PetscErrorCode ierr;
982 slepc 55
  PetscReal      abnrm,*scale,dummy;
681 dsic.upv.es!antodo 56
  PetscScalar    *work;
1642 slepc 57
  PetscBLASInt   ilo,ihi,n,lwork,info;
1004 slepc 58
  const char     *jobvr,*jobvl;
681 dsic.upv.es!antodo 59
#if defined(PETSC_USE_COMPLEX)
60
  PetscReal      *rwork;
982 slepc 61
#else
1509 slepc 62
  PetscBLASInt   idummy;
681 dsic.upv.es!antodo 63
#endif
6 dsic.upv.es!jroman 64
 
74 dsic.upv.es!antodo 65
  PetscFunctionBegin;
1339 slepc 66
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 67
  n = PetscBLASIntCast(n_);
68
  lwork = PetscBLASIntCast(4*n_);
681 dsic.upv.es!antodo 69
  if (V) jobvr = "V";
70
  else jobvr = "N";
780 dsic.upv.es!jroman 71
  if (W) jobvl = "V";
72
  else jobvl = "N";
681 dsic.upv.es!antodo 73
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
74
  ierr  = PetscMalloc(n*sizeof(PetscReal),&scale);CHKERRQ(ierr);
6 dsic.upv.es!jroman 75
#if defined(PETSC_USE_COMPLEX)
681 dsic.upv.es!antodo 76
  ierr  = PetscMalloc(2*n*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
1536 slepc 77
  LAPACKgeevx_("B",jobvl,jobvr,"N",&n,A,&n,w,W,&n,V,&n,&ilo,&ihi,scale,&abnrm,&dummy,&dummy,work,&lwork,rwork,&info);
982 slepc 78
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZGEEVX %d",info);
681 dsic.upv.es!antodo 79
  ierr = PetscFree(rwork);CHKERRQ(ierr);
6 dsic.upv.es!jroman 80
#else
1536 slepc 81
  LAPACKgeevx_("B",jobvl,jobvr,"N",&n,A,&n,w,wi,W,&n,V,&n,&ilo,&ihi,scale,&abnrm,&dummy,&dummy,work,&lwork,&idummy,&info);
982 slepc 82
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DGEEVX %d",info);
681 dsic.upv.es!antodo 83
#endif
84
  ierr = PetscFree(work);CHKERRQ(ierr);
85
  ierr = PetscFree(scale);CHKERRQ(ierr);
1339 slepc 86
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
6 dsic.upv.es!jroman 87
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 88
#endif
6 dsic.upv.es!jroman 89
}
90
 
91
#undef __FUNCT__  
681 dsic.upv.es!antodo 92
#define __FUNCT__ "EPSDenseGNHEP"
6 dsic.upv.es!jroman 93
/*@
683 dsic.upv.es!jroman 94
   EPSDenseGNHEP - Solves a dense Generalized non-Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 95
 
96
   Not Collective
97
 
545 dsic.upv.es!jroman 98
   Input Parameters:
6 dsic.upv.es!jroman 99
+  n  - dimension of the eigenproblem
681 dsic.upv.es!antodo 100
.  A  - pointer to the array containing the matrix values for A
101
-  B  - pointer to the array containing the matrix values for B
6 dsic.upv.es!jroman 102
 
103
   Output Parameters:
104
+  w  - pointer to the array to store the computed eigenvalues
105
.  wi - imaginary part of the eigenvalues (only when using real numbers)
780 dsic.upv.es!jroman 106
.  V  - pointer to the array to store right eigenvectors
107
-  W  - pointer to the array to store left eigenvectors
6 dsic.upv.es!jroman 108
 
109
   Notes:
780 dsic.upv.es!jroman 110
   If either V or W are PETSC_NULL then the corresponding eigenvectors are
111
   not computed.
6 dsic.upv.es!jroman 112
 
683 dsic.upv.es!jroman 113
   Matrices A and B are overwritten.
6 dsic.upv.es!jroman 114
 
681 dsic.upv.es!antodo 115
   This routine uses LAPACK routines xGGEVX.
6 dsic.upv.es!jroman 116
 
117
   Level: developer
118
 
681 dsic.upv.es!antodo 119
.seealso: EPSDenseNHEP(), EPSDenseHEP(), EPSDenseGHEP()
6 dsic.upv.es!jroman 120
@*/
1509 slepc 121
PetscErrorCode EPSDenseGNHEP(PetscInt n_,PetscScalar *A,PetscScalar *B,PetscScalar *w,PetscScalar *wi,PetscScalar *V,PetscScalar *W)
6 dsic.upv.es!jroman 122
{
806 dsic.upv.es!antodo 123
#if defined(SLEPC_MISSING_LAPACK_GGEVX)
817 dsic.upv.es!antodo 124
  PetscFunctionBegin;
806 dsic.upv.es!antodo 125
  SETERRQ(PETSC_ERR_SUP,"GGEVX - Lapack routine is unavailable.");
126
#else
476 dsic.upv.es!antodo 127
  PetscErrorCode ierr;
982 slepc 128
  PetscReal      *rscale,*lscale,abnrm,bbnrm,dummy;
681 dsic.upv.es!antodo 129
  PetscScalar    *alpha,*beta,*work;
1512 slepc 130
  PetscInt       i;
1642 slepc 131
  PetscBLASInt   ilo,ihi,idummy,info,n;
1004 slepc 132
  const char     *jobvr,*jobvl;
681 dsic.upv.es!antodo 133
#if defined(PETSC_USE_COMPLEX)
134
  PetscReal      *rwork;
1642 slepc 135
  PetscBLASInt   lwork;
681 dsic.upv.es!antodo 136
#else
137
  PetscReal      *alphai;
1642 slepc 138
  PetscBLASInt   lwork;
681 dsic.upv.es!antodo 139
#endif
6 dsic.upv.es!jroman 140
 
681 dsic.upv.es!antodo 141
  PetscFunctionBegin;
1339 slepc 142
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 143
  n = PetscBLASIntCast(n_);
144
#if defined(PETSC_USE_COMPLEX)
145
  lwork = PetscBLASIntCast(2*n_);
146
#else
147
  lwork = PetscBLASIntCast(6*n_);
148
#endif
681 dsic.upv.es!antodo 149
  if (V) jobvr = "V";
150
  else jobvr = "N";
780 dsic.upv.es!jroman 151
  if (W) jobvl = "V";
152
  else jobvl = "N";
681 dsic.upv.es!antodo 153
  ierr  = PetscMalloc(n*sizeof(PetscScalar),&alpha);CHKERRQ(ierr);
154
  ierr  = PetscMalloc(n*sizeof(PetscScalar),&beta);CHKERRQ(ierr);
155
  ierr  = PetscMalloc(n*sizeof(PetscReal),&rscale);CHKERRQ(ierr);
156
  ierr  = PetscMalloc(n*sizeof(PetscReal),&lscale);CHKERRQ(ierr);
157
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
158
#if defined(PETSC_USE_COMPLEX)
159
  ierr  = PetscMalloc(6*n*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
1536 slepc 160
  LAPACKggevx_("B",jobvl,jobvr,"N",&n,A,&n,B,&n,alpha,beta,W,&n,V,&n,&ilo,&ihi,lscale,rscale,&abnrm,&bbnrm,&dummy,&dummy,work,&lwork,rwork,&idummy,&idummy,&info);
982 slepc 161
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZGGEVX %d",info);
681 dsic.upv.es!antodo 162
  for (i=0;i<n;i++) {
163
    w[i] = alpha[i]/beta[i];
164
  }
165
  ierr = PetscFree(rwork);CHKERRQ(ierr);
6 dsic.upv.es!jroman 166
#else
681 dsic.upv.es!antodo 167
  ierr  = PetscMalloc(n*sizeof(PetscReal),&alphai);CHKERRQ(ierr);
1536 slepc 168
  LAPACKggevx_("B",jobvl,jobvr,"N",&n,A,&n,B,&n,alpha,alphai,beta,W,&n,V,&n,&ilo,&ihi,lscale,rscale,&abnrm,&bbnrm,&dummy,&dummy,work,&lwork,&idummy,&idummy,&info);
982 slepc 169
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DGGEVX %d",info);
681 dsic.upv.es!antodo 170
  for (i=0;i<n;i++) {
171
    w[i] = alpha[i]/beta[i];
172
    wi[i] = alphai[i]/beta[i];
173
  }
174
  ierr = PetscFree(alphai);CHKERRQ(ierr);
175
#endif
176
  ierr = PetscFree(alpha);CHKERRQ(ierr);
177
  ierr = PetscFree(beta);CHKERRQ(ierr);
178
  ierr = PetscFree(rscale);CHKERRQ(ierr);
179
  ierr = PetscFree(lscale);CHKERRQ(ierr);
6 dsic.upv.es!jroman 180
  ierr = PetscFree(work);CHKERRQ(ierr);
1339 slepc 181
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
681 dsic.upv.es!antodo 182
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 183
#endif
681 dsic.upv.es!antodo 184
}
6 dsic.upv.es!jroman 185
 
681 dsic.upv.es!antodo 186
#undef __FUNCT__  
187
#define __FUNCT__ "EPSDenseHEP"
188
/*@
683 dsic.upv.es!jroman 189
   EPSDenseHEP - Solves a dense standard Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 190
 
681 dsic.upv.es!antodo 191
   Not Collective
6 dsic.upv.es!jroman 192
 
681 dsic.upv.es!antodo 193
   Input Parameters:
1175 slepc 194
+  n   - dimension of the eigenproblem
195
.  A   - pointer to the array containing the matrix values
196
-  lda - leading dimension of A
6 dsic.upv.es!jroman 197
 
681 dsic.upv.es!antodo 198
   Output Parameters:
199
+  w  - pointer to the array to store the computed eigenvalues
200
-  V  - pointer to the array to store the eigenvectors
201
 
202
   Notes:
203
   If V is PETSC_NULL then the eigenvectors are not computed.
204
 
205
   Matrix A is overwritten.
206
 
207
   This routine uses LAPACK routines DSYEVR or ZHEEVR.
208
 
209
   Level: developer
210
 
211
.seealso: EPSDenseNHEP(), EPSDenseGNHEP(), EPSDenseGHEP()
212
@*/
1509 slepc 213
PetscErrorCode EPSDenseHEP(PetscInt n_,PetscScalar *A,PetscInt lda_,PetscReal *w,PetscScalar *V)
681 dsic.upv.es!antodo 214
{
806 dsic.upv.es!antodo 215
#if defined(SLEPC_MISSING_LAPACK_SYEVR) || defined(SLEPC_MISSING_LAPACK_HEEVR)
817 dsic.upv.es!antodo 216
  PetscFunctionBegin;
806 dsic.upv.es!antodo 217
  SETERRQ(PETSC_ERR_SUP,"DSYEVR/ZHEEVR - Lapack routine is unavailable.");
218
#else
681 dsic.upv.es!antodo 219
  PetscErrorCode ierr;
982 slepc 220
  PetscReal      abstol = 0.0,vl,vu;
681 dsic.upv.es!antodo 221
  PetscScalar    *work;
1642 slepc 222
  PetscBLASInt   il,iu,m,*isuppz,*iwork,n,lda,liwork,info;
1004 slepc 223
  const char     *jobz;
681 dsic.upv.es!antodo 224
#if defined(PETSC_USE_COMPLEX)
225
  PetscReal      *rwork;
1642 slepc 226
  PetscBLASInt   lwork,lrwork;
6 dsic.upv.es!jroman 227
#else
1642 slepc 228
  PetscBLASInt   lwork;
681 dsic.upv.es!antodo 229
#endif
6 dsic.upv.es!jroman 230
 
231
  PetscFunctionBegin;
1339 slepc 232
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 233
  n = PetscBLASIntCast(n_);
234
  lda = PetscBLASIntCast(lda_);
235
  liwork = PetscBLASIntCast(10*n_);
236
#if defined(PETSC_USE_COMPLEX)
237
  lwork = PetscBLASIntCast(18*n_);
238
  lrwork = PetscBLASIntCast(24*n_);
239
#else
240
  lwork = PetscBLASIntCast(26*n_);
241
#endif
681 dsic.upv.es!antodo 242
  if (V) jobz = "V";
243
  else jobz = "N";
1509 slepc 244
  ierr  = PetscMalloc(2*n*sizeof(PetscBLASInt),&isuppz);CHKERRQ(ierr);
681 dsic.upv.es!antodo 245
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1509 slepc 246
  ierr  = PetscMalloc(liwork*sizeof(PetscBLASInt),&iwork);CHKERRQ(ierr);
681 dsic.upv.es!antodo 247
#if defined(PETSC_USE_COMPLEX)
248
  ierr  = PetscMalloc(lrwork*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
1536 slepc 249
  LAPACKsyevr_(jobz,"A","L",&n,A,&lda,&vl,&vu,&il,&iu,&abstol,&m,w,V,&n,isuppz,work,&lwork,rwork,&lrwork,iwork,&liwork,&info);
681 dsic.upv.es!antodo 250
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZHEEVR %d",info);
6 dsic.upv.es!jroman 251
  ierr = PetscFree(rwork);CHKERRQ(ierr);
681 dsic.upv.es!antodo 252
#else
1536 slepc 253
  LAPACKsyevr_(jobz,"A","L",&n,A,&lda,&vl,&vu,&il,&iu,&abstol,&m,w,V,&n,isuppz,work,&lwork,iwork,&liwork,&info);
681 dsic.upv.es!antodo 254
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DSYEVR %d",info);
6 dsic.upv.es!jroman 255
#endif
681 dsic.upv.es!antodo 256
  ierr = PetscFree(isuppz);CHKERRQ(ierr);
257
  ierr = PetscFree(work);CHKERRQ(ierr);
258
  ierr = PetscFree(iwork);CHKERRQ(ierr);
1339 slepc 259
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
6 dsic.upv.es!jroman 260
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 261
#endif
6 dsic.upv.es!jroman 262
}
263
 
264
#undef __FUNCT__  
681 dsic.upv.es!antodo 265
#define __FUNCT__ "EPSDenseGHEP"
6 dsic.upv.es!jroman 266
/*@
683 dsic.upv.es!jroman 267
   EPSDenseGHEP - Solves a dense Generalized Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 268
 
269
   Not Collective
270
 
545 dsic.upv.es!jroman 271
   Input Parameters:
6 dsic.upv.es!jroman 272
+  n  - dimension of the eigenproblem
681 dsic.upv.es!antodo 273
.  A  - pointer to the array containing the matrix values for A
274
-  B  - pointer to the array containing the matrix values for B
6 dsic.upv.es!jroman 275
 
276
   Output Parameters:
277
+  w  - pointer to the array to store the computed eigenvalues
278
-  V  - pointer to the array to store the eigenvectors
279
 
280
   Notes:
172 dsic.upv.es!jroman 281
   If V is PETSC_NULL then the eigenvectors are not computed.
6 dsic.upv.es!jroman 282
 
683 dsic.upv.es!jroman 283
   Matrices A and B are overwritten.
681 dsic.upv.es!antodo 284
 
285
   This routine uses LAPACK routines DSYGVD or ZHEGVD.
6 dsic.upv.es!jroman 286
 
287
   Level: developer
288
 
681 dsic.upv.es!antodo 289
.seealso: EPSDenseNHEP(), EPSDenseGNHEP(), EPSDenseHEP()
6 dsic.upv.es!jroman 290
@*/
1509 slepc 291
PetscErrorCode EPSDenseGHEP(PetscInt n_,PetscScalar *A,PetscScalar *B,PetscReal *w,PetscScalar *V)
6 dsic.upv.es!jroman 292
{
806 dsic.upv.es!antodo 293
#if defined(SLEPC_MISSING_LAPACK_SYGVD) || defined(SLEPC_MISSING_LAPACK_HEGVD)
817 dsic.upv.es!antodo 294
  PetscFunctionBegin;
806 dsic.upv.es!antodo 295
  SETERRQ(PETSC_ERR_SUP,"DSYGVD/ZHEGVD - Lapack routine is unavailable.");
296
#else
476 dsic.upv.es!antodo 297
  PetscErrorCode ierr;
681 dsic.upv.es!antodo 298
  PetscScalar    *work;
1642 slepc 299
  PetscBLASInt   itype = 1,*iwork,info,n,
300
                 liwork;
1004 slepc 301
  const char     *jobz;
681 dsic.upv.es!antodo 302
#if defined(PETSC_USE_COMPLEX)
303
  PetscReal      *rwork;
1642 slepc 304
  PetscBLASInt   lwork,lrwork;
681 dsic.upv.es!antodo 305
#else
1642 slepc 306
  PetscBLASInt   lwork;
681 dsic.upv.es!antodo 307
#endif
6 dsic.upv.es!jroman 308
 
309
  PetscFunctionBegin;
1339 slepc 310
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 311
  n = PetscBLASIntCast(n_);
312
  if (V) {
313
    jobz = "V";
314
    liwork = PetscBLASIntCast(5*n_+3);
315
#if defined(PETSC_USE_COMPLEX)
316
    lwork  = PetscBLASIntCast(n_*n_+2*n_);
1660 slepc 317
    lrwork = PetscBLASIntCast(2*n_*n_+5*n_+1);
1642 slepc 318
#else
319
    lwork  = PetscBLASIntCast(2*n_*n_+6*n_+1);
320
#endif
321
  } else {
322
    jobz = "N";  
323
    liwork = 1;
324
#if defined(PETSC_USE_COMPLEX)
325
    lwork  = PetscBLASIntCast(n_+1);
326
    lrwork = PetscBLASIntCast(n_);
327
#else
328
    lwork  = PetscBLASIntCast(2*n_+1);
329
#endif
330
  }
681 dsic.upv.es!antodo 331
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1509 slepc 332
  ierr  = PetscMalloc(liwork*sizeof(PetscBLASInt),&iwork);CHKERRQ(ierr);
681 dsic.upv.es!antodo 333
#if defined(PETSC_USE_COMPLEX)
334
  ierr  = PetscMalloc(lrwork*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
1536 slepc 335
  LAPACKsygvd_(&itype,jobz,"U",&n,A,&n,B,&n,w,work,&lwork,rwork,&lrwork,iwork,&liwork,&info);
735 dsic.upv.es!antodo 336
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZHEGVD %d",info);
681 dsic.upv.es!antodo 337
  ierr = PetscFree(rwork);CHKERRQ(ierr);
338
#else
1536 slepc 339
  LAPACKsygvd_(&itype,jobz,"U",&n,A,&n,B,&n,w,work,&lwork,iwork,&liwork,&info);
735 dsic.upv.es!antodo 340
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DSYGVD %d",info);
681 dsic.upv.es!antodo 341
#endif
6 dsic.upv.es!jroman 342
  if (V) {
681 dsic.upv.es!antodo 343
    ierr = PetscMemcpy(V,A,n*n*sizeof(PetscScalar));CHKERRQ(ierr);
6 dsic.upv.es!jroman 344
  }
681 dsic.upv.es!antodo 345
  ierr = PetscFree(work);CHKERRQ(ierr);
346
  ierr = PetscFree(iwork);CHKERRQ(ierr);
1339 slepc 347
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
6 dsic.upv.es!jroman 348
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 349
#endif
6 dsic.upv.es!jroman 350
}
351
 
461 dsic.upv.es!antodo 352
#undef __FUNCT__  
1175 slepc 353
#define __FUNCT__ "EPSDenseHessenberg"
354
/*@
355
   EPSDenseHessenberg - Computes the Hessenberg form of a dense matrix.
356
 
357
   Not Collective
358
 
359
   Input Parameters:
360
+  n     - dimension of the matrix
361
.  k     - first active column
362
-  lda   - leading dimension of A
363
 
364
   Input/Output Parameters:
365
+  A  - on entry, the full matrix; on exit, the upper Hessenberg matrix (H)
366
-  Q  - on exit, orthogonal matrix of vectors A = Q*H*Q'
367
 
368
   Notes:
369
   Only active columns (from k to n) are computed.
370
 
371
   Both A and Q are overwritten.
372
 
373
   This routine uses LAPACK routines xGEHRD and xORGHR/xUNGHR.
374
 
375
   Level: developer
376
 
377
.seealso: EPSDenseSchur(), EPSSortDenseSchur(), EPSDenseTridiagonal()
378
@*/
1509 slepc 379
PetscErrorCode EPSDenseHessenberg(PetscInt n_,PetscInt k,PetscScalar *A,PetscInt lda_,PetscScalar *Q)
1175 slepc 380
{
381
#if defined(SLEPC_MISSING_LAPACK_GEHRD) || defined(SLEPC_MISSING_LAPACK_ORGHR) || defined(SLEPC_MISSING_LAPACK_UNGHR)
382
  PetscFunctionBegin;
383
  SETERRQ(PETSC_ERR_SUP,"GEHRD,ORGHR/UNGHR - Lapack routines are unavailable.");
384
#else
385
  PetscScalar    *tau,*work;
386
  PetscErrorCode ierr;
1512 slepc 387
  PetscInt       i,j;
1642 slepc 388
  PetscBLASInt   ilo,lwork,info,n,lda;
1175 slepc 389
 
390
  PetscFunctionBegin;
1339 slepc 391
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 392
  n = PetscBLASIntCast(n_);
393
  lda = PetscBLASIntCast(lda_);
1175 slepc 394
  ierr = PetscMalloc(n*sizeof(PetscScalar),&tau);CHKERRQ(ierr);
1644 slepc 395
  lwork = n;
1175 slepc 396
  ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1642 slepc 397
  ilo = PetscBLASIntCast(k+1);
1175 slepc 398
  LAPACKgehrd_(&n,&ilo,&n,A,&lda,tau,work,&lwork,&info);
399
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xGEHRD %d",info);
400
  for (j=0;j<n-1;j++) {
401
    for (i=j+2;i<n;i++) {
402
      Q[i+j*n] = A[i+j*lda];
403
      A[i+j*lda] = 0.0;
404
    }      
405
  }
406
  LAPACKorghr_(&n,&ilo,&n,Q,&n,tau,work,&lwork,&info);
407
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xORGHR %d",info);
408
  ierr = PetscFree(tau);CHKERRQ(ierr);
409
  ierr = PetscFree(work);CHKERRQ(ierr);
1339 slepc 410
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1175 slepc 411
  PetscFunctionReturn(0);
412
#endif
413
}
414
 
415
#undef __FUNCT__  
461 dsic.upv.es!antodo 416
#define __FUNCT__ "EPSDenseSchur"
545 dsic.upv.es!jroman 417
/*@
418
   EPSDenseSchur - Computes the upper (quasi-)triangular form of a dense
419
   upper Hessenberg matrix.
420
 
421
   Not Collective
422
 
423
   Input Parameters:
1059 slepc 424
+  n   - dimension of the matrix
425
.  k   - first active column
426
-  ldh - leading dimension of H
545 dsic.upv.es!jroman 427
 
428
   Input/Output Parameters:
429
+  H  - on entry, the upper Hessenber matrix; on exit, the upper
430
        (quasi-)triangular matrix (T)
431
-  Z  - on entry, initial transformation matrix; on exit, orthogonal
432
        matrix of Schur vectors
433
 
434
   Output Parameters:
435
+  wr - pointer to the array to store the computed eigenvalues
436
-  wi - imaginary part of the eigenvalues (only when using real numbers)
437
 
438
   Notes:
439
   This function computes the (real) Schur decomposition of an upper
440
   Hessenberg matrix H: H*Z = Z*T,  where T is an upper (quasi-)triangular
441
   matrix (returned in H), and Z is the orthogonal matrix of Schur vectors.
442
   Eigenvalues are extracted from the diagonal blocks of T and returned in
443
   wr,wi. Transformations are accumulated in Z so that on entry it can
444
   contain the transformation matrix associated to the Hessenberg reduction.
445
 
446
   Only active columns (from k to n) are computed.
447
 
448
   Both H and Z are overwritten.
449
 
450
   This routine uses LAPACK routines xHSEQR.
451
 
452
   Level: developer
453
 
1175 slepc 454
.seealso: EPSDenseHessenberg(), EPSSortDenseSchur(), EPSDenseTridiagonal()
545 dsic.upv.es!jroman 455
@*/
1509 slepc 456
PetscErrorCode EPSDenseSchur(PetscInt n_,PetscInt k,PetscScalar *H,PetscInt ldh_,PetscScalar *Z,PetscScalar *wr,PetscScalar *wi)
461 dsic.upv.es!antodo 457
{
806 dsic.upv.es!antodo 458
#if defined(SLEPC_MISSING_LAPACK_HSEQR)
817 dsic.upv.es!antodo 459
  PetscFunctionBegin;
806 dsic.upv.es!antodo 460
  SETERRQ(PETSC_ERR_SUP,"HSEQR - Lapack routine is unavailable.");
461
#else
476 dsic.upv.es!antodo 462
  PetscErrorCode ierr;
1642 slepc 463
  PetscBLASInt   ilo,lwork,info,n,ldh;
1512 slepc 464
  PetscScalar    *work;
551 dsic.upv.es!antodo 465
#if !defined(PETSC_USE_COMPLEX)
1512 slepc 466
  PetscInt       j;
551 dsic.upv.es!antodo 467
#endif
461 dsic.upv.es!antodo 468
 
469
  PetscFunctionBegin;
1339 slepc 470
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 471
  n = PetscBLASIntCast(n_);
472
  ldh = PetscBLASIntCast(ldh_);
1644 slepc 473
  lwork = n;
461 dsic.upv.es!antodo 474
  ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1642 slepc 475
  ilo = PetscBLASIntCast(k+1);
461 dsic.upv.es!antodo 476
#if !defined(PETSC_USE_COMPLEX)
1536 slepc 477
  LAPACKhseqr_("S","V",&n,&ilo,&n,H,&ldh,wr,wi,Z,&n,work,&lwork,&info);
551 dsic.upv.es!antodo 478
  for (j=0;j<k;j++) {
1057 slepc 479
    if (j==n-1 || H[j*ldh+j+1] == 0.0) {
551 dsic.upv.es!antodo 480
      /* real eigenvalue */
1057 slepc 481
      wr[j] = H[j*ldh+j];
551 dsic.upv.es!antodo 482
      wi[j] = 0.0;
483
    } else {
484
      /* complex eigenvalue */
1057 slepc 485
      wr[j] = H[j*ldh+j];
486
      wr[j+1] = H[j*ldh+j];
487
      wi[j] = sqrt(PetscAbsReal(H[j*ldh+j+1])) *
488
              sqrt(PetscAbsReal(H[(j+1)*ldh+j]));
551 dsic.upv.es!antodo 489
      wi[j+1] = -wi[j];
490
      j++;
491
    }
492
  }
461 dsic.upv.es!antodo 493
#else
1536 slepc 494
  LAPACKhseqr_("S","V",&n,&ilo,&n,H,&ldh,wr,Z,&n,work,&lwork,&info);
461 dsic.upv.es!antodo 495
#endif
476 dsic.upv.es!antodo 496
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xHSEQR %d",info);
461 dsic.upv.es!antodo 497
 
515 dsic.upv.es!antodo 498
  ierr = PetscFree(work);CHKERRQ(ierr);
1339 slepc 499
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
515 dsic.upv.es!antodo 500
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 501
#endif
515 dsic.upv.es!antodo 502
}
503
 
504
#undef __FUNCT__  
505
#define __FUNCT__ "EPSSortDenseSchur"
545 dsic.upv.es!jroman 506
/*@
507
   EPSSortDenseSchur - Reorders the Schur decomposition computed by
508
   EPSDenseSchur().
509
 
510
   Not Collective
511
 
512
   Input Parameters:
1180 slepc 513
+  n     - dimension of the matrix
514
.  k     - first active column
515
.  ldt   - leading dimension of T
516
-  which - eigenvalue sort order
545 dsic.upv.es!jroman 517
 
518
   Input/Output Parameters:
519
+  T  - the upper (quasi-)triangular matrix
1427 slepc 520
.  Z  - the orthogonal matrix of Schur vectors
521
.  wr - pointer to the array to store the computed eigenvalues
545 dsic.upv.es!jroman 522
-  wi - imaginary part of the eigenvalues (only when using real numbers)
523
 
524
   Notes:
525
   This function reorders the eigenvalues in wr,wi located in positions k
1180 slepc 526
   to n according to the sort order specified in which. The Schur
527
   decomposition Z*T*Z^T, is also reordered by means of rotations so that
528
   eigenvalues in the diagonal blocks of T follow the same order.
545 dsic.upv.es!jroman 529
 
530
   Both T and Z are overwritten.
531
 
532
   This routine uses LAPACK routines xTREXC.
533
 
534
   Level: developer
535
 
1175 slepc 536
.seealso: EPSDenseHessenberg(), EPSDenseSchur(), EPSDenseTridiagonal()
545 dsic.upv.es!jroman 537
@*/
1509 slepc 538
PetscErrorCode EPSSortDenseSchur(PetscInt n_,PetscInt k,PetscScalar *T,PetscInt ldt_,PetscScalar *Z,PetscScalar *wr,PetscScalar *wi,EPSWhich which)
515 dsic.upv.es!antodo 539
{
806 dsic.upv.es!antodo 540
#if defined(SLEPC_MISSING_LAPACK_TREXC)
817 dsic.upv.es!antodo 541
  PetscFunctionBegin;
806 dsic.upv.es!antodo 542
  SETERRQ(PETSC_ERR_SUP,"TREXC - Lapack routine is unavailable.");
543
#else
1512 slepc 544
  PetscErrorCode ierr;
545
  PetscReal      value,v;
546
  PetscInt       i,j;
1642 slepc 547
  PetscBLASInt   ifst,ilst,info,pos,n,ldt;
515 dsic.upv.es!antodo 548
#if !defined(PETSC_USE_COMPLEX)
1512 slepc 549
  PetscScalar    *work;
515 dsic.upv.es!antodo 550
#endif
551
 
552
  PetscFunctionBegin;
1339 slepc 553
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 554
  n = PetscBLASIntCast(n_);
555
  ldt = PetscBLASIntCast(ldt_);
515 dsic.upv.es!antodo 556
#if !defined(PETSC_USE_COMPLEX)
557
  ierr = PetscMalloc(n*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1174 slepc 558
#endif
738 dsic.upv.es!antodo 559
 
461 dsic.upv.es!antodo 560
  for (i=k;i<n-1;i++) {
1174 slepc 561
    switch(which) {
562
      case EPS_LARGEST_MAGNITUDE:
563
      case EPS_SMALLEST_MAGNITUDE:
564
        value = SlepcAbsEigenvalue(wr[i],wi[i]);
565
        break;
566
      case EPS_LARGEST_REAL:
567
      case EPS_SMALLEST_REAL:
568
        value = PetscRealPart(wr[i]);
569
        break;
570
      case EPS_LARGEST_IMAGINARY:
571
      case EPS_SMALLEST_IMAGINARY:
572
#if !defined(PETSC_USE_COMPLEX)
573
        value = PetscAbsReal(wi[i]);
574
#else
575
        value = PetscImaginaryPart(wr[i]);
576
#endif
577
        break;
578
      default: SETERRQ(1,"Wrong value of which");
579
    }
580
    pos = 0;
461 dsic.upv.es!antodo 581
    for (j=i+1;j<n;j++) {
1174 slepc 582
      switch(which) {
583
        case EPS_LARGEST_MAGNITUDE:
584
        case EPS_SMALLEST_MAGNITUDE:
585
          v = SlepcAbsEigenvalue(wr[j],wi[j]);
586
          break;
587
        case EPS_LARGEST_REAL:
588
        case EPS_SMALLEST_REAL:
589
          v = PetscRealPart(wr[j]);
590
          break;
591
        case EPS_LARGEST_IMAGINARY:
592
        case EPS_SMALLEST_IMAGINARY:
593
#if !defined(PETSC_USE_COMPLEX)
594
          v = PetscAbsReal(wi[j]);
595
#else
596
          v = PetscImaginaryPart(wr[j]);
597
#endif
598
          break;
599
        default: SETERRQ(1,"Wrong value of which");
461 dsic.upv.es!antodo 600
      }
1174 slepc 601
      switch(which) {
602
        case EPS_LARGEST_MAGNITUDE:
603
        case EPS_LARGEST_REAL:
604
        case EPS_LARGEST_IMAGINARY:
605
          if (v > value) {
606
            value = v;
607
            pos = j;
608
          }
609
          break;
610
        case EPS_SMALLEST_MAGNITUDE:
611
        case EPS_SMALLEST_REAL:
612
        case EPS_SMALLEST_IMAGINARY:
613
          if (v < value) {
614
            value = v;
615
            pos = j;
616
          }
617
          break;
618
        default: SETERRQ(1,"Wrong value of which");
619
      }
620
#if !defined(PETSC_USE_COMPLEX)
461 dsic.upv.es!antodo 621
      if (wi[j] != 0) j++;
1174 slepc 622
#endif
461 dsic.upv.es!antodo 623
    }
1174 slepc 624
    if (pos) {
1642 slepc 625
      ifst = PetscBLASIntCast(pos + 1);
626
      ilst = PetscBLASIntCast(i + 1);
1174 slepc 627
#if !defined(PETSC_USE_COMPLEX)
1536 slepc 628
      LAPACKtrexc_("V",&n,T,&ldt,Z,&n,&ifst,&ilst,work,&info);
1174 slepc 629
#else
1536 slepc 630
      LAPACKtrexc_("V",&n,T,&ldt,Z,&n,&ifst,&ilst,&info);
1174 slepc 631
#endif
476 dsic.upv.es!antodo 632
      if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xTREXC %d",info);
738 dsic.upv.es!antodo 633
 
545 dsic.upv.es!jroman 634
      for (j=k;j<n;j++) {
1174 slepc 635
#if !defined(PETSC_USE_COMPLEX)
1057 slepc 636
        if (j==n-1 || T[j*ldt+j+1] == 0.0) {
545 dsic.upv.es!jroman 637
          /* real eigenvalue */
1057 slepc 638
          wr[j] = T[j*ldt+j];
545 dsic.upv.es!jroman 639
          wi[j] = 0.0;
640
        } else {
641
          /* complex eigenvalue */
1057 slepc 642
          wr[j] = T[j*ldt+j];
643
          wr[j+1] = T[j*ldt+j];
644
          wi[j] = sqrt(PetscAbsReal(T[j*ldt+j+1])) *
645
                  sqrt(PetscAbsReal(T[(j+1)*ldt+j]));
551 dsic.upv.es!antodo 646
          wi[j+1] = -wi[j];
545 dsic.upv.es!jroman 647
          j++;
648
        }
1174 slepc 649
#else
650
        wr[j] = T[j*(ldt+1)];
651
#endif
545 dsic.upv.es!jroman 652
      }
738 dsic.upv.es!antodo 653
    }
1174 slepc 654
#if !defined(PETSC_USE_COMPLEX)
738 dsic.upv.es!antodo 655
    if (wi[i] != 0) i++;
1174 slepc 656
#endif
738 dsic.upv.es!antodo 657
  }
658
 
1174 slepc 659
#if !defined(PETSC_USE_COMPLEX)
738 dsic.upv.es!antodo 660
  ierr = PetscFree(work);CHKERRQ(ierr);
461 dsic.upv.es!antodo 661
#endif
1339 slepc 662
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
461 dsic.upv.es!antodo 663
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 664
 
665
#endif
461 dsic.upv.es!antodo 666
}
1175 slepc 667
 
668
#undef __FUNCT__  
1428 slepc 669
#define __FUNCT__ "EPSSortDenseSchurTarget"
670
/*@
671
   EPSSortDenseSchurTarget - Reorders the Schur decomposition computed by
672
   EPSDenseSchur().
673
 
674
   Not Collective
675
 
676
   Input Parameters:
677
+  n     - dimension of the matrix
678
.  k     - first active column
679
.  ldt   - leading dimension of T
1496 slepc 680
.  target - the target value
681
-  which - eigenvalue sort order
1428 slepc 682
 
683
   Input/Output Parameters:
684
+  T  - the upper (quasi-)triangular matrix
685
.  Z  - the orthogonal matrix of Schur vectors
686
.  wr - pointer to the array to store the computed eigenvalues
687
-  wi - imaginary part of the eigenvalues (only when using real numbers)
688
 
689
   Notes:
690
   This function reorders the eigenvalues in wr,wi located in positions k
1496 slepc 691
   to n according to increasing distance to the target. The parameter which
692
   is used to determine if distance is relative to magnitude, real axis,
693
   or imaginary axis. The Schur decomposition Z*T*Z^T, is also reordered
694
   by means of rotations so that eigenvalues in the diagonal blocks of T
695
   follow the same order.
1428 slepc 696
 
697
   Both T and Z are overwritten.
698
 
699
   This routine uses LAPACK routines xTREXC.
700
 
701
   Level: developer
702
 
703
.seealso: EPSDenseHessenberg(), EPSDenseSchur(), EPSDenseTridiagonal()
704
@*/
1509 slepc 705
PetscErrorCode EPSSortDenseSchurTarget(PetscInt n_,PetscInt k,PetscScalar *T,PetscInt ldt_,PetscScalar *Z,PetscScalar *wr,PetscScalar *wi,PetscScalar target,EPSWhich which)
1428 slepc 706
{
707
#if defined(SLEPC_MISSING_LAPACK_TREXC)
708
  PetscFunctionBegin;
709
  SETERRQ(PETSC_ERR_SUP,"TREXC - Lapack routine is unavailable.");
710
#else
1512 slepc 711
  PetscErrorCode ierr;
712
  PetscReal      value,v;
713
  PetscInt       i,j;
1642 slepc 714
  PetscBLASInt   ifst,ilst,info,pos,n,ldt;
1428 slepc 715
#if !defined(PETSC_USE_COMPLEX)
1512 slepc 716
  PetscScalar    *work;
1428 slepc 717
#endif
718
 
719
  PetscFunctionBegin;
720
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 721
  n = PetscBLASIntCast(n_);
722
  ldt = PetscBLASIntCast(ldt_);
1428 slepc 723
#if !defined(PETSC_USE_COMPLEX)
724
  ierr = PetscMalloc(n*sizeof(PetscScalar),&work);CHKERRQ(ierr);
725
#endif
726
 
727
  for (i=k;i<n-1;i++) {
1496 slepc 728
    switch(which) {
729
      case EPS_LARGEST_MAGNITUDE:
730
        /* complex target only allowed if scalartype=complex */
731
        value = SlepcAbsEigenvalue(wr[i]-target,wi[i]);
732
        break;
733
      case EPS_LARGEST_REAL:
1497 slepc 734
        value = PetscAbsReal(PetscRealPart(wr[i]-target));
1496 slepc 735
        break;
736
      case EPS_LARGEST_IMAGINARY:
737
#if !defined(PETSC_USE_COMPLEX)
738
        /* complex target only allowed if scalartype=complex */
1497 slepc 739
        value = PetscAbsReal(wi[i]);
1496 slepc 740
#else
1497 slepc 741
        value = PetscAbsReal(PetscImaginaryPart(wr[i]-target));
1496 slepc 742
#endif
743
        break;
744
      default: SETERRQ(1,"Wrong value of which");
745
    }
1428 slepc 746
    pos = 0;
747
    for (j=i+1;j<n;j++) {
1496 slepc 748
      switch(which) {
749
        case EPS_LARGEST_MAGNITUDE:
750
          /* complex target only allowed if scalartype=complex */
751
          v = SlepcAbsEigenvalue(wr[j]-target,wi[j]);
752
          break;
753
        case EPS_LARGEST_REAL:
1497 slepc 754
          v = PetscAbsReal(PetscRealPart(wr[j]-target));
1496 slepc 755
          break;
756
        case EPS_LARGEST_IMAGINARY:
757
#if !defined(PETSC_USE_COMPLEX)
758
          /* complex target only allowed if scalartype=complex */
1497 slepc 759
          v = PetscAbsReal(wi[j]);
1496 slepc 760
#else
1497 slepc 761
          v = PetscAbsReal(PetscImaginaryPart(wr[j]-target));
1496 slepc 762
#endif
763
          break;
764
        default: SETERRQ(1,"Wrong value of which");
765
      }
1428 slepc 766
      if (v < value) {
767
        value = v;
768
        pos = j;
769
      }
770
#if !defined(PETSC_USE_COMPLEX)
771
      if (wi[j] != 0) j++;
772
#endif
773
    }
774
    if (pos) {
1642 slepc 775
      ifst = PetscBLASIntCast(pos + 1);
776
      ilst = PetscBLASIntCast(i + 1);
1428 slepc 777
#if !defined(PETSC_USE_COMPLEX)
1536 slepc 778
      LAPACKtrexc_("V",&n,T,&ldt,Z,&n,&ifst,&ilst,work,&info);
1428 slepc 779
#else
1536 slepc 780
      LAPACKtrexc_("V",&n,T,&ldt,Z,&n,&ifst,&ilst,&info);
1428 slepc 781
#endif
782
      if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xTREXC %d",info);
783
 
784
      for (j=k;j<n;j++) {
785
#if !defined(PETSC_USE_COMPLEX)
786
        if (j==n-1 || T[j*ldt+j+1] == 0.0) {
787
          /* real eigenvalue */
788
          wr[j] = T[j*ldt+j];
789
          wi[j] = 0.0;
790
        } else {
791
          /* complex eigenvalue */
792
          wr[j] = T[j*ldt+j];
793
          wr[j+1] = T[j*ldt+j];
794
          wi[j] = sqrt(PetscAbsReal(T[j*ldt+j+1])) *
795
                  sqrt(PetscAbsReal(T[(j+1)*ldt+j]));
796
          wi[j+1] = -wi[j];
797
          j++;
798
        }
799
#else
800
        wr[j] = T[j*(ldt+1)];
801
#endif
802
      }
803
    }
804
#if !defined(PETSC_USE_COMPLEX)
805
    if (wi[i] != 0) i++;
806
#endif
807
  }
808
 
809
#if !defined(PETSC_USE_COMPLEX)
810
  ierr = PetscFree(work);CHKERRQ(ierr);
811
#endif
812
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
813
  PetscFunctionReturn(0);
814
 
815
#endif
816
}
817
 
818
#undef __FUNCT__  
1175 slepc 819
#define __FUNCT__ "EPSDenseTridiagonal"
820
/*@
821
   EPSDenseTridiagonal - Solves a real tridiagonal Hermitian Eigenvalue Problem.
822
 
823
   Not Collective
824
 
825
   Input Parameters:
826
+  n   - dimension of the eigenproblem
827
.  A   - pointer to the array containing the matrix values
828
-  lda - leading dimension of A
829
 
830
   Output Parameters:
831
+  w  - pointer to the array to store the computed eigenvalues
832
-  V  - pointer to the array to store the eigenvectors
833
 
834
   Notes:
835
   If V is PETSC_NULL then the eigenvectors are not computed.
836
 
837
   This routine use LAPACK routines DSTEVR.
838
 
839
   Level: developer
840
 
841
.seealso: EPSDenseNHEP(), EPSDenseHEP(), EPSDenseGNHEP(), EPSDenseGHEP()
842
@*/
1616 slepc 843
PetscErrorCode EPSDenseTridiagonal(PetscInt n_,PetscReal *D,PetscReal *E,PetscReal *w,PetscScalar *V)
1175 slepc 844
{
1441 slepc 845
#if defined(SLEPC_MISSING_LAPACK_STEVR)
1175 slepc 846
  PetscFunctionBegin;
1441 slepc 847
  SETERRQ(PETSC_ERR_SUP,"STEVR - Lapack routine is unavailable.");
1175 slepc 848
#else
849
  PetscErrorCode ierr;
1616 slepc 850
  PetscReal      abstol = 0.0,vl,vu,*work;
1642 slepc 851
  PetscBLASInt   il,iu,m,*isuppz,n,lwork,*iwork,liwork,info;
1175 slepc 852
  const char     *jobz;
1177 slepc 853
#if defined(PETSC_USE_COMPLEX)
1662 slepc 854
  PetscInt       i,j;
1177 slepc 855
  PetscReal      *VV;
856
#endif
857
 
1175 slepc 858
  PetscFunctionBegin;
1339 slepc 859
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1642 slepc 860
  n = PetscBLASIntCast(n_);
861
  lwork = PetscBLASIntCast(20*n_);
862
  liwork = PetscBLASIntCast(10*n_);
1177 slepc 863
  if (V) {
864
    jobz = "V";
865
#if defined(PETSC_USE_COMPLEX)
866
    ierr = PetscMalloc(n*n*sizeof(PetscReal),&VV);CHKERRQ(ierr);
867
#endif
868
  } else jobz = "N";
1509 slepc 869
  ierr = PetscMalloc(2*n*sizeof(PetscBLASInt),&isuppz);CHKERRQ(ierr);
1175 slepc 870
  ierr = PetscMalloc(lwork*sizeof(PetscReal),&work);CHKERRQ(ierr);
1509 slepc 871
  ierr = PetscMalloc(liwork*sizeof(PetscBLASInt),&iwork);CHKERRQ(ierr);
1177 slepc 872
#if defined(PETSC_USE_COMPLEX)
1536 slepc 873
  LAPACKstevr_(jobz,"A",&n,D,E,&vl,&vu,&il,&iu,&abstol,&m,w,VV,&n,isuppz,work,&lwork,iwork,&liwork,&info);
1177 slepc 874
#else
1536 slepc 875
  LAPACKstevr_(jobz,"A",&n,D,E,&vl,&vu,&il,&iu,&abstol,&m,w,V,&n,isuppz,work,&lwork,iwork,&liwork,&info);
1177 slepc 876
#endif
1175 slepc 877
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DSTEVR %d",info);
1177 slepc 878
#if defined(PETSC_USE_COMPLEX)
879
  if (V) {
880
    for (i=0;i<n;i++)
881
      for (j=0;j<n;j++)
882
        V[i*n+j] = VV[i*n+j];
883
    ierr = PetscFree(VV);CHKERRQ(ierr);
884
  }
885
#endif
1175 slepc 886
  ierr = PetscFree(isuppz);CHKERRQ(ierr);
887
  ierr = PetscFree(work);CHKERRQ(ierr);
888
  ierr = PetscFree(iwork);CHKERRQ(ierr);
1339 slepc 889
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
1175 slepc 890
  PetscFunctionReturn(0);
891
#endif
892
}