Subversion Repositories slepc-dev

Rev

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.
6 dsic.upv.es!jroman 6
*/
183 dsic.upv.es!antodo 7
#include "slepceps.h" /*I "slepceps.h" I*/
6 dsic.upv.es!jroman 8
#include "slepcblaslapack.h"
9
 
10
#undef __FUNCT__  
681 dsic.upv.es!antodo 11
#define __FUNCT__ "EPSDenseNHEP"
6 dsic.upv.es!jroman 12
/*@
683 dsic.upv.es!jroman 13
   EPSDenseNHEP - Solves a dense standard non-Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 14
 
15
   Not Collective
16
 
17
   Input Parameters:
681 dsic.upv.es!antodo 18
+  n  - dimension of the eigenproblem
19
-  A  - pointer to the array containing the matrix values
6 dsic.upv.es!jroman 20
 
681 dsic.upv.es!antodo 21
   Output Parameters:
22
+  w  - pointer to the array to store the computed eigenvalues
23
.  wi - imaginary part of the eigenvalues (only when using real numbers)
780 dsic.upv.es!jroman 24
.  V  - pointer to the array to store right eigenvectors
25
-  W  - pointer to the array to store left eigenvectors
6 dsic.upv.es!jroman 26
 
27
   Notes:
780 dsic.upv.es!jroman 28
   If either V or W are PETSC_NULL then the corresponding eigenvectors are
29
   not computed.
6 dsic.upv.es!jroman 30
 
681 dsic.upv.es!antodo 31
   Matrix A is overwritten.
32
 
33
   This routine uses LAPACK routines xGEEVX.
34
 
6 dsic.upv.es!jroman 35
   Level: developer
36
 
681 dsic.upv.es!antodo 37
.seealso: EPSDenseGNHEP(), EPSDenseHEP(), EPSDenseGHEP()
6 dsic.upv.es!jroman 38
@*/
780 dsic.upv.es!jroman 39
PetscErrorCode EPSDenseNHEP(int n,PetscScalar *A,PetscScalar *w,PetscScalar *wi,PetscScalar *V,PetscScalar *W)
6 dsic.upv.es!jroman 40
{
806 dsic.upv.es!antodo 41
#if defined(SLEPC_MISSING_LAPACK_GEEVX)
817 dsic.upv.es!antodo 42
  PetscFunctionBegin;
806 dsic.upv.es!antodo 43
  SETERRQ(PETSC_ERR_SUP,"GEEVX - Lapack routine is unavailable.");
44
#else
476 dsic.upv.es!antodo 45
  PetscErrorCode ierr;
982 slepc 46
  PetscReal      abnrm,*scale,dummy;
681 dsic.upv.es!antodo 47
  PetscScalar    *work;
48
  int            ilo,ihi,lwork = 4*n,info;
1004 slepc 49
  const char     *jobvr,*jobvl;
681 dsic.upv.es!antodo 50
#if defined(PETSC_USE_COMPLEX)
51
  PetscReal      *rwork;
982 slepc 52
#else
53
  int            idummy;
681 dsic.upv.es!antodo 54
#endif
6 dsic.upv.es!jroman 55
 
74 dsic.upv.es!antodo 56
  PetscFunctionBegin;
681 dsic.upv.es!antodo 57
  if (V) jobvr = "V";
58
  else jobvr = "N";
780 dsic.upv.es!jroman 59
  if (W) jobvl = "V";
60
  else jobvl = "N";
681 dsic.upv.es!antodo 61
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
62
  ierr  = PetscMalloc(n*sizeof(PetscReal),&scale);CHKERRQ(ierr);
6 dsic.upv.es!jroman 63
#if defined(PETSC_USE_COMPLEX)
681 dsic.upv.es!antodo 64
  ierr  = PetscMalloc(2*n*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
982 slepc 65
  LAPACKgeevx_("B",jobvl,jobvr,"N",&n,A,&n,w,W,&n,V,&n,&ilo,&ihi,scale,&abnrm,&dummy,&dummy,work,&lwork,rwork,&info,1,1,1,1);
66
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZGEEVX %d",info);
681 dsic.upv.es!antodo 67
  ierr = PetscFree(rwork);CHKERRQ(ierr);
6 dsic.upv.es!jroman 68
#else
982 slepc 69
  LAPACKgeevx_("B",jobvl,jobvr,"N",&n,A,&n,w,wi,W,&n,V,&n,&ilo,&ihi,scale,&abnrm,&dummy,&dummy,work,&lwork,&idummy,&info,1,1,1,1);
70
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DGEEVX %d",info);
681 dsic.upv.es!antodo 71
#endif
72
  ierr = PetscFree(work);CHKERRQ(ierr);
73
  ierr = PetscFree(scale);CHKERRQ(ierr);
6 dsic.upv.es!jroman 74
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 75
#endif
6 dsic.upv.es!jroman 76
}
77
 
78
#undef __FUNCT__  
681 dsic.upv.es!antodo 79
#define __FUNCT__ "EPSDenseGNHEP"
6 dsic.upv.es!jroman 80
/*@
683 dsic.upv.es!jroman 81
   EPSDenseGNHEP - Solves a dense Generalized non-Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 82
 
83
   Not Collective
84
 
545 dsic.upv.es!jroman 85
   Input Parameters:
6 dsic.upv.es!jroman 86
+  n  - dimension of the eigenproblem
681 dsic.upv.es!antodo 87
.  A  - pointer to the array containing the matrix values for A
88
-  B  - pointer to the array containing the matrix values for B
6 dsic.upv.es!jroman 89
 
90
   Output Parameters:
91
+  w  - pointer to the array to store the computed eigenvalues
92
.  wi - imaginary part of the eigenvalues (only when using real numbers)
780 dsic.upv.es!jroman 93
.  V  - pointer to the array to store right eigenvectors
94
-  W  - pointer to the array to store left eigenvectors
6 dsic.upv.es!jroman 95
 
96
   Notes:
780 dsic.upv.es!jroman 97
   If either V or W are PETSC_NULL then the corresponding eigenvectors are
98
   not computed.
6 dsic.upv.es!jroman 99
 
683 dsic.upv.es!jroman 100
   Matrices A and B are overwritten.
6 dsic.upv.es!jroman 101
 
681 dsic.upv.es!antodo 102
   This routine uses LAPACK routines xGGEVX.
6 dsic.upv.es!jroman 103
 
104
   Level: developer
105
 
681 dsic.upv.es!antodo 106
.seealso: EPSDenseNHEP(), EPSDenseHEP(), EPSDenseGHEP()
6 dsic.upv.es!jroman 107
@*/
780 dsic.upv.es!jroman 108
PetscErrorCode EPSDenseGNHEP(int n,PetscScalar *A,PetscScalar *B,PetscScalar *w,PetscScalar *wi,PetscScalar *V,PetscScalar *W)
6 dsic.upv.es!jroman 109
{
806 dsic.upv.es!antodo 110
#if defined(SLEPC_MISSING_LAPACK_GGEVX)
817 dsic.upv.es!antodo 111
  PetscFunctionBegin;
806 dsic.upv.es!antodo 112
  SETERRQ(PETSC_ERR_SUP,"GGEVX - Lapack routine is unavailable.");
113
#else
476 dsic.upv.es!antodo 114
  PetscErrorCode ierr;
982 slepc 115
  PetscReal      *rscale,*lscale,abnrm,bbnrm,dummy;
681 dsic.upv.es!antodo 116
  PetscScalar    *alpha,*beta,*work;
982 slepc 117
  int            i,ilo,ihi,idummy,info;
1004 slepc 118
  const char     *jobvr,*jobvl;
681 dsic.upv.es!antodo 119
#if defined(PETSC_USE_COMPLEX)
120
  PetscReal      *rwork;
121
  int            lwork = 2*n;
122
#else
123
  PetscReal      *alphai;
124
  int            lwork = 6*n;
125
#endif
6 dsic.upv.es!jroman 126
 
681 dsic.upv.es!antodo 127
  PetscFunctionBegin;
128
  if (V) jobvr = "V";
129
  else jobvr = "N";
780 dsic.upv.es!jroman 130
  if (W) jobvl = "V";
131
  else jobvl = "N";
681 dsic.upv.es!antodo 132
  ierr  = PetscMalloc(n*sizeof(PetscScalar),&alpha);CHKERRQ(ierr);
133
  ierr  = PetscMalloc(n*sizeof(PetscScalar),&beta);CHKERRQ(ierr);
134
  ierr  = PetscMalloc(n*sizeof(PetscReal),&rscale);CHKERRQ(ierr);
135
  ierr  = PetscMalloc(n*sizeof(PetscReal),&lscale);CHKERRQ(ierr);
136
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
137
#if defined(PETSC_USE_COMPLEX)
138
  ierr  = PetscMalloc(6*n*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
982 slepc 139
  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,1,1,1,1);
140
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZGGEVX %d",info);
681 dsic.upv.es!antodo 141
  for (i=0;i<n;i++) {
142
    w[i] = alpha[i]/beta[i];
143
  }
144
  ierr = PetscFree(rwork);CHKERRQ(ierr);
6 dsic.upv.es!jroman 145
#else
681 dsic.upv.es!antodo 146
  ierr  = PetscMalloc(n*sizeof(PetscReal),&alphai);CHKERRQ(ierr);
982 slepc 147
  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,1,1,1,1);
148
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DGGEVX %d",info);
681 dsic.upv.es!antodo 149
  for (i=0;i<n;i++) {
150
    w[i] = alpha[i]/beta[i];
151
    wi[i] = alphai[i]/beta[i];
152
  }
153
  ierr = PetscFree(alphai);CHKERRQ(ierr);
154
#endif
155
  ierr = PetscFree(alpha);CHKERRQ(ierr);
156
  ierr = PetscFree(beta);CHKERRQ(ierr);
157
  ierr = PetscFree(rscale);CHKERRQ(ierr);
158
  ierr = PetscFree(lscale);CHKERRQ(ierr);
6 dsic.upv.es!jroman 159
  ierr = PetscFree(work);CHKERRQ(ierr);
681 dsic.upv.es!antodo 160
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 161
#endif
681 dsic.upv.es!antodo 162
}
6 dsic.upv.es!jroman 163
 
681 dsic.upv.es!antodo 164
#undef __FUNCT__  
165
#define __FUNCT__ "EPSDenseHEP"
166
/*@
683 dsic.upv.es!jroman 167
   EPSDenseHEP - Solves a dense standard Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 168
 
681 dsic.upv.es!antodo 169
   Not Collective
6 dsic.upv.es!jroman 170
 
681 dsic.upv.es!antodo 171
   Input Parameters:
1175 slepc 172
+  n   - dimension of the eigenproblem
173
.  A   - pointer to the array containing the matrix values
174
-  lda - leading dimension of A
6 dsic.upv.es!jroman 175
 
681 dsic.upv.es!antodo 176
   Output Parameters:
177
+  w  - pointer to the array to store the computed eigenvalues
178
-  V  - pointer to the array to store the eigenvectors
179
 
180
   Notes:
181
   If V is PETSC_NULL then the eigenvectors are not computed.
182
 
183
   Matrix A is overwritten.
184
 
185
   This routine uses LAPACK routines DSYEVR or ZHEEVR.
186
 
187
   Level: developer
188
 
189
.seealso: EPSDenseNHEP(), EPSDenseGNHEP(), EPSDenseGHEP()
190
@*/
1175 slepc 191
PetscErrorCode EPSDenseHEP(int n,PetscScalar *A,int lda,PetscReal *w,PetscScalar *V)
681 dsic.upv.es!antodo 192
{
806 dsic.upv.es!antodo 193
#if defined(SLEPC_MISSING_LAPACK_SYEVR) || defined(SLEPC_MISSING_LAPACK_HEEVR)
817 dsic.upv.es!antodo 194
  PetscFunctionBegin;
806 dsic.upv.es!antodo 195
  SETERRQ(PETSC_ERR_SUP,"DSYEVR/ZHEEVR - Lapack routine is unavailable.");
196
#else
681 dsic.upv.es!antodo 197
  PetscErrorCode ierr;
982 slepc 198
  PetscReal      abstol = 0.0,vl,vu;
681 dsic.upv.es!antodo 199
  PetscScalar    *work;
982 slepc 200
  int            il,iu,m,*isuppz,*iwork,liwork = 10*n,info;
1004 slepc 201
  const char     *jobz;
681 dsic.upv.es!antodo 202
#if defined(PETSC_USE_COMPLEX)
203
  PetscReal      *rwork;
711 dsic.upv.es!antodo 204
  int            lwork = 18*n,lrwork = 24*n;
6 dsic.upv.es!jroman 205
#else
681 dsic.upv.es!antodo 206
  int            lwork = 26*n;
207
#endif
6 dsic.upv.es!jroman 208
 
209
  PetscFunctionBegin;
681 dsic.upv.es!antodo 210
  if (V) jobz = "V";
211
  else jobz = "N";
212
  ierr  = PetscMalloc(2*n*sizeof(int),&isuppz);CHKERRQ(ierr);
213
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
214
  ierr  = PetscMalloc(liwork*sizeof(int),&iwork);CHKERRQ(ierr);
215
#if defined(PETSC_USE_COMPLEX)
216
  ierr  = PetscMalloc(lrwork*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
1175 slepc 217
  LAPACKsyevr_(jobz,"A","L",&n,A,&lda,&vl,&vu,&il,&iu,&abstol,&m,w,V,&n,isuppz,work,&lwork,rwork,&lrwork,iwork,&liwork,&info,1,1,1);
681 dsic.upv.es!antodo 218
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZHEEVR %d",info);
6 dsic.upv.es!jroman 219
  ierr = PetscFree(rwork);CHKERRQ(ierr);
681 dsic.upv.es!antodo 220
#else
1175 slepc 221
  LAPACKsyevr_(jobz,"A","L",&n,A,&lda,&vl,&vu,&il,&iu,&abstol,&m,w,V,&n,isuppz,work,&lwork,iwork,&liwork,&info,1,1,1);
681 dsic.upv.es!antodo 222
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DSYEVR %d",info);
6 dsic.upv.es!jroman 223
#endif
681 dsic.upv.es!antodo 224
  ierr = PetscFree(isuppz);CHKERRQ(ierr);
225
  ierr = PetscFree(work);CHKERRQ(ierr);
226
  ierr = PetscFree(iwork);CHKERRQ(ierr);
6 dsic.upv.es!jroman 227
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 228
#endif
6 dsic.upv.es!jroman 229
}
230
 
231
#undef __FUNCT__  
681 dsic.upv.es!antodo 232
#define __FUNCT__ "EPSDenseGHEP"
6 dsic.upv.es!jroman 233
/*@
683 dsic.upv.es!jroman 234
   EPSDenseGHEP - Solves a dense Generalized Hermitian Eigenvalue Problem.
6 dsic.upv.es!jroman 235
 
236
   Not Collective
237
 
545 dsic.upv.es!jroman 238
   Input Parameters:
6 dsic.upv.es!jroman 239
+  n  - dimension of the eigenproblem
681 dsic.upv.es!antodo 240
.  A  - pointer to the array containing the matrix values for A
241
-  B  - pointer to the array containing the matrix values for B
6 dsic.upv.es!jroman 242
 
243
   Output Parameters:
244
+  w  - pointer to the array to store the computed eigenvalues
245
-  V  - pointer to the array to store the eigenvectors
246
 
247
   Notes:
172 dsic.upv.es!jroman 248
   If V is PETSC_NULL then the eigenvectors are not computed.
6 dsic.upv.es!jroman 249
 
683 dsic.upv.es!jroman 250
   Matrices A and B are overwritten.
681 dsic.upv.es!antodo 251
 
252
   This routine uses LAPACK routines DSYGVD or ZHEGVD.
6 dsic.upv.es!jroman 253
 
254
   Level: developer
255
 
681 dsic.upv.es!antodo 256
.seealso: EPSDenseNHEP(), EPSDenseGNHEP(), EPSDenseHEP()
6 dsic.upv.es!jroman 257
@*/
681 dsic.upv.es!antodo 258
PetscErrorCode EPSDenseGHEP(int n,PetscScalar *A,PetscScalar *B,PetscReal *w,PetscScalar *V)
6 dsic.upv.es!jroman 259
{
806 dsic.upv.es!antodo 260
#if defined(SLEPC_MISSING_LAPACK_SYGVD) || defined(SLEPC_MISSING_LAPACK_HEGVD)
817 dsic.upv.es!antodo 261
  PetscFunctionBegin;
806 dsic.upv.es!antodo 262
  SETERRQ(PETSC_ERR_SUP,"DSYGVD/ZHEGVD - Lapack routine is unavailable.");
263
#else
476 dsic.upv.es!antodo 264
  PetscErrorCode ierr;
681 dsic.upv.es!antodo 265
  PetscScalar    *work;
266
  int            itype = 1,*iwork,info,
267
                 liwork = V ? 5*n+3 : 1;
1004 slepc 268
  const char     *jobz;
681 dsic.upv.es!antodo 269
#if defined(PETSC_USE_COMPLEX)
270
  PetscReal      *rwork;
271
  int            lwork  = V ? n*n+2*n     : n+1,
272
                 lrwork = V ? 2*n*n+5*n+1 : n;
273
#else
274
  int            lwork  = V ? 2*n*n+6*n+1 : 2*n+1;
275
#endif
6 dsic.upv.es!jroman 276
 
277
  PetscFunctionBegin;
681 dsic.upv.es!antodo 278
  if (V) jobz = "V";
279
  else jobz = "N";  
280
  ierr  = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
281
  ierr  = PetscMalloc(liwork*sizeof(int),&iwork);CHKERRQ(ierr);
282
#if defined(PETSC_USE_COMPLEX)
283
  ierr  = PetscMalloc(lrwork*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
784 dsic.upv.es!antodo 284
  LAPACKsygvd_(&itype,jobz,"U",&n,A,&n,B,&n,w,work,&lwork,rwork,&lrwork,iwork,&liwork,&info,1,1);
735 dsic.upv.es!antodo 285
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack ZHEGVD %d",info);
681 dsic.upv.es!antodo 286
  ierr = PetscFree(rwork);CHKERRQ(ierr);
287
#else
784 dsic.upv.es!antodo 288
  LAPACKsygvd_(&itype,jobz,"U",&n,A,&n,B,&n,w,work,&lwork,iwork,&liwork,&info,1,1);
735 dsic.upv.es!antodo 289
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DSYGVD %d",info);
681 dsic.upv.es!antodo 290
#endif
6 dsic.upv.es!jroman 291
  if (V) {
681 dsic.upv.es!antodo 292
    ierr = PetscMemcpy(V,A,n*n*sizeof(PetscScalar));CHKERRQ(ierr);
6 dsic.upv.es!jroman 293
  }
681 dsic.upv.es!antodo 294
  ierr = PetscFree(work);CHKERRQ(ierr);
295
  ierr = PetscFree(iwork);CHKERRQ(ierr);
6 dsic.upv.es!jroman 296
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 297
#endif
6 dsic.upv.es!jroman 298
}
299
 
461 dsic.upv.es!antodo 300
#undef __FUNCT__  
1175 slepc 301
#define __FUNCT__ "EPSDenseHessenberg"
302
/*@
303
   EPSDenseHessenberg - Computes the Hessenberg form of a dense matrix.
304
 
305
   Not Collective
306
 
307
   Input Parameters:
308
+  n     - dimension of the matrix
309
.  k     - first active column
310
-  lda   - leading dimension of A
311
 
312
   Input/Output Parameters:
313
+  A  - on entry, the full matrix; on exit, the upper Hessenberg matrix (H)
314
-  Q  - on exit, orthogonal matrix of vectors A = Q*H*Q'
315
 
316
   Notes:
317
   Only active columns (from k to n) are computed.
318
 
319
   Both A and Q are overwritten.
320
 
321
   This routine uses LAPACK routines xGEHRD and xORGHR/xUNGHR.
322
 
323
   Level: developer
324
 
325
.seealso: EPSDenseSchur(), EPSSortDenseSchur(), EPSDenseTridiagonal()
326
@*/
327
PetscErrorCode EPSDenseHessenberg(int n,int k,PetscScalar *A,int lda,PetscScalar *Q)
328
{
329
#if defined(SLEPC_MISSING_LAPACK_GEHRD) || defined(SLEPC_MISSING_LAPACK_ORGHR) || defined(SLEPC_MISSING_LAPACK_UNGHR)
330
  PetscFunctionBegin;
331
  SETERRQ(PETSC_ERR_SUP,"GEHRD,ORGHR/UNGHR - Lapack routines are unavailable.");
332
#else
333
  PetscScalar    *tau,*work;
334
  PetscErrorCode ierr;
335
  int            i,j,ilo,lwork,info;
336
 
337
  PetscFunctionBegin;
338
  ierr = PetscMalloc(n*sizeof(PetscScalar),&tau);CHKERRQ(ierr);
339
  lwork = n;
340
  ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
341
  ilo = k+1;
342
  LAPACKgehrd_(&n,&ilo,&n,A,&lda,tau,work,&lwork,&info);
343
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xGEHRD %d",info);
344
  for (j=0;j<n-1;j++) {
345
    for (i=j+2;i<n;i++) {
346
      Q[i+j*n] = A[i+j*lda];
347
      A[i+j*lda] = 0.0;
348
    }      
349
  }
350
  LAPACKorghr_(&n,&ilo,&n,Q,&n,tau,work,&lwork,&info);
351
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xORGHR %d",info);
352
  ierr = PetscFree(tau);CHKERRQ(ierr);
353
  ierr = PetscFree(work);CHKERRQ(ierr);
354
  PetscFunctionReturn(0);
355
#endif
356
}
357
 
358
#undef __FUNCT__  
461 dsic.upv.es!antodo 359
#define __FUNCT__ "EPSDenseSchur"
545 dsic.upv.es!jroman 360
/*@
361
   EPSDenseSchur - Computes the upper (quasi-)triangular form of a dense
362
   upper Hessenberg matrix.
363
 
364
   Not Collective
365
 
366
   Input Parameters:
1059 slepc 367
+  n   - dimension of the matrix
368
.  k   - first active column
369
-  ldh - leading dimension of H
545 dsic.upv.es!jroman 370
 
371
   Input/Output Parameters:
372
+  H  - on entry, the upper Hessenber matrix; on exit, the upper
373
        (quasi-)triangular matrix (T)
374
-  Z  - on entry, initial transformation matrix; on exit, orthogonal
375
        matrix of Schur vectors
376
 
377
   Output Parameters:
378
+  wr - pointer to the array to store the computed eigenvalues
379
-  wi - imaginary part of the eigenvalues (only when using real numbers)
380
 
381
   Notes:
382
   This function computes the (real) Schur decomposition of an upper
383
   Hessenberg matrix H: H*Z = Z*T,  where T is an upper (quasi-)triangular
384
   matrix (returned in H), and Z is the orthogonal matrix of Schur vectors.
385
   Eigenvalues are extracted from the diagonal blocks of T and returned in
386
   wr,wi. Transformations are accumulated in Z so that on entry it can
387
   contain the transformation matrix associated to the Hessenberg reduction.
388
 
389
   Only active columns (from k to n) are computed.
390
 
391
   Both H and Z are overwritten.
392
 
393
   This routine uses LAPACK routines xHSEQR.
394
 
395
   Level: developer
396
 
1175 slepc 397
.seealso: EPSDenseHessenberg(), EPSSortDenseSchur(), EPSDenseTridiagonal()
545 dsic.upv.es!jroman 398
@*/
1057 slepc 399
PetscErrorCode EPSDenseSchur(int n,int k,PetscScalar *H,int ldh,PetscScalar *Z,PetscScalar *wr,PetscScalar *wi)
461 dsic.upv.es!antodo 400
{
806 dsic.upv.es!antodo 401
#if defined(SLEPC_MISSING_LAPACK_HSEQR)
817 dsic.upv.es!antodo 402
  PetscFunctionBegin;
806 dsic.upv.es!antodo 403
  SETERRQ(PETSC_ERR_SUP,"HSEQR - Lapack routine is unavailable.");
404
#else
476 dsic.upv.es!antodo 405
  PetscErrorCode ierr;
515 dsic.upv.es!antodo 406
  int ilo,lwork,info;
461 dsic.upv.es!antodo 407
  PetscScalar *work;
551 dsic.upv.es!antodo 408
#if !defined(PETSC_USE_COMPLEX)
409
  int j;
410
#endif
461 dsic.upv.es!antodo 411
 
412
  PetscFunctionBegin;
413
  lwork = n;
414
  ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
415
  ilo = k+1;
416
#if !defined(PETSC_USE_COMPLEX)
1057 slepc 417
  LAPACKhseqr_("S","V",&n,&ilo,&n,H,&ldh,wr,wi,Z,&n,work,&lwork,&info,1,1);
551 dsic.upv.es!antodo 418
  for (j=0;j<k;j++) {
1057 slepc 419
    if (j==n-1 || H[j*ldh+j+1] == 0.0) {
551 dsic.upv.es!antodo 420
      /* real eigenvalue */
1057 slepc 421
      wr[j] = H[j*ldh+j];
551 dsic.upv.es!antodo 422
      wi[j] = 0.0;
423
    } else {
424
      /* complex eigenvalue */
1057 slepc 425
      wr[j] = H[j*ldh+j];
426
      wr[j+1] = H[j*ldh+j];
427
      wi[j] = sqrt(PetscAbsReal(H[j*ldh+j+1])) *
428
              sqrt(PetscAbsReal(H[(j+1)*ldh+j]));
551 dsic.upv.es!antodo 429
      wi[j+1] = -wi[j];
430
      j++;
431
    }
432
  }
461 dsic.upv.es!antodo 433
#else
1057 slepc 434
  LAPACKhseqr_("S","V",&n,&ilo,&n,H,&ldh,wr,Z,&n,work,&lwork,&info,1,1);
461 dsic.upv.es!antodo 435
#endif
476 dsic.upv.es!antodo 436
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xHSEQR %d",info);
461 dsic.upv.es!antodo 437
 
515 dsic.upv.es!antodo 438
  ierr = PetscFree(work);CHKERRQ(ierr);
439
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 440
#endif
515 dsic.upv.es!antodo 441
}
442
 
443
#undef __FUNCT__  
444
#define __FUNCT__ "EPSSortDenseSchur"
545 dsic.upv.es!jroman 445
/*@
446
   EPSSortDenseSchur - Reorders the Schur decomposition computed by
447
   EPSDenseSchur().
448
 
449
   Not Collective
450
 
451
   Input Parameters:
1180 slepc 452
+  n     - dimension of the matrix
453
.  k     - first active column
454
.  ldt   - leading dimension of T
455
-  which - eigenvalue sort order
545 dsic.upv.es!jroman 456
 
457
   Input/Output Parameters:
458
+  T  - the upper (quasi-)triangular matrix
459
-  Z  - the orthogonal matrix of Schur vectors
460
 
461
   Output Parameters:
462
+  wr - pointer to the array to store the computed eigenvalues
463
-  wi - imaginary part of the eigenvalues (only when using real numbers)
464
 
465
   Notes:
466
   This function reorders the eigenvalues in wr,wi located in positions k
1180 slepc 467
   to n according to the sort order specified in which. The Schur
468
   decomposition Z*T*Z^T, is also reordered by means of rotations so that
469
   eigenvalues in the diagonal blocks of T follow the same order.
545 dsic.upv.es!jroman 470
 
471
   Both T and Z are overwritten.
472
 
473
   This routine uses LAPACK routines xTREXC.
474
 
475
   Level: developer
476
 
1175 slepc 477
.seealso: EPSDenseHessenberg(), EPSDenseSchur(), EPSDenseTridiagonal()
545 dsic.upv.es!jroman 478
@*/
1174 slepc 479
PetscErrorCode EPSSortDenseSchur(int n,int k,PetscScalar *T,int ldt,PetscScalar *Z,PetscScalar *wr,PetscScalar *wi,EPSWhich which)
515 dsic.upv.es!antodo 480
{
806 dsic.upv.es!antodo 481
#if defined(SLEPC_MISSING_LAPACK_TREXC)
817 dsic.upv.es!antodo 482
  PetscFunctionBegin;
806 dsic.upv.es!antodo 483
  SETERRQ(PETSC_ERR_SUP,"TREXC - Lapack routine is unavailable.");
484
#else
1174 slepc 485
  int i,j,ifst,ilst,info,pos;
515 dsic.upv.es!antodo 486
#if !defined(PETSC_USE_COMPLEX)
487
  PetscScalar *work;
488
  PetscErrorCode ierr;
489
#endif
1174 slepc 490
  PetscReal   value,v;
515 dsic.upv.es!antodo 491
 
492
  PetscFunctionBegin;
493
#if !defined(PETSC_USE_COMPLEX)
494
  ierr = PetscMalloc(n*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1174 slepc 495
#endif
738 dsic.upv.es!antodo 496
 
461 dsic.upv.es!antodo 497
  for (i=k;i<n-1;i++) {
1174 slepc 498
    switch(which) {
499
      case EPS_LARGEST_MAGNITUDE:
500
      case EPS_SMALLEST_MAGNITUDE:
501
        value = SlepcAbsEigenvalue(wr[i],wi[i]);
502
        break;
503
      case EPS_LARGEST_REAL:
504
      case EPS_SMALLEST_REAL:
505
        value = PetscRealPart(wr[i]);
506
        break;
507
      case EPS_LARGEST_IMAGINARY:
508
      case EPS_SMALLEST_IMAGINARY:
509
#if !defined(PETSC_USE_COMPLEX)
510
        value = PetscAbsReal(wi[i]);
511
#else
512
        value = PetscImaginaryPart(wr[i]);
513
#endif
514
        break;
515
      default: SETERRQ(1,"Wrong value of which");
516
    }
517
    pos = 0;
461 dsic.upv.es!antodo 518
    for (j=i+1;j<n;j++) {
1174 slepc 519
      switch(which) {
520
        case EPS_LARGEST_MAGNITUDE:
521
        case EPS_SMALLEST_MAGNITUDE:
522
          v = SlepcAbsEigenvalue(wr[j],wi[j]);
523
          break;
524
        case EPS_LARGEST_REAL:
525
        case EPS_SMALLEST_REAL:
526
          v = PetscRealPart(wr[j]);
527
          break;
528
        case EPS_LARGEST_IMAGINARY:
529
        case EPS_SMALLEST_IMAGINARY:
530
#if !defined(PETSC_USE_COMPLEX)
531
          v = PetscAbsReal(wi[j]);
532
#else
533
          v = PetscImaginaryPart(wr[j]);
534
#endif
535
          break;
536
        default: SETERRQ(1,"Wrong value of which");
461 dsic.upv.es!antodo 537
      }
1174 slepc 538
      switch(which) {
539
        case EPS_LARGEST_MAGNITUDE:
540
        case EPS_LARGEST_REAL:
541
        case EPS_LARGEST_IMAGINARY:
542
          if (v > value) {
543
            value = v;
544
            pos = j;
545
          }
546
          break;
547
        case EPS_SMALLEST_MAGNITUDE:
548
        case EPS_SMALLEST_REAL:
549
        case EPS_SMALLEST_IMAGINARY:
550
          if (v < value) {
551
            value = v;
552
            pos = j;
553
          }
554
          break;
555
        default: SETERRQ(1,"Wrong value of which");
556
      }
557
#if !defined(PETSC_USE_COMPLEX)
461 dsic.upv.es!antodo 558
      if (wi[j] != 0) j++;
1174 slepc 559
#endif
461 dsic.upv.es!antodo 560
    }
1174 slepc 561
    if (pos) {
562
      ifst = pos + 1;
461 dsic.upv.es!antodo 563
      ilst = i + 1;
1174 slepc 564
#if !defined(PETSC_USE_COMPLEX)
1057 slepc 565
      LAPACKtrexc_("V",&n,T,&ldt,Z,&n,&ifst,&ilst,work,&info,1);
1174 slepc 566
#else
567
      LAPACKtrexc_("V",&n,T,&ldt,Z,&n,&ifst,&ilst,&info,1);
568
#endif
476 dsic.upv.es!antodo 569
      if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xTREXC %d",info);
738 dsic.upv.es!antodo 570
 
545 dsic.upv.es!jroman 571
      for (j=k;j<n;j++) {
1174 slepc 572
#if !defined(PETSC_USE_COMPLEX)
1057 slepc 573
        if (j==n-1 || T[j*ldt+j+1] == 0.0) {
545 dsic.upv.es!jroman 574
          /* real eigenvalue */
1057 slepc 575
          wr[j] = T[j*ldt+j];
545 dsic.upv.es!jroman 576
          wi[j] = 0.0;
577
        } else {
578
          /* complex eigenvalue */
1057 slepc 579
          wr[j] = T[j*ldt+j];
580
          wr[j+1] = T[j*ldt+j];
581
          wi[j] = sqrt(PetscAbsReal(T[j*ldt+j+1])) *
582
                  sqrt(PetscAbsReal(T[(j+1)*ldt+j]));
551 dsic.upv.es!antodo 583
          wi[j+1] = -wi[j];
545 dsic.upv.es!jroman 584
          j++;
585
        }
1174 slepc 586
#else
587
        wr[j] = T[j*(ldt+1)];
588
#endif
545 dsic.upv.es!jroman 589
      }
738 dsic.upv.es!antodo 590
    }
1174 slepc 591
#if !defined(PETSC_USE_COMPLEX)
738 dsic.upv.es!antodo 592
    if (wi[i] != 0) i++;
1174 slepc 593
#endif
738 dsic.upv.es!antodo 594
  }
595
 
1174 slepc 596
#if !defined(PETSC_USE_COMPLEX)
738 dsic.upv.es!antodo 597
  ierr = PetscFree(work);CHKERRQ(ierr);
461 dsic.upv.es!antodo 598
#endif
599
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 600
 
601
#endif
461 dsic.upv.es!antodo 602
}
1175 slepc 603
 
604
#undef __FUNCT__  
605
#define __FUNCT__ "EPSDenseTridiagonal"
606
/*@
607
   EPSDenseTridiagonal - Solves a real tridiagonal Hermitian Eigenvalue Problem.
608
 
609
   Not Collective
610
 
611
   Input Parameters:
612
+  n   - dimension of the eigenproblem
613
.  A   - pointer to the array containing the matrix values
614
-  lda - leading dimension of A
615
 
616
   Output Parameters:
617
+  w  - pointer to the array to store the computed eigenvalues
618
-  V  - pointer to the array to store the eigenvectors
619
 
620
   Notes:
621
   If V is PETSC_NULL then the eigenvectors are not computed.
622
 
623
   This routine use LAPACK routines DSTEVR.
624
 
625
   Level: developer
626
 
627
.seealso: EPSDenseNHEP(), EPSDenseHEP(), EPSDenseGNHEP(), EPSDenseGHEP()
628
@*/
1177 slepc 629
PetscErrorCode EPSDenseTridiagonal(int n,PetscScalar *A,int lda,PetscReal *w,PetscScalar *V)
1175 slepc 630
{
1262 slepc 631
#if defined(SLEPC_MISSING_LAPACK_DSTEVR)
1175 slepc 632
  PetscFunctionBegin;
633
  SETERRQ(PETSC_ERR_SUP,"DSTEVR - Lapack routine is unavailable.");
634
#else
635
  PetscErrorCode ierr;
636
  PetscReal      abstol = 0.0,vl,vu,*D,*E,*work;
637
  int            i,il,iu,m,*isuppz,lwork = 20*n,*iwork,liwork = 10*n,info;
638
  const char     *jobz;
1177 slepc 639
#if defined(PETSC_USE_COMPLEX)
640
  int            j;
641
  PetscReal      *VV;
642
#endif
643
 
1175 slepc 644
  PetscFunctionBegin;
1177 slepc 645
  if (V) {
646
    jobz = "V";
647
#if defined(PETSC_USE_COMPLEX)
648
    ierr = PetscMalloc(n*n*sizeof(PetscReal),&VV);CHKERRQ(ierr);
649
#endif
650
  } else jobz = "N";
1175 slepc 651
  ierr = PetscMalloc(n*sizeof(PetscReal),&D);CHKERRQ(ierr);
652
  ierr = PetscMalloc(n*sizeof(PetscReal),&E);CHKERRQ(ierr);
653
  ierr = PetscMalloc(2*n*sizeof(int),&isuppz);CHKERRQ(ierr);
654
  ierr = PetscMalloc(lwork*sizeof(PetscReal),&work);CHKERRQ(ierr);
655
  ierr = PetscMalloc(liwork*sizeof(int),&iwork);CHKERRQ(ierr);
656
  for (i=0;i<n-1;i++) {
1177 slepc 657
    D[i] = PetscRealPart(A[i*(lda+1)]);
658
    E[i] = PetscRealPart(A[i*(lda+1)+1]);
1175 slepc 659
  }
1177 slepc 660
  D[n-1] = PetscRealPart(A[(n-1)*(lda+1)]);
661
#if defined(PETSC_USE_COMPLEX)
662
  LAPACKstevr_(jobz,"A",&n,D,E,&vl,&vu,&il,&iu,&abstol,&m,w,VV,&n,isuppz,work,&lwork,iwork,&liwork,&info,1,1);
663
#else
1175 slepc 664
  LAPACKstevr_(jobz,"A",&n,D,E,&vl,&vu,&il,&iu,&abstol,&m,w,V,&n,isuppz,work,&lwork,iwork,&liwork,&info,1,1);
1177 slepc 665
#endif
1175 slepc 666
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack DSTEVR %d",info);
1177 slepc 667
#if defined(PETSC_USE_COMPLEX)
668
  if (V) {
669
    for (i=0;i<n;i++)
670
      for (j=0;j<n;j++)
671
        V[i*n+j] = VV[i*n+j];
672
    ierr = PetscFree(VV);CHKERRQ(ierr);
673
  }
674
#endif
1175 slepc 675
  ierr = PetscFree(D);CHKERRQ(ierr);
676
  ierr = PetscFree(E);CHKERRQ(ierr);
677
  ierr = PetscFree(isuppz);CHKERRQ(ierr);
678
  ierr = PetscFree(work);CHKERRQ(ierr);
679
  ierr = PetscFree(iwork);CHKERRQ(ierr);
680
  PetscFunctionReturn(0);
681
#endif
682
}