Date: 2022-10-01T06:39:17+00:00

Actual source code: dspep.c
slepc-3.18.0 2022-10-01
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

      6:    This file is part of SLEPc.
      7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
      8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      9: */

     11: #include <slepc/private/dsimpl.h>
     12: #include <slepcblaslapack.h>

     14: typedef struct {
     15:   PetscInt  d;              /* polynomial degree */
     16:   PetscReal *pbc;           /* polynomial basis coefficients */
     17: } DS_PEP;

     19: PetscErrorCode DSAllocate_PEP(DS ds,PetscInt ld)
     20: {
     21:   DS_PEP         *ctx = (DS_PEP*)ds->data;
     22:   PetscInt       i;

     25:   DSAllocateMat_Private(ds,DS_MAT_X);
     26:   DSAllocateMat_Private(ds,DS_MAT_Y);
     27:   for (i=0;i<=ctx->d;i++) DSAllocateMat_Private(ds,DSMatExtra[i]);
     28:   PetscFree(ds->perm);
     29:   PetscMalloc1(ld*ctx->d,&ds->perm);
     30:   return 0;
     31: }

     33: PetscErrorCode DSView_PEP(DS ds,PetscViewer viewer)
     34: {
     35:   DS_PEP            *ctx = (DS_PEP*)ds->data;
     36:   PetscViewerFormat format;
     37:   PetscInt          i;

     39:   PetscViewerGetFormat(viewer,&format);
     40:   if (format == PETSC_VIEWER_ASCII_INFO) return 0;
     41:   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
     42:     PetscViewerASCIIPrintf(viewer,"polynomial degree: %" PetscInt_FMT "\n",ctx->d);
     43:     return 0;
     44:   }
     45:   for (i=0;i<=ctx->d;i++) DSViewMat(ds,viewer,DSMatExtra[i]);
     46:   if (ds->state>DS_STATE_INTERMEDIATE) DSViewMat(ds,viewer,DS_MAT_X);
     47:   return 0;
     48: }

     50: PetscErrorCode DSVectors_PEP(DS ds,DSMatType mat,PetscInt *j,PetscReal *rnorm)
     51: {
     53:   switch (mat) {
     54:     case DS_MAT_X:
     55:       break;
     56:     case DS_MAT_Y:
     57:       break;
     58:     default:
     59:       SETERRQ(PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Invalid mat parameter");
     60:   }
     61:   return 0;
     62: }

     64: PetscErrorCode DSSort_PEP(DS ds,PetscScalar *wr,PetscScalar *wi,PetscScalar *rr,PetscScalar *ri,PetscInt *kout)
     65: {
     66:   DS_PEP         *ctx = (DS_PEP*)ds->data;
     67:   PetscInt       n,i,*perm,told;
     68:   PetscScalar    *A;

     70:   if (!ds->sc) return 0;
     71:   n = ds->n*ctx->d;
     72:   perm = ds->perm;
     73:   for (i=0;i<n;i++) perm[i] = i;
     74:   told = ds->t;
     75:   ds->t = n;  /* force the sorting routines to consider d*n eigenvalues */
     76:   if (rr) DSSortEigenvalues_Private(ds,rr,ri,perm,PETSC_FALSE);
     77:   else DSSortEigenvalues_Private(ds,wr,wi,perm,PETSC_FALSE);
     78:   ds->t = told;  /* restore value of t */
     79:   MatDenseGetArray(ds->omat[DS_MAT_A],&A);
     80:   for (i=0;i<n;i++) A[i]  = wr[perm[i]];
     81:   for (i=0;i<n;i++) wr[i] = A[i];
     82:   for (i=0;i<n;i++) A[i]  = wi[perm[i]];
     83:   for (i=0;i<n;i++) wi[i] = A[i];
     84:   MatDenseRestoreArray(ds->omat[DS_MAT_A],&A);
     85:   DSPermuteColumnsTwo_Private(ds,0,n,ds->n,DS_MAT_X,DS_MAT_Y,perm);
     86:   return 0;
     87: }

     89: PetscErrorCode DSSolve_PEP_QZ(DS ds,PetscScalar *wr,PetscScalar *wi)
     90: {
     91:   DS_PEP            *ctx = (DS_PEP*)ds->data;
     92:   PetscInt          i,j,k,off;
     93:   PetscScalar       *A,*B,*W,*X,*U,*Y,*work,*beta;
     94:   const PetscScalar *Ed,*Ei;
     95:   PetscReal         *ca,*cb,*cg,norm,done=1.0;
     96:   PetscBLASInt      info,n,ld,ldd,nd,lrwork=0,lwork,one=1,zero=0,cols;
     97: #if defined(PETSC_USE_COMPLEX)
     98:   PetscReal         *rwork;
     99: #endif

    101:   PetscBLASIntCast(ds->n*ctx->d,&nd);
    102:   PetscBLASIntCast(ds->n,&n);
    103:   PetscBLASIntCast(ds->ld,&ld);
    104:   PetscBLASIntCast(ds->ld*ctx->d,&ldd);
    105: #if defined(PETSC_USE_COMPLEX)
    106:   PetscBLASIntCast(nd+2*nd,&lwork);
    107:   PetscBLASIntCast(8*nd,&lrwork);
    108: #else
    109:   PetscBLASIntCast(nd+8*nd,&lwork);
    110: #endif
    111:   DSAllocateWork_Private(ds,lwork,lrwork,0);
    112:   beta = ds->work;
    113:   work = ds->work + nd;
    114:   lwork -= nd;
    115:   DSAllocateMat_Private(ds,DS_MAT_A);
    116:   DSAllocateMat_Private(ds,DS_MAT_B);
    117:   DSAllocateMat_Private(ds,DS_MAT_W);
    118:   DSAllocateMat_Private(ds,DS_MAT_U);
    119:   MatDenseGetArray(ds->omat[DS_MAT_A],&A);
    120:   MatDenseGetArray(ds->omat[DS_MAT_B],&B);

    122:   /* build matrices A and B of the linearization */
    123:   MatDenseGetArrayRead(ds->omat[DSMatExtra[ctx->d]],&Ed);
    124:   PetscArrayzero(A,ldd*ldd);
    125:   if (!ctx->pbc) { /* monomial basis */
    126:     for (i=0;i<nd-ds->n;i++) A[i+(i+ds->n)*ldd] = 1.0;
    127:     for (i=0;i<ctx->d;i++) {
    128:       MatDenseGetArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    129:       off = i*ds->n*ldd+(ctx->d-1)*ds->n;
    130:       for (j=0;j<ds->n;j++) PetscArraycpy(A+off+j*ldd,Ei+j*ds->ld,ds->n);
    131:       MatDenseRestoreArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    132:     }
    133:   } else {
    134:     ca = ctx->pbc;
    135:     cb = ca+ctx->d+1;
    136:     cg = cb+ctx->d+1;
    137:     for (i=0;i<ds->n;i++) {
    138:       A[i+(i+ds->n)*ldd] = ca[0];
    139:       A[i+i*ldd] = cb[0];
    140:     }
    141:     for (;i<nd-ds->n;i++) {
    142:       j = i/ds->n;
    143:       A[i+(i+ds->n)*ldd] = ca[j];
    144:       A[i+i*ldd] = cb[j];
    145:       A[i+(i-ds->n)*ldd] = cg[j];
    146:     }
    147:     for (i=0;i<ctx->d-2;i++) {
    148:       MatDenseGetArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    149:       off = i*ds->n*ldd+(ctx->d-1)*ds->n;
    150:       for (j=0;j<ds->n;j++)
    151:         for (k=0;k<ds->n;k++)
    152:           A[off+j*ldd+k] = Ei[j*ds->ld+k]*ca[ctx->d-1];
    153:       MatDenseRestoreArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    154:     }
    155:     MatDenseGetArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    156:     off = i*ds->n*ldd+(ctx->d-1)*ds->n;
    157:     for (j=0;j<ds->n;j++)
    158:       for (k=0;k<ds->n;k++)
    159:         A[off+j*ldd+k] = Ei[j*ds->ld+k]*ca[ctx->d-1]-Ed[j*ds->ld+k]*cg[ctx->d-1];
    160:     MatDenseRestoreArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    161:     i++;
    162:     MatDenseGetArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    163:     off = i*ds->n*ldd+(ctx->d-1)*ds->n;
    164:     for (j=0;j<ds->n;j++)
    165:       for (k=0;k<ds->n;k++)
    166:         A[off+j*ldd+k] = Ei[j*ds->ld+k]*ca[ctx->d-1]-Ed[j*ds->ld+k]*cb[ctx->d-1];
    167:     MatDenseRestoreArrayRead(ds->omat[DSMatExtra[i]],&Ei);
    168:   }
    169:   PetscArrayzero(B,ldd*ldd);
    170:   for (i=0;i<nd-ds->n;i++) B[i+i*ldd] = 1.0;
    171:   off = (ctx->d-1)*ds->n*(ldd+1);
    172:   for (j=0;j<ds->n;j++) {
    173:     for (i=0;i<ds->n;i++) B[off+i+j*ldd] = -Ed[i+j*ds->ld];
    174:   }
    175:   MatDenseRestoreArrayRead(ds->omat[DSMatExtra[ctx->d]],&Ed);

    177:   /* solve generalized eigenproblem */
    178:   MatDenseGetArray(ds->omat[DS_MAT_W],&W);
    179:   MatDenseGetArray(ds->omat[DS_MAT_U],&U);
    180: #if defined(PETSC_USE_COMPLEX)
    181:   rwork = ds->rwork;
    182:   PetscCallBLAS("LAPACKggev",LAPACKggev_("V","V",&nd,A,&ldd,B,&ldd,wr,beta,U,&ldd,W,&ldd,work,&lwork,rwork,&info));
    183: #else
    184:   PetscCallBLAS("LAPACKggev",LAPACKggev_("V","V",&nd,A,&ldd,B,&ldd,wr,wi,beta,U,&ldd,W,&ldd,work,&lwork,&info));
    185: #endif
    186:   SlepcCheckLapackInfo("ggev",info);
    187:   MatDenseRestoreArray(ds->omat[DS_MAT_A],&A);
    188:   MatDenseRestoreArray(ds->omat[DS_MAT_B],&B);

    190:   /* copy eigenvalues */
    191:   for (i=0;i<nd;i++) {
    192:     if (beta[i]==0.0) wr[i] = (PetscRealPart(wr[i])>0.0)? PETSC_MAX_REAL: PETSC_MIN_REAL;
    193:     else wr[i] /= beta[i];
    194: #if !defined(PETSC_USE_COMPLEX)
    195:     if (beta[i]==0.0) wi[i] = 0.0;
    196:     else wi[i] /= beta[i];
    197: #else
    198:     if (wi) wi[i] = 0.0;
    199: #endif
    200:   }

    202:   /* copy and normalize eigenvectors */
    203:   MatDenseGetArray(ds->omat[DS_MAT_X],&X);
    204:   MatDenseGetArray(ds->omat[DS_MAT_Y],&Y);
    205:   for (j=0;j<nd;j++) {
    206:     PetscArraycpy(X+j*ds->ld,W+j*ldd,ds->n);
    207:     PetscArraycpy(Y+j*ds->ld,U+ds->n*(ctx->d-1)+j*ldd,ds->n);
    208:   }
    209:   MatDenseRestoreArray(ds->omat[DS_MAT_W],&W);
    210:   MatDenseRestoreArray(ds->omat[DS_MAT_U],&U);
    211:   for (j=0;j<nd;j++) {
    212:     cols = 1;
    213:     norm = BLASnrm2_(&n,X+j*ds->ld,&one);
    214: #if !defined(PETSC_USE_COMPLEX)
    215:     if (wi[j] != 0.0) {
    216:       norm = SlepcAbsEigenvalue(norm,BLASnrm2_(&n,X+(j+1)*ds->ld,&one));
    217:       cols = 2;
    218:     }
    219: #endif
    220:     PetscCallBLAS("LAPACKlascl",LAPACKlascl_("G",&zero,&zero,&norm,&done,&n,&cols,X+j*ds->ld,&ld,&info));
    221:     SlepcCheckLapackInfo("lascl",info);
    222:     norm = BLASnrm2_(&n,Y+j*ds->ld,&one);
    223: #if !defined(PETSC_USE_COMPLEX)
    224:     if (wi[j] != 0.0) norm = SlepcAbsEigenvalue(norm,BLASnrm2_(&n,Y+(j+1)*ds->ld,&one));
    225: #endif
    226:     PetscCallBLAS("LAPACKlascl",LAPACKlascl_("G",&zero,&zero,&norm,&done,&n,&cols,Y+j*ds->ld,&ld,&info));
    227:     SlepcCheckLapackInfo("lascl",info);
    228: #if !defined(PETSC_USE_COMPLEX)
    229:     if (wi[j] != 0.0) j++;
    230: #endif
    231:   }
    232:   MatDenseRestoreArray(ds->omat[DS_MAT_X],&X);
    233:   MatDenseRestoreArray(ds->omat[DS_MAT_Y],&Y);
    234:   return 0;
    235: }

    237: PetscErrorCode DSSynchronize_PEP(DS ds,PetscScalar eigr[],PetscScalar eigi[])
    238: {
    239:   DS_PEP         *ctx = (DS_PEP*)ds->data;
    240:   PetscInt       ld=ds->ld,k=0;
    241:   PetscMPIInt    ldnd,rank,off=0,size,dn;
    242:   PetscScalar    *X,*Y;

    244:   if (ds->state>=DS_STATE_CONDENSED) k += 2*ctx->d*ds->n*ld;
    245:   if (eigr) k += ctx->d*ds->n;
    246:   if (eigi) k += ctx->d*ds->n;
    247:   DSAllocateWork_Private(ds,k,0,0);
    248:   PetscMPIIntCast(k*sizeof(PetscScalar),&size);
    249:   PetscMPIIntCast(ds->n*ctx->d*ld,&ldnd);
    250:   PetscMPIIntCast(ctx->d*ds->n,&dn);
    251:   if (ds->state>=DS_STATE_CONDENSED) {
    252:     MatDenseGetArray(ds->omat[DS_MAT_X],&X);
    253:     MatDenseGetArray(ds->omat[DS_MAT_Y],&Y);
    254:   }
    255:   MPI_Comm_rank(PetscObjectComm((PetscObject)ds),&rank);
    256:   if (!rank) {
    257:     if (ds->state>=DS_STATE_CONDENSED) {
    258:       MPI_Pack(X,ldnd,MPIU_SCALAR,ds->work,size,&off,PetscObjectComm((PetscObject)ds));
    259:       MPI_Pack(Y,ldnd,MPIU_SCALAR,ds->work,size,&off,PetscObjectComm((PetscObject)ds));
    260:     }
    261:     if (eigr) MPI_Pack(eigr,dn,MPIU_SCALAR,ds->work,size,&off,PetscObjectComm((PetscObject)ds));
    262: #if !defined(PETSC_USE_COMPLEX)
    263:     if (eigi) MPI_Pack(eigi,dn,MPIU_SCALAR,ds->work,size,&off,PetscObjectComm((PetscObject)ds));
    264: #endif
    265:   }
    266:   MPI_Bcast(ds->work,size,MPI_BYTE,0,PetscObjectComm((PetscObject)ds));
    267:   if (rank) {
    268:     if (ds->state>=DS_STATE_CONDENSED) {
    269:       MPI_Unpack(ds->work,size,&off,X,ldnd,MPIU_SCALAR,PetscObjectComm((PetscObject)ds));
    270:       MPI_Unpack(ds->work,size,&off,Y,ldnd,MPIU_SCALAR,PetscObjectComm((PetscObject)ds));
    271:     }
    272:     if (eigr) MPI_Unpack(ds->work,size,&off,eigr,dn,MPIU_SCALAR,PetscObjectComm((PetscObject)ds));
    273: #if !defined(PETSC_USE_COMPLEX)
    274:     if (eigi) MPI_Unpack(ds->work,size,&off,eigi,dn,MPIU_SCALAR,PetscObjectComm((PetscObject)ds));
    275: #endif
    276:   }
    277:   if (ds->state>=DS_STATE_CONDENSED) {
    278:     MatDenseRestoreArray(ds->omat[DS_MAT_X],&X);
    279:     MatDenseRestoreArray(ds->omat[DS_MAT_Y],&Y);
    280:   }
    281:   return 0;
    282: }

    284: static PetscErrorCode DSPEPSetDegree_PEP(DS ds,PetscInt d)
    285: {
    286:   DS_PEP *ctx = (DS_PEP*)ds->data;

    290:   ctx->d = d;
    291:   return 0;
    292: }

    294: /*@
    295:    DSPEPSetDegree - Sets the polynomial degree for a DSPEP.

    297:    Logically Collective on ds

    299:    Input Parameters:
    300: +  ds - the direct solver context
    301: -  d  - the degree

    303:    Level: intermediate

    305: .seealso: DSPEPGetDegree()
    306: @*/
    307: PetscErrorCode DSPEPSetDegree(DS ds,PetscInt d)
    308: {
    311:   PetscTryMethod(ds,"DSPEPSetDegree_C",(DS,PetscInt),(ds,d));
    312:   return 0;
    313: }

    315: static PetscErrorCode DSPEPGetDegree_PEP(DS ds,PetscInt *d)
    316: {
    317:   DS_PEP *ctx = (DS_PEP*)ds->data;

    319:   *d = ctx->d;
    320:   return 0;
    321: }

    323: /*@
    324:    DSPEPGetDegree - Returns the polynomial degree for a DSPEP.

    326:    Not collective

    328:    Input Parameter:
    329: .  ds - the direct solver context

    331:    Output Parameters:
    332: .  d - the degree

    334:    Level: intermediate

    336: .seealso: DSPEPSetDegree()
    337: @*/
    338: PetscErrorCode DSPEPGetDegree(DS ds,PetscInt *d)
    339: {
    342:   PetscUseMethod(ds,"DSPEPGetDegree_C",(DS,PetscInt*),(ds,d));
    343:   return 0;
    344: }

    346: static PetscErrorCode DSPEPSetCoefficients_PEP(DS ds,PetscReal *pbc)
    347: {
    348:   DS_PEP         *ctx = (DS_PEP*)ds->data;
    349:   PetscInt       i;

    352:   if (ctx->pbc) PetscFree(ctx->pbc);
    353:   PetscMalloc1(3*(ctx->d+1),&ctx->pbc);
    354:   for (i=0;i<3*(ctx->d+1);i++) ctx->pbc[i] = pbc[i];
    355:   ds->state = DS_STATE_RAW;
    356:   return 0;
    357: }

    359: /*@C
    360:    DSPEPSetCoefficients - Sets the polynomial basis coefficients for a DSPEP.

    362:    Logically Collective on ds

    364:    Input Parameters:
    365: +  ds  - the direct solver context
    366: -  pbc - the polynomial basis coefficients

    368:    Notes:
    369:    This function is required only in the case of a polynomial specified in a
    370:    non-monomial basis, to provide the coefficients that will be used
    371:    during the linearization, multiplying the identity blocks on the three main
    372:    diagonal blocks. Depending on the polynomial basis (Chebyshev, Legendre, ...)
    373:    the coefficients must be different.

    375:    There must be a total of 3*(d+1) coefficients, where d is the degree of the
    376:    polynomial. The coefficients are arranged in three groups, alpha, beta, and
    377:    gamma, according to the definition of the three-term recurrence. In the case
    378:    of the monomial basis, alpha=1 and beta=gamma=0, in which case it is not
    379:    necessary to invoke this function.

    381:    Level: advanced

    383: .seealso: DSPEPGetCoefficients(), DSPEPSetDegree()
    384: @*/
    385: PetscErrorCode DSPEPSetCoefficients(DS ds,PetscReal *pbc)
    386: {
    388:   PetscTryMethod(ds,"DSPEPSetCoefficients_C",(DS,PetscReal*),(ds,pbc));
    389:   return 0;
    390: }

    392: static PetscErrorCode DSPEPGetCoefficients_PEP(DS ds,PetscReal **pbc)
    393: {
    394:   DS_PEP         *ctx = (DS_PEP*)ds->data;
    395:   PetscInt       i;

    398:   PetscCalloc1(3*(ctx->d+1),pbc);
    399:   if (ctx->pbc) for (i=0;i<3*(ctx->d+1);i++) (*pbc)[i] = ctx->pbc[i];
    400:   else for (i=0;i<ctx->d+1;i++) (*pbc)[i] = 1.0;
    401:   return 0;
    402: }

    404: /*@C
    405:    DSPEPGetCoefficients - Returns the polynomial basis coefficients for a DSPEP.

    407:    Not collective

    409:    Input Parameter:
    410: .  ds - the direct solver context

    412:    Output Parameters:
    413: .  pbc - the polynomial basis coefficients

    415:    Note:
    416:    The returned array has length 3*(d+1) and should be freed by the user.

    418:    Fortran Notes:
    419:    The calling sequence from Fortran is
    420: .vb
    421:    DSPEPGetCoefficients(eps,pbc,ierr)
    422:    double precision pbc(d+1) output
    423: .ve

    425:    Level: advanced

    427: .seealso: DSPEPSetCoefficients()
    428: @*/
    429: PetscErrorCode DSPEPGetCoefficients(DS ds,PetscReal **pbc)
    430: {
    433:   PetscUseMethod(ds,"DSPEPGetCoefficients_C",(DS,PetscReal**),(ds,pbc));
    434:   return 0;
    435: }

    437: PetscErrorCode DSDestroy_PEP(DS ds)
    438: {
    439:   DS_PEP         *ctx = (DS_PEP*)ds->data;

    441:   if (ctx->pbc) PetscFree(ctx->pbc);
    442:   PetscFree(ds->data);
    443:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPSetDegree_C",NULL);
    444:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPGetDegree_C",NULL);
    445:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPSetCoefficients_C",NULL);
    446:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPGetCoefficients_C",NULL);
    447:   return 0;
    448: }

    450: PetscErrorCode DSMatGetSize_PEP(DS ds,DSMatType t,PetscInt *rows,PetscInt *cols)
    451: {
    452:   DS_PEP *ctx = (DS_PEP*)ds->data;

    455:   *rows = ds->n;
    456:   if (t==DS_MAT_A || t==DS_MAT_B || t==DS_MAT_W || t==DS_MAT_U) *rows *= ctx->d;
    457:   *cols = ds->n;
    458:   if (t==DS_MAT_A || t==DS_MAT_B || t==DS_MAT_W || t==DS_MAT_U || t==DS_MAT_X || t==DS_MAT_Y) *cols *= ctx->d;
    459:   return 0;
    460: }

    462: /*MC
    463:    DSPEP - Dense Polynomial Eigenvalue Problem.

    465:    Level: beginner

    467:    Notes:
    468:    The problem is expressed as P(lambda)*x = 0, where P(.) is a matrix
    469:    polynomial of degree d. The eigenvalues lambda are the arguments
    470:    returned by DSSolve().

    472:    The degree of the polynomial, d, can be set with DSPEPSetDegree(), with
    473:    the first d+1 extra matrices of the DS defining the matrix polynomial. By
    474:    default, the polynomial is expressed in the monomial basis, but a
    475:    different basis can be used by setting the corresponding coefficients
    476:    via DSPEPSetCoefficients().

    478:    The problem is solved via linearization, by building a pencil (A,B) of
    479:    size p*n and solving the corresponding GNHEP.

    481:    Used DS matrices:
    482: +  DS_MAT_Ex - coefficients of the matrix polynomial
    483: .  DS_MAT_A  - (workspace) first matrix of the linearization
    484: .  DS_MAT_B  - (workspace) second matrix of the linearization
    485: .  DS_MAT_W  - (workspace) right eigenvectors of the linearization
    486: -  DS_MAT_U  - (workspace) left eigenvectors of the linearization

    488:    Implemented methods:
    489: .  0 - QZ iteration on the linearization (_ggev)

    491: .seealso: DSCreate(), DSSetType(), DSType, DSPEPSetDegree(), DSPEPSetCoefficients()
    492: M*/
    493: SLEPC_EXTERN PetscErrorCode DSCreate_PEP(DS ds)
    494: {
    495:   DS_PEP         *ctx;

    497:   PetscNew(&ctx);
    498:   ds->data = (void*)ctx;

    500:   ds->ops->allocate      = DSAllocate_PEP;
    501:   ds->ops->view          = DSView_PEP;
    502:   ds->ops->vectors       = DSVectors_PEP;
    503:   ds->ops->solve[0]      = DSSolve_PEP_QZ;
    504:   ds->ops->sort          = DSSort_PEP;
    505:   ds->ops->synchronize   = DSSynchronize_PEP;
    506:   ds->ops->destroy       = DSDestroy_PEP;
    507:   ds->ops->matgetsize    = DSMatGetSize_PEP;
    508:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPSetDegree_C",DSPEPSetDegree_PEP);
    509:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPGetDegree_C",DSPEPGetDegree_PEP);
    510:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPSetCoefficients_C",DSPEPSetCoefficients_PEP);
    511:   PetscObjectComposeFunction((PetscObject)ds,"DSPEPGetCoefficients_C",DSPEPGetCoefficients_PEP);
    512:   return 0;
    513: }