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
2783 jroman 1
/*
2
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3
   SLEPc - Scalable Library for Eigenvalue Problem Computations
4
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
5
 
6
   This file is part of SLEPc.
7
 
8
   SLEPc is free software: you can redistribute it and/or modify it under  the
9
   terms of version 3 of the GNU Lesser General Public License as published by
10
   the Free Software Foundation.
11
 
12
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
13
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
14
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
15
   more details.
16
 
17
   You  should have received a copy of the GNU Lesser General  Public  License
18
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
19
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20
*/
21
 
22
#include <slepc-private/psimpl.h>      /*I "slepcps.h" I*/
23
#include <slepcblaslapack.h>
24
 
25
#undef __FUNCT__  
26
#define __FUNCT__ "PSAllocate_HEP"
27
PetscErrorCode PSAllocate_HEP(PS ps,PetscInt ld)
28
{
29
  PetscErrorCode ierr;
30
 
31
  PetscFunctionBegin;
32
  ierr = PSAllocateMat_Private(ps,PS_MAT_A);CHKERRQ(ierr);
2789 jroman 33
  ierr = PSAllocateMat_Private(ps,PS_MAT_Q);CHKERRQ(ierr);
2783 jroman 34
  ierr = PSAllocateMatReal_Private(ps,PS_MAT_T);CHKERRQ(ierr);
35
  PetscFunctionReturn(0);
36
}
37
 
2821 jroman 38
/*   0       l           k                 n-1
2818 jroman 39
    -----------------------------------------
40
    |*       ·           ·                  |
41
    |  *     ·           ·                  |
42
    |    *   ·           ·                  |
43
    |      * ·           ·                  |
44
    |· · · · o           o                  |
45
    |          o         o                  |
46
    |            o       o                  |
47
    |              o     o                  |
48
    |                o   o                  |
49
    |                  o o                  |
50
    |· · · · o o o o o o o x                |
51
    |                    x x x              |
52
    |                      x x x            |
53
    |                        x x x          |
54
    |                          x x x        |
55
    |                            x x x      |
56
    |                              x x x    |
57
    |                                x x x  |
58
    |                                  x x x|
59
    |                                    x x|
60
    -----------------------------------------
61
*/
62
 
2783 jroman 63
#undef __FUNCT__  
2813 jroman 64
#define __FUNCT__ "PSSwitchFormat_HEP"
65
PetscErrorCode PSSwitchFormat_HEP(PS ps,PetscBool tocompact)
66
{
67
  PetscReal   *T = ps->rmat[PS_MAT_T];
68
  PetscScalar *A = ps->mat[PS_MAT_A];
69
  PetscInt    i,n=ps->n,k=ps->k,ld=ps->ld;
70
 
71
  PetscFunctionBegin;
72
  if (ps->compact==tocompact) PetscFunctionReturn(0);
73
  if (tocompact) { /* switch from dense (arrow) to compact storage */
74
    for (i=0;i<k;i++) {
75
      T[i] = PetscRealPart(A[i+i*ld]);
76
      T[i+ld] = PetscRealPart(A[k+i*ld]);
77
    }
78
    for (i=k;i<n;i++) {
79
      T[i] = PetscRealPart(A[i+i*ld]);
80
      T[i+ld] = PetscRealPart(A[i+1+i*ld]);
81
    }
82
  } else { /* switch from compact (arrow) to dense storage */
83
    for (i=0;i<k;i++) {
84
      A[i+i*ld] = T[i];
85
      A[k+i*ld] = T[i+ld];
86
      A[i+k*ld] = T[i+ld];
87
    }
88
    A[k+k*ld] = T[k];
89
    for (i=k+1;i<n;i++) {
90
      A[i+i*ld] = T[i];
91
      A[i-1+i*ld] = T[i-1+ld];
92
      A[i+(i-1)*ld] = T[i-1+ld];
93
    }
94
  }
95
  PetscFunctionReturn(0);
96
}
97
 
98
#undef __FUNCT__  
2783 jroman 99
#define __FUNCT__ "PSView_HEP"
100
PetscErrorCode PSView_HEP(PS ps,PetscViewer viewer)
101
{
102
  PetscErrorCode    ierr;
2793 jroman 103
  PetscViewerFormat format;
2796 jroman 104
  PetscInt          i,j,r,c;
105
  PetscReal         value;
2819 jroman 106
  const char        *meth[] = { "LAPACK's _steqr",
107
                                "LAPACK's _stevr" };
2783 jroman 108
 
109
  PetscFunctionBegin;
2793 jroman 110
  ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
111
  if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
112
    ierr = PetscViewerASCIIPrintf(viewer,"solving the problem with: %s\n",meth[ps->method]);CHKERRQ(ierr);
2796 jroman 113
    PetscFunctionReturn(0);
2793 jroman 114
  }
2796 jroman 115
  if (ps->compact) {
116
    ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
117
    if (format == PETSC_VIEWER_ASCII_MATLAB) {
118
      ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D\n",ps->n,ps->n);CHKERRQ(ierr);
119
      ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",3*ps->n);CHKERRQ(ierr);
120
      ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
121
      for (i=0;i<ps->n;i++) {
122
        ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,i+1,*(ps->rmat[PS_MAT_T]+i));CHKERRQ(ierr);
123
      }
124
      for (i=0;i<ps->n-1;i++) {
125
        r = PetscMax(i+2,ps->k+1);
126
        c = i+1;
127
        ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",r,c,*(ps->rmat[PS_MAT_T]+ps->ld+i));CHKERRQ(ierr);
128
        ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",c,r,*(ps->rmat[PS_MAT_T]+ps->ld+i));CHKERRQ(ierr);
129
      }
130
      ierr = PetscViewerASCIIPrintf(viewer,"];\n%s = spconvert(zzz);\n",PSMatName[PS_MAT_T]);CHKERRQ(ierr);
131
    } else {
132
      for (i=0;i<ps->n;i++) {
133
        for (j=0;j<ps->n;j++) {
134
          if (i==j) value = *(ps->rmat[PS_MAT_T]+i);
135
          else if ((i<ps->k && j==ps->k) || (i==ps->k && j<ps->k)) value = *(ps->rmat[PS_MAT_T]+ps->ld+PetscMin(i,j));
136
          else if (i==j+1 && i>ps->k) value = *(ps->rmat[PS_MAT_T]+ps->ld+i-1);
137
          else if (i+1==j && j>ps->k) value = *(ps->rmat[PS_MAT_T]+ps->ld+j-1);
138
          else value = 0.0;
139
          ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",value);CHKERRQ(ierr);
140
        }
141
        ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
142
      }
143
    }
144
    ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
145
    ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
146
  } else {
147
    ierr = PSViewMat_Private(ps,viewer,PS_MAT_A);CHKERRQ(ierr);
148
  }
2787 jroman 149
  if (ps->state>PS_STATE_INTERMEDIATE) {
2789 jroman 150
    ierr = PSViewMat_Private(ps,viewer,PS_MAT_Q);CHKERRQ(ierr);
2787 jroman 151
  }
2783 jroman 152
  PetscFunctionReturn(0);
153
}
154
 
155
#undef __FUNCT__  
2807 jroman 156
#define __FUNCT__ "PSVectors_HEP"
2818 jroman 157
PetscErrorCode PSVectors_HEP(PS ps,PSMatType mat,PetscInt *j,PetscReal *rnorm)
2807 jroman 158
{
159
  PetscScalar    *Q = ps->mat[PS_MAT_Q];
160
  PetscInt       ld = ps->ld;
161
  PetscErrorCode ierr;
162
 
163
  PetscFunctionBegin;
164
  if (ps->state<PS_STATE_CONDENSED) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ORDER,"Must call PSSolve() first");
165
  switch (mat) {
166
    case PS_MAT_X:
167
    case PS_MAT_Y:
2818 jroman 168
      if (j) {
169
        ierr = PetscMemcpy(ps->mat[mat]+(*j)*ld,Q+(*j)*ld,ld*sizeof(PetscScalar));CHKERRQ(ierr);
2807 jroman 170
      } else {
171
        ierr = PetscMemcpy(ps->mat[mat],Q,ld*ld*sizeof(PetscScalar));CHKERRQ(ierr);
172
      }
2818 jroman 173
      if (rnorm) *rnorm = PetscAbsScalar(Q[ps->n-1+(*j)*ld]);
2807 jroman 174
      break;
175
    case PS_MAT_U:
176
    case PS_MAT_VT:
177
      SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented yet");
178
      break;
179
    default:
180
      SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid mat parameter");
181
  }
182
  PetscFunctionReturn(0);
183
}
184
 
185
#undef __FUNCT__  
2783 jroman 186
#define __FUNCT__ "PSSolve_HEP"
187
PetscErrorCode PSSolve_HEP(PS ps,PetscScalar *wr,PetscScalar *wi)
188
{
189
#if defined(SLEPC_MISSING_LAPACK_SYTRD) || defined(SLEPC_MISSING_LAPACK_ORGTR) || defined(SLEPC_MISSING_LAPACK_STEQR)
190
  PetscFunctionBegin;
191
  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SYTRD/ORGTR/STEQR - Lapack routine is unavailable.");
192
#else
193
  PetscErrorCode ierr;
2796 jroman 194
  PetscInt       i,j;
2819 jroman 195
  PetscBLASInt   n1,n2,n3,lwork,liwork,info,l,n,m,ld,off,il,iu,*isuppz;
2821 jroman 196
  PetscScalar    *A,*S,*Q,*W,*work,*tau,one=1.0,zero=0.0;
2822 jroman 197
  PetscReal      *d,*e,abstol=0.0,vl,vu;
198
#if defined(PETSC_USE_COMPLEX)
199
  PetscReal      *ritz;
200
#endif
2783 jroman 201
 
202
  PetscFunctionBegin;
203
  n  = PetscBLASIntCast(ps->n);
2818 jroman 204
  l  = PetscBLASIntCast(ps->l);
2783 jroman 205
  ld = PetscBLASIntCast(ps->ld);
2818 jroman 206
  n1 = PetscBLASIntCast(ps->k-l+1);  /* size of leading block, excluding locked */
207
  n2 = PetscBLASIntCast(n-ps->k-1);  /* size of trailing block */
208
  n3 = n1+n2;
209
  off = l+l*ld;
2821 jroman 210
  A  = ps->mat[PS_MAT_A];
2789 jroman 211
  Q  = ps->mat[PS_MAT_Q];
2783 jroman 212
  d  = ps->rmat[PS_MAT_T];
213
  e  = ps->rmat[PS_MAT_T]+ld;
2818 jroman 214
  ierr = PetscMemzero(Q,ld*ld*sizeof(PetscScalar));CHKERRQ(ierr);
215
  for (i=0;i<n;i++) Q[i+i*ld] = 1.0;
2783 jroman 216
 
2796 jroman 217
  if (ps->compact) {
218
 
2787 jroman 219
    /* reduce to tridiagonal form */
2796 jroman 220
    if (ps->state<PS_STATE_INTERMEDIATE) {
221
 
222
      ierr = PSAllocateMat_Private(ps,PS_MAT_W);CHKERRQ(ierr);
223
      S = ps->mat[PS_MAT_W];
224
      ierr = PetscMemzero(S,ld*ld*sizeof(PetscScalar));CHKERRQ(ierr);
225
      ierr = PSAllocateWork_Private(ps,ld+ld*ld,0,0);CHKERRQ(ierr);
226
      tau  = ps->work;
227
      work = ps->work+ld;
228
      lwork = ld*ld;
229
 
230
      /* Flip matrix S */
2818 jroman 231
      for (i=l;i<n;i++) S[(n3-1-i+l)+(n3-1-i+l)*ld] = d[i];
232
      for (i=l;i<ps->k;i++) S[(n3-1-i+l)+(n3-1-ps->k+l)*ld] = e[i];
233
      for (i=ps->k;i<n-1;i++) S[(n3-1-i+l)+(n3-1-i-1+l)*ld] = e[i];
2796 jroman 234
 
235
      /* Reduce (2,2)-block of flipped S to tridiagonal form */
2818 jroman 236
      LAPACKsytrd_("L",&n1,S+n2+n2*ld,&ld,d+l,e+l,tau,work,&lwork,&info);
2796 jroman 237
      if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xSYTRD %d",info);
238
 
239
      /* Flip back diag and subdiag, put them in d and e */
2818 jroman 240
      for (i=0;i<n1-1;i++) {
241
        d[l+n1-i-1] = PetscRealPart(S[n2+i+(n2+i)*ld]);
242
        e[l+n1-i-2] = PetscRealPart(S[n2+i+1+(n2+i)*ld]);
2796 jroman 243
      }
2818 jroman 244
      d[l] = PetscRealPart(S[n3-1+(n3-1)*ld]);
2796 jroman 245
 
246
      /* Compute the orthogonal matrix used for tridiagonalization */
247
      LAPACKorgtr_("L",&n1,S+n2+n2*ld,&ld,tau,work,&lwork,&info);
248
      if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xORGTR %d",info);
249
 
250
      /* Create full-size Q, flipped back to original order */
251
      for (i=0;i<n1;i++)
252
        for (j=0;j<n1;j++)
2818 jroman 253
          Q[l+i+(l+j)*ld] = S[n3-i-1+(n3-j-1)*ld];
2796 jroman 254
 
255
    }
256
 
2787 jroman 257
  } else {
2796 jroman 258
 
2818 jroman 259
    for (i=0;i<l;i++) { d[i] = PetscRealPart(A[i+i*ld]); e[i] = 0.0; }
2796 jroman 260
 
261
    if (ps->state<PS_STATE_INTERMEDIATE) {
2821 jroman 262
      ierr = PSCopyMatrix_Private(ps,PS_MAT_Q,PS_MAT_A);CHKERRQ(ierr);
2796 jroman 263
      ierr = PSAllocateWork_Private(ps,ld+ld*ld,0,0);CHKERRQ(ierr);
264
      tau  = ps->work;
265
      work = ps->work+ld;
266
      lwork = ld*ld;
2818 jroman 267
      LAPACKsytrd_("L",&n3,Q+off,&ld,d+l,e+l,tau,work,&lwork,&info);
2796 jroman 268
      if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xSYTRD %d",info);
2818 jroman 269
      LAPACKorgtr_("L",&n3,Q+off,&ld,tau,work,&lwork,&info);
2796 jroman 270
      if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xORGTR %d",info);
271
    } else {
2818 jroman 272
      /* copy tridiagonal to d,e */
273
      for (i=l;i<n;i++) d[i] = PetscRealPart(A[i+i*ld]);
274
      for (i=l;i<n-1;i++) e[i] = PetscRealPart(A[(i+1)+i*ld]);
2796 jroman 275
    }
2783 jroman 276
  }
277
 
278
  /* Solve the tridiagonal eigenproblem */
2821 jroman 279
  for (i=0;i<l;i++) wr[i] = d[i];
2819 jroman 280
  switch (ps->method) {
281
    case 0:
282
      ierr = PSAllocateWork_Private(ps,0,2*ld,0);CHKERRQ(ierr);
283
      LAPACKsteqr_("V",&n3,d+l,e+l,Q+off,&ld,ps->rwork,&info);
284
      if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xSTEQR %d",info);
2821 jroman 285
      for (i=l;i<n;i++) wr[i] = d[i];
2819 jroman 286
      break;
287
    case 1:
2821 jroman 288
      if (ps->state<PS_STATE_INTERMEDIATE) {  /* Q contains useful info */
289
        ierr = PSAllocateMat_Private(ps,PS_MAT_W);CHKERRQ(ierr);
290
        W = ps->mat[PS_MAT_W];
291
        ierr = PSCopyMatrix_Private(ps,PS_MAT_W,PS_MAT_Q);CHKERRQ(ierr);
292
      }
2819 jroman 293
#if defined(PETSC_USE_COMPLEX)
294
      ierr = PSAllocateMatReal_Private(ps,PS_MAT_Q);CHKERRQ(ierr);
295
#endif
2821 jroman 296
      lwork = 20*ld;
297
      liwork = 10*ld;
298
      ierr = PSAllocateWork_Private(ps,0,lwork+ld,liwork+2*ld);CHKERRQ(ierr);
2819 jroman 299
      isuppz = ps->iwork+liwork;
300
#if defined(PETSC_USE_COMPLEX)
2821 jroman 301
      ritz = ps->rwork+lwork;
302
      LAPACKstevr_("V","A",&n3,d+l,e+l,&vl,&vu,&il,&iu,&abstol,&m,ritz+l,ps->rmat[PS_MAT_Q]+off,&ld,isuppz,ps->rwork,&lwork,ps->iwork,&liwork,&info);
303
      for (i=l;i<n;i++) wr[i] = ritz[i];
2819 jroman 304
#else
305
      LAPACKstevr_("V","A",&n3,d+l,e+l,&vl,&vu,&il,&iu,&abstol,&m,wr+l,Q+off,&ld,isuppz,ps->rwork,&lwork,ps->iwork,&liwork,&info);
306
#endif
307
      if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack DSTEVR %d",info);
308
#if defined(PETSC_USE_COMPLEX)
2821 jroman 309
      for (i=l;i<n;i++)
310
        for (j=l;j<n;j++)
311
          Q[i+j*ld] = (ps->rmat[PS_MAT_Q])[i+j*ld];
2819 jroman 312
#endif
2821 jroman 313
      if (ps->state<PS_STATE_INTERMEDIATE) {  /* accumulate previous Q */
314
        BLASgemm_("N","N",&n3,&n3,&n3,&one,W+off,&ld,Q+off,&ld,&zero,A+off,&ld);
315
        ierr = PSCopyMatrix_Private(ps,PS_MAT_Q,PS_MAT_A);CHKERRQ(ierr);
316
      }
317
      for (i=l;i<n;i++) d[i] = wr[i];
318
      break;
2819 jroman 319
    default:
320
      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong value of method: %d",ps->method);
321
  }
2796 jroman 322
  if (ps->compact) {
323
    ierr = PetscMemzero(e,(n-1)*sizeof(PetscReal));CHKERRQ(ierr);
324
  } else {
325
    ierr = PetscMemzero(A,ld*ld*sizeof(PetscScalar));CHKERRQ(ierr);
326
    for (i=0;i<n;i++) A[i+i*ld] = d[i];
327
  }
2783 jroman 328
  PetscFunctionReturn(0);
329
#endif
330
}
331
 
332
#undef __FUNCT__  
333
#define __FUNCT__ "PSSort_HEP"
334
PetscErrorCode PSSort_HEP(PS ps,PetscScalar *wr,PetscScalar *wi,PetscErrorCode (*comp_func)(PetscScalar,PetscScalar,PetscScalar,PetscScalar,PetscInt*,void*),void *comp_ctx)
335
{
336
  PetscErrorCode ierr;
2818 jroman 337
  PetscInt       n,l,i,*perm;
2792 jroman 338
  PetscScalar    *A;
2791 jroman 339
  PetscReal      *d;
2783 jroman 340
 
341
  PetscFunctionBegin;
2791 jroman 342
  n = ps->n;
2818 jroman 343
  l = ps->l;
2791 jroman 344
  d = ps->rmat[PS_MAT_T];
345
  ierr = PSAllocateWork_Private(ps,0,0,ps->ld);CHKERRQ(ierr);
2783 jroman 346
  perm = ps->iwork;
2818 jroman 347
  ierr = PSSortEigenvaluesReal_Private(ps,l,n,d,perm,comp_func,comp_ctx);CHKERRQ(ierr);
348
  for (i=l;i<n;i++) wr[i] = d[perm[i]];
349
  ierr = PSPermuteColumns_Private(ps,l,n,PS_MAT_Q,perm);CHKERRQ(ierr);
2796 jroman 350
  if (ps->compact) {
2818 jroman 351
    for (i=l;i<n;i++) d[i] = PetscRealPart(wr[i]);
2796 jroman 352
  } else {
353
    A  = ps->mat[PS_MAT_A];
2818 jroman 354
    for (i=l;i<n;i++) A[i+i*ps->ld] = wr[i];
2796 jroman 355
  }
2783 jroman 356
  PetscFunctionReturn(0);
357
}
358
 
359
#undef __FUNCT__  
360
#define __FUNCT__ "PSCond_HEP"
361
PetscErrorCode PSCond_HEP(PS ps,PetscReal *cond)
362
{
363
#if defined(PETSC_MISSING_LAPACK_GETRF) || defined(SLEPC_MISSING_LAPACK_GETRI) || defined(SLEPC_MISSING_LAPACK_LANGE) || defined(SLEPC_MISSING_LAPACK_LANHS)
364
  PetscFunctionBegin;
365
  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF/GETRI/LANGE/LANHS - Lapack routines are unavailable.");
366
#else
367
  PetscErrorCode ierr;
368
  PetscScalar    *work;
369
  PetscReal      *rwork;
370
  PetscBLASInt   *ipiv;
371
  PetscBLASInt   lwork,info,n,ld;
372
  PetscReal      hn,hin;
373
  PetscScalar    *A;
374
 
375
  PetscFunctionBegin;
376
  n  = PetscBLASIntCast(ps->n);
377
  ld = PetscBLASIntCast(ps->ld);
378
  lwork = 8*ld;
379
  ierr = PSAllocateWork_Private(ps,lwork,ld,ld);CHKERRQ(ierr);
380
  work  = ps->work;
381
  rwork = ps->rwork;
382
  ipiv  = ps->iwork;
2813 jroman 383
  ierr = PSSwitchFormat_HEP(ps,PETSC_FALSE);CHKERRQ(ierr);
2783 jroman 384
 
385
  /* use workspace matrix W to avoid overwriting A */
2793 jroman 386
  ierr = PSAllocateMat_Private(ps,PS_MAT_W);CHKERRQ(ierr);
2783 jroman 387
  A = ps->mat[PS_MAT_W];
388
  ierr = PetscMemcpy(A,ps->mat[PS_MAT_A],sizeof(PetscScalar)*ps->ld*ps->ld);CHKERRQ(ierr);
389
 
390
  /* norm of A */
391
  hn = LAPACKlange_("I",&n,&n,A,&ld,rwork);
392
 
393
  /* norm of inv(A) */
394
  LAPACKgetrf_(&n,&n,A,&ld,ipiv,&info);
395
  if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xGETRF %d",info);
396
  LAPACKgetri_(&n,A,&ld,ipiv,work,&lwork,&info);
397
  if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xGETRI %d",info);
398
  hin = LAPACKlange_("I",&n,&n,A,&ld,rwork);
399
 
400
  *cond = hn*hin;
401
  PetscFunctionReturn(0);
402
#endif
403
}
404
 
2814 jroman 405
#undef __FUNCT__  
406
#define __FUNCT__ "PSTranslateRKS_HEP"
407
PetscErrorCode PSTranslateRKS_HEP(PS ps,PetscScalar alpha)
408
{
409
#if defined(PETSC_MISSING_LAPACK_GEQRF) || defined(SLEPC_MISSING_LAPACK_ORGQR)
410
  PetscFunctionBegin;
411
  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GEQRF/ORGQR - Lapack routines are unavailable.");
412
#else
413
  PetscErrorCode ierr;
414
  PetscInt       i,j,k=ps->k;
415
  PetscScalar    *Q,*A,*R,*tau,*work;
416
  PetscBLASInt   ld,n1,n0,lwork,info;
417
 
418
  PetscFunctionBegin;
419
  ld = PetscBLASIntCast(ps->ld);
420
  ierr = PSAllocateWork_Private(ps,ld*ld,0,0);CHKERRQ(ierr);
421
  tau = ps->work;
422
  work = ps->work+ld;
423
  lwork = PetscBLASIntCast(ld*(ld-1));
424
  ierr = PSAllocateMat_Private(ps,PS_MAT_W);CHKERRQ(ierr);
425
  A  = ps->mat[PS_MAT_A];
426
  Q  = ps->mat[PS_MAT_Q];
427
  R  = ps->mat[PS_MAT_W];
428
  /* Copy I+alpha*A */
429
  ierr = PetscMemzero(Q,ld*ld*sizeof(PetscScalar));CHKERRQ(ierr);
430
  ierr = PetscMemzero(R,ld*ld*sizeof(PetscScalar));CHKERRQ(ierr);
431
  for (i=0;i<k;i++) {
432
    Q[i+i*ld] = 1.0 + alpha*A[i+i*ld];
433
    Q[k+i*ld] = alpha*A[k+i*ld];
434
  }
435
  /* Compute qr */
436
  n1 = PetscBLASIntCast(k+1);
437
  n0 = PetscBLASIntCast(k);
438
  LAPACKgeqrf_(&n1,&n0,Q,&ld,tau,work,&lwork,&info);
439
  if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xGEQRF %d",info);
440
  /* Copy R from Q */
441
  for (j=0;j<k;j++)
442
    for(i=0;i<=j;i++)
443
      R[i+j*ld] = Q[i+j*ld];
444
  /* Compute orthogonal matrix in Q */
445
  LAPACKorgqr_(&n1,&n1,&n0,Q,&ld,tau,work,&lwork,&info);
446
  if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in Lapack xORGQR %d",info);
447
  /* Compute the updated matrix of projected problem */
448
  for(j=0;j<k;j++){
449
    for(i=0;i<k+1;i++)
450
      A[j*ld+i] = Q[i*ld+j];
451
  }
452
  alpha = -1.0/alpha;
453
  BLAStrsm_("R","U","N","N",&n1,&n0,&alpha,R,&ld,A,&ld);
454
  for(i=0;i<k;i++)
455
    A[ld*i+i]-=alpha;
456
  PetscFunctionReturn(0);
457
#endif
458
}
459
 
2783 jroman 460
EXTERN_C_BEGIN
461
#undef __FUNCT__  
462
#define __FUNCT__ "PSCreate_HEP"
463
PetscErrorCode PSCreate_HEP(PS ps)
464
{
465
  PetscFunctionBegin;
2819 jroman 466
  ps->nmeth  = 2;
2783 jroman 467
  ps->ops->allocate      = PSAllocate_HEP;
468
  ps->ops->view          = PSView_HEP;
2807 jroman 469
  ps->ops->vectors       = PSVectors_HEP;
2783 jroman 470
  ps->ops->solve         = PSSolve_HEP;
471
  ps->ops->sort          = PSSort_HEP;
472
  ps->ops->cond          = PSCond_HEP;
2814 jroman 473
  ps->ops->transrks      = PSTranslateRKS_HEP;
2783 jroman 474
  PetscFunctionReturn(0);
475
}
476
EXTERN_C_END
477