Subversion Repositories slepc-dev

Rev

Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2102 Rev 2116
/*                      
/*                      
 
 
   SLEPc eigensolver: "power"
   SLEPc eigensolver: "power"
 
 
   Method: Power Iteration
   Method: Power Iteration
 
 
   Algorithm:
   Algorithm:
 
 
       This solver implements the power iteration for finding dominant
       This solver implements the power iteration for finding dominant
       eigenpairs. It also includes the following well-known methods:
       eigenpairs. It also includes the following well-known methods:
       - Inverse Iteration: when used in combination with shift-and-invert
       - Inverse Iteration: when used in combination with shift-and-invert
         spectral transformation.
         spectral transformation.
       - Rayleigh Quotient Iteration (RQI): also with shift-and-invert plus
       - Rayleigh Quotient Iteration (RQI): also with shift-and-invert plus
         a variable shift.
         a variable shift.
 
 
   References:
   References:
 
 
       [1] "Single Vector Iteration Methods in SLEPc", SLEPc Technical Report STR-2,
       [1] "Single Vector Iteration Methods in SLEPc", SLEPc Technical Report STR-2,
           available at http://www.grycap.upv.es/slepc.
           available at http://www.grycap.upv.es/slepc.
 
 
   Last update: Feb 2009
   Last update: Feb 2009
 
 
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   SLEPc - Scalable Library for Eigenvalue Problem Computations
   SLEPc - Scalable Library for Eigenvalue Problem Computations
   Copyright (c) 2002-2009, Universidad Politecnica de Valencia, Spain
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
 
 
   This file is part of SLEPc.
   This file is part of SLEPc.
     
     
   SLEPc is free software: you can redistribute it and/or modify it under  the
   SLEPc is free software: you can redistribute it and/or modify it under  the
   terms of version 3 of the GNU Lesser General Public License as published by
   terms of version 3 of the GNU Lesser General Public License as published by
   the Free Software Foundation.
   the Free Software Foundation.
 
 
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
   more details.
   more details.
 
 
   You  should have received a copy of the GNU Lesser General  Public  License
   You  should have received a copy of the GNU Lesser General  Public  License
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
 
 
#include "private/epsimpl.h"                /*I "slepceps.h" I*/
#include "private/epsimpl.h"                /*I "slepceps.h" I*/
#include "slepcblaslapack.h"
#include "slepcblaslapack.h"
 
 
PetscErrorCode EPSSolve_POWER(EPS);
PetscErrorCode EPSSolve_POWER(EPS);
PetscErrorCode EPSSolve_TS_POWER(EPS);
PetscErrorCode EPSSolve_TS_POWER(EPS);
 
 
typedef struct {
typedef struct {
  EPSPowerShiftType shift_type;
  EPSPowerShiftType shift_type;
} EPS_POWER;
} EPS_POWER;
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSSetUp_POWER"
#define __FUNCT__ "EPSSetUp_POWER"
PetscErrorCode EPSSetUp_POWER(EPS eps)
PetscErrorCode EPSSetUp_POWER(EPS eps)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  PetscTruth     flg;
  PetscTruth     flg;
  STMatMode      mode;
  STMatMode      mode;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  if (eps->ncv) {
  if (eps->ncv) {
    if (eps->ncv<eps->nev) SETERRQ(1,"The value of ncv must be at least nev");
    if (eps->ncv<eps->nev) SETERRQ(1,"The value of ncv must be at least nev");
  }
  }
  else eps->ncv = eps->nev;
  else eps->ncv = eps->nev;
  if (eps->mpd) PetscInfo(eps,"Warning: parameter mpd ignored\n");
  if (eps->mpd) PetscInfo(eps,"Warning: parameter mpd ignored\n");
  if (!eps->max_it) eps->max_it = PetscMax(2000,100*eps->n);
  if (!eps->max_it) eps->max_it = PetscMax(2000,100*eps->n);
  if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE;
  if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE;
  if (eps->which!=EPS_LARGEST_MAGNITUDE)
  if (eps->which!=EPS_LARGEST_MAGNITUDE)
    SETERRQ(1,"Wrong value of eps->which");
    SETERRQ(1,"Wrong value of eps->which");
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT) {
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT) {
    ierr = PetscTypeCompare((PetscObject)eps->OP,STSINVERT,&flg);CHKERRQ(ierr);
    ierr = PetscTypeCompare((PetscObject)eps->OP,STSINVERT,&flg);CHKERRQ(ierr);
    if (!flg)
    if (!flg)
      SETERRQ(PETSC_ERR_SUP,"Variable shifts only allowed in shift-and-invert ST");
      SETERRQ(PETSC_ERR_SUP,"Variable shifts only allowed in shift-and-invert ST");
    ierr = STGetMatMode(eps->OP,&mode);CHKERRQ(ierr);
    ierr = STGetMatMode(eps->OP,&mode);CHKERRQ(ierr);
    if (mode == ST_MATMODE_INPLACE)
    if (mode == ST_MATMODE_INPLACE)
      SETERRQ(PETSC_ERR_SUP,"ST matrix mode inplace does not work with variable shifts");
      SETERRQ(PETSC_ERR_SUP,"ST matrix mode inplace does not work with variable shifts");
  }
  }
  if (eps->extraction) {
  if (eps->extraction) {
     ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr);
     ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr);
  }
  }
  if (eps->balance!=EPS_BALANCE_NONE)
  if (eps->balance!=EPS_BALANCE_NONE)
    SETERRQ(PETSC_ERR_SUP,"Balancing not supported in this solver");
    SETERRQ(PETSC_ERR_SUP,"Balancing not supported in this solver");
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
  if (eps->leftvecs) {
  if (eps->leftvecs) {
    ierr = EPSDefaultGetWork(eps,3);CHKERRQ(ierr);
    ierr = EPSDefaultGetWork(eps,3);CHKERRQ(ierr);
  } else {
  } else {
    ierr = EPSDefaultGetWork(eps,2);CHKERRQ(ierr);
    ierr = EPSDefaultGetWork(eps,2);CHKERRQ(ierr);
  }
  }
 
 
  /* dispatch solve method */
  /* dispatch solve method */
  if (eps->leftvecs) eps->ops->solve = EPSSolve_TS_POWER;
  if (eps->leftvecs) eps->ops->solve = EPSSolve_TS_POWER;
  else eps->ops->solve = EPSSolve_POWER;
  else eps->ops->solve = EPSSolve_POWER;
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSSolve_POWER"
#define __FUNCT__ "EPSSolve_POWER"
PetscErrorCode EPSSolve_POWER(EPS eps)
PetscErrorCode EPSSolve_POWER(EPS eps)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  PetscInt       i;
  PetscInt       i;
  Vec            v, y, e;
  Vec            v, y, e;
  Mat            A;
  Mat            A;
  PetscReal      relerr, norm, rt1, rt2, cs1, anorm;
  PetscReal      relerr, norm, rt1, rt2, cs1, anorm;
  PetscScalar    theta, rho, delta, sigma, alpha2, beta1, sn1;
  PetscScalar    theta, rho, delta, sigma, alpha2, beta1, sn1;
  PetscTruth     breakdown,*select = PETSC_NULL,hasnorm;
  PetscTruth     breakdown,*select = PETSC_NULL,hasnorm;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  v = eps->V[0];
  v = eps->V[0];
  y = eps->work[1];
  y = eps->work[1];
  e = eps->work[0];
  e = eps->work[0];
 
 
  /* prepare for selective orthogonalization of converged vectors */
  /* prepare for selective orthogonalization of converged vectors */
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT && eps->nev>1) {
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT && eps->nev>1) {
    ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
    ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
    ierr = MatHasOperation(A,MATOP_NORM,&hasnorm);CHKERRQ(ierr);
    ierr = MatHasOperation(A,MATOP_NORM,&hasnorm);CHKERRQ(ierr);
    if (hasnorm) {
    if (hasnorm) {
      ierr = MatNorm(A,NORM_INFINITY,&anorm);CHKERRQ(ierr);
      ierr = MatNorm(A,NORM_INFINITY,&anorm);CHKERRQ(ierr);
      ierr = PetscMalloc(eps->nev*sizeof(PetscTruth),&select);CHKERRQ(ierr);
      ierr = PetscMalloc(eps->nev*sizeof(PetscTruth),&select);CHKERRQ(ierr);
    }
    }
  }
  }
 
 
  ierr = EPSGetStartVector(eps,0,v,PETSC_NULL);CHKERRQ(ierr);
  ierr = EPSGetStartVector(eps,0,v,PETSC_NULL);CHKERRQ(ierr);
  ierr = STGetShift(eps->OP,&sigma);CHKERRQ(ierr);    /* original shift */
  ierr = STGetShift(eps->OP,&sigma);CHKERRQ(ierr);    /* original shift */
  rho = sigma;
  rho = sigma;
 
 
  while (eps->reason == EPS_CONVERGED_ITERATING) {
  while (eps->reason == EPS_CONVERGED_ITERATING) {
    eps->its = eps->its + 1;
    eps->its = eps->its + 1;
 
 
    /* y = OP v */
    /* y = OP v */
    ierr = STApply(eps->OP,v,y);CHKERRQ(ierr);
    ierr = STApply(eps->OP,v,y);CHKERRQ(ierr);
 
 
    /* theta = (v,y)_B */
    /* theta = (v,y)_B */
    ierr = IPInnerProduct(eps->ip,v,y,&theta);CHKERRQ(ierr);
    ierr = IPInnerProduct(eps->ip,v,y,&theta);CHKERRQ(ierr);
 
 
    if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
    if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
 
 
      /* approximate eigenvalue is the Rayleigh quotient */
      /* approximate eigenvalue is the Rayleigh quotient */
      eps->eigr[eps->nconv] = theta;
      eps->eigr[eps->nconv] = theta;
 
 
      /* compute relative error as ||y-theta v||_2/|theta| */
      /* compute relative error as ||y-theta v||_2/|theta| */
      ierr = VecCopy(y,e);CHKERRQ(ierr);
      ierr = VecCopy(y,e);CHKERRQ(ierr);
      ierr = VecAXPY(e,-theta,v);CHKERRQ(ierr);
      ierr = VecAXPY(e,-theta,v);CHKERRQ(ierr);
      ierr = VecNorm(e,NORM_2,&norm);CHKERRQ(ierr);
      ierr = VecNorm(e,NORM_2,&norm);CHKERRQ(ierr);
      relerr = norm / PetscAbsScalar(theta);
      relerr = norm / PetscAbsScalar(theta);
 
 
    } else {  /* RQI */
    } else {  /* RQI */
 
 
      /* delta = ||y||_B */
      /* delta = ||y||_B */
      ierr = IPNorm(eps->ip,y,&norm);CHKERRQ(ierr);
      ierr = IPNorm(eps->ip,y,&norm);CHKERRQ(ierr);
      delta = norm;
      delta = norm;
 
 
      /* compute relative error */
      /* compute relative error */
      if (rho == 0.0) relerr = PETSC_MAX;
      if (rho == 0.0) relerr = PETSC_MAX;
      else relerr = 1.0 / (norm*PetscAbsScalar(rho));
      else relerr = 1.0 / (norm*PetscAbsScalar(rho));
 
 
      /* approximate eigenvalue is the shift */
      /* approximate eigenvalue is the shift */
      eps->eigr[eps->nconv] = rho;
      eps->eigr[eps->nconv] = rho;
 
 
      /* compute new shift */
      /* compute new shift */
      if (relerr<eps->tol) {
      if (relerr<eps->tol) {
        rho = sigma; /* if converged, restore original shift */
        rho = sigma; /* if converged, restore original shift */
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
      } else {
      } else {
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v) */
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v) */
        if (power->shift_type == EPS_POWER_SHIFT_WILKINSON) {
        if (power->shift_type == EPS_POWER_SHIFT_WILKINSON) {
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
#else
#else
          /* beta1 is the norm of the residual associated to R(v) */
          /* beta1 is the norm of the residual associated to R(v) */
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
          ierr = VecScale(v,1.0/delta);CHKERRQ(ierr);
          ierr = VecScale(v,1.0/delta);CHKERRQ(ierr);
          ierr = IPNorm(eps->ip,v,&norm);CHKERRQ(ierr);
          ierr = IPNorm(eps->ip,v,&norm);CHKERRQ(ierr);
          beta1 = norm;
          beta1 = norm;
   
   
          /* alpha2 = (e'*A*e)/(beta1*beta1), where e is the residual */
          /* alpha2 = (e'*A*e)/(beta1*beta1), where e is the residual */
          ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
          ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
          ierr = MatMult(A,v,e);CHKERRQ(ierr);
          ierr = MatMult(A,v,e);CHKERRQ(ierr);
          ierr = VecDot(v,e,&alpha2);CHKERRQ(ierr);
          ierr = VecDot(v,e,&alpha2);CHKERRQ(ierr);
          alpha2 = alpha2 / (beta1 * beta1);
          alpha2 = alpha2 / (beta1 * beta1);
 
 
          /* choose the eigenvalue of [rho beta1; beta1 alpha2] closest to rho */
          /* choose the eigenvalue of [rho beta1; beta1 alpha2] closest to rho */
          LAPACKlaev2_(&rho,&beta1,&alpha2,&rt1,&rt2,&cs1,&sn1);
          LAPACKlaev2_(&rho,&beta1,&alpha2,&rt1,&rt2,&cs1,&sn1);
          if (PetscAbsScalar(rt1-rho) < PetscAbsScalar(rt2-rho)) rho = rt1;
          if (PetscAbsScalar(rt1-rho) < PetscAbsScalar(rt2-rho)) rho = rt1;
          else rho = rt2;
          else rho = rt2;
#endif
#endif
        }
        }
        /* update operator according to new shift */
        /* update operator according to new shift */
        PetscPushErrorHandler(PetscIgnoreErrorHandler,PETSC_NULL);
        PetscPushErrorHandler(PetscIgnoreErrorHandler,PETSC_NULL);
        ierr = STSetShift(eps->OP,rho);
        ierr = STSetShift(eps->OP,rho);
        PetscPopErrorHandler();
        PetscPopErrorHandler();
        if (ierr) {
        if (ierr) {
          eps->eigr[eps->nconv] = rho;
          eps->eigr[eps->nconv] = rho;
          relerr = PETSC_MACHINE_EPSILON;
          relerr = PETSC_MACHINE_EPSILON;
          rho = sigma;
          rho = sigma;
          ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
          ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
        }      
        }      
      }
      }
    }
    }
 
 
    eps->errest[eps->nconv] = relerr;
    eps->errest[eps->nconv] = relerr;
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,eps->nconv+1);
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,eps->nconv+1);
 
 
    /* purge previously converged eigenvectors */
    /* purge previously converged eigenvectors */
    if (select) {
    if (select) {
      for (i=0;i<eps->nconv;i++) {
      for (i=0;i<eps->nconv;i++) {
        if(PetscAbsScalar(rho-eps->eigr[i])>eps->its*anorm/1000) select[i] = PETSC_TRUE;
        if(PetscAbsScalar(rho-eps->eigr[i])>eps->its*anorm/1000) select[i] = PETSC_TRUE;
        else select[i] = PETSC_FALSE;
        else select[i] = PETSC_FALSE;
      }
      }
      ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,eps->nconv,select,eps->V,y,PETSC_NULL,&norm,PETSC_NULL);CHKERRQ(ierr);
      ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,eps->nconv,select,eps->V,y,PETSC_NULL,&norm,PETSC_NULL);CHKERRQ(ierr);
    } else {
    } else {
      ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,eps->nconv,PETSC_NULL,eps->V,y,PETSC_NULL,&norm,PETSC_NULL);CHKERRQ(ierr);
      ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,eps->nconv,PETSC_NULL,eps->V,y,PETSC_NULL,&norm,PETSC_NULL);CHKERRQ(ierr);
    }
    }
 
 
    /* v = y/||y||_B */
    /* v = y/||y||_B */
    ierr = VecCopy(y,v);CHKERRQ(ierr);
    ierr = VecCopy(y,v);CHKERRQ(ierr);
    ierr = VecScale(v,1.0/norm);CHKERRQ(ierr);
    ierr = VecScale(v,1.0/norm);CHKERRQ(ierr);
 
 
    /* if relerr<tol, accept eigenpair */
    /* if relerr<tol, accept eigenpair */
    if (relerr<eps->tol) {
    if (relerr<eps->tol) {
      eps->nconv = eps->nconv + 1;
      eps->nconv = eps->nconv + 1;
      if (eps->nconv==eps->nev) eps->reason = EPS_CONVERGED_TOL;
      if (eps->nconv==eps->nev) eps->reason = EPS_CONVERGED_TOL;
      else {
      else {
        v = eps->V[eps->nconv];
        v = eps->V[eps->nconv];
        ierr = EPSGetStartVector(eps,eps->nconv,v,&breakdown);CHKERRQ(ierr);
        ierr = EPSGetStartVector(eps,eps->nconv,v,&breakdown);CHKERRQ(ierr);
        if (breakdown) {
        if (breakdown) {
          eps->reason = EPS_DIVERGED_BREAKDOWN;
          eps->reason = EPS_DIVERGED_BREAKDOWN;
          PetscInfo(eps,"Unable to generate more start vectors\n");
          PetscInfo(eps,"Unable to generate more start vectors\n");
        }
        }
      }
      }
    }
    }
 
 
    if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
    if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
  }
  }
 
 
  ierr = PetscFree(select);CHKERRQ(ierr);
  ierr = PetscFree(select);CHKERRQ(ierr);
 
 
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSSolve_TS_POWER"
#define __FUNCT__ "EPSSolve_TS_POWER"
PetscErrorCode EPSSolve_TS_POWER(EPS eps)
PetscErrorCode EPSSolve_TS_POWER(EPS eps)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  Vec            v, w, y, z, e;
  Vec            v, w, y, z, e;
  Mat            A;
  Mat            A;
  PetscReal      relerr, norm, rt1, rt2, cs1;
  PetscReal      relerr, norm, rt1, rt2, cs1;
  PetscScalar    theta, alpha, beta, rho, delta, sigma, alpha2, beta1, sn1;
  PetscScalar    theta, alpha, beta, rho, delta, sigma, alpha2, beta1, sn1;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  v = eps->V[0];
  v = eps->V[0];
  y = eps->work[1];
  y = eps->work[1];
  e = eps->work[0];
  e = eps->work[0];
  w = eps->W[0];
  w = eps->W[0];
  z = eps->work[2];
  z = eps->work[2];
 
 
  ierr = EPSGetStartVector(eps,0,v,PETSC_NULL);CHKERRQ(ierr);
  ierr = EPSGetStartVector(eps,0,v,PETSC_NULL);CHKERRQ(ierr);
  ierr = EPSGetStartVectorLeft(eps,0,w,PETSC_NULL);CHKERRQ(ierr);
  ierr = EPSGetStartVectorLeft(eps,0,w,PETSC_NULL);CHKERRQ(ierr);
  ierr = STGetShift(eps->OP,&sigma);CHKERRQ(ierr);    /* original shift */
  ierr = STGetShift(eps->OP,&sigma);CHKERRQ(ierr);    /* original shift */
  rho = sigma;
  rho = sigma;
 
 
  while (eps->its<eps->max_it) {
  while (eps->its<eps->max_it) {
    eps->its++;
    eps->its++;
   
   
    /* y = OP v, z = OP' w */
    /* y = OP v, z = OP' w */
    ierr = STApply(eps->OP,v,y);CHKERRQ(ierr);
    ierr = STApply(eps->OP,v,y);CHKERRQ(ierr);
    ierr = STApplyTranspose(eps->OP,w,z);CHKERRQ(ierr);
    ierr = STApplyTranspose(eps->OP,w,z);CHKERRQ(ierr);
 
 
    /* theta = (v,z)_B */
    /* theta = (v,z)_B */
    ierr = IPInnerProduct(eps->ip,v,z,&theta);CHKERRQ(ierr);
    ierr = IPInnerProduct(eps->ip,v,z,&theta);CHKERRQ(ierr);
 
 
    if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
    if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
 
 
      /* approximate eigenvalue is the Rayleigh quotient */
      /* approximate eigenvalue is the Rayleigh quotient */
      eps->eigr[eps->nconv] = theta;
      eps->eigr[eps->nconv] = theta;
 
 
      /* compute relative errors (right and left) */
      /* compute relative errors (right and left) */
      ierr = VecCopy(y,e);CHKERRQ(ierr);
      ierr = VecCopy(y,e);CHKERRQ(ierr);
      ierr = VecAXPY(e,-theta,v);CHKERRQ(ierr);
      ierr = VecAXPY(e,-theta,v);CHKERRQ(ierr);
      ierr = VecNorm(e,NORM_2,&norm);CHKERRQ(ierr);
      ierr = VecNorm(e,NORM_2,&norm);CHKERRQ(ierr);
      relerr = norm / PetscAbsScalar(theta);
      relerr = norm / PetscAbsScalar(theta);
      eps->errest[eps->nconv] = relerr;
      eps->errest[eps->nconv] = relerr;
      ierr = VecCopy(z,e);CHKERRQ(ierr);
      ierr = VecCopy(z,e);CHKERRQ(ierr);
      ierr = VecAXPY(e,-theta,w);CHKERRQ(ierr);
      ierr = VecAXPY(e,-theta,w);CHKERRQ(ierr);
      ierr = VecNorm(e,NORM_2,&norm);CHKERRQ(ierr);
      ierr = VecNorm(e,NORM_2,&norm);CHKERRQ(ierr);
      relerr = norm / PetscAbsScalar(theta);
      relerr = norm / PetscAbsScalar(theta);
      eps->errest_left[eps->nconv] = relerr;
      eps->errest_left[eps->nconv] = relerr;
 
 
    } else {  /* RQI */
    } else {  /* RQI */
 
 
      /* delta = sqrt(y,z)_B */
      /* delta = sqrt(y,z)_B */
      ierr = IPInnerProduct(eps->ip,y,z,&alpha);CHKERRQ(ierr);
      ierr = IPInnerProduct(eps->ip,y,z,&alpha);CHKERRQ(ierr);
      if (alpha==0.0) SETERRQ(1,"Breakdown in two-sided Power/RQI");
      if (alpha==0.0) SETERRQ(1,"Breakdown in two-sided Power/RQI");
      delta = PetscSqrtScalar(alpha);
      delta = PetscSqrtScalar(alpha);
 
 
      /* compute relative error */
      /* compute relative error */
      if (rho == 0.0) relerr = PETSC_MAX;
      if (rho == 0.0) relerr = PETSC_MAX;
      else relerr = 1.0 / (PetscAbsScalar(delta*rho));
      else relerr = 1.0 / (PetscAbsScalar(delta*rho));
      eps->errest[eps->nconv] = relerr;
      eps->errest[eps->nconv] = relerr;
      eps->errest_left[eps->nconv] = relerr;
      eps->errest_left[eps->nconv] = relerr;
 
 
      /* approximate eigenvalue is the shift */
      /* approximate eigenvalue is the shift */
      eps->eigr[eps->nconv] = rho;
      eps->eigr[eps->nconv] = rho;
 
 
      /* compute new shift */
      /* compute new shift */
      if (eps->errest[eps->nconv]<eps->tol && eps->errest_left[eps->nconv]<eps->tol) {
      if (eps->errest[eps->nconv]<eps->tol && eps->errest_left[eps->nconv]<eps->tol) {
        rho = sigma; /* if converged, restore original shift */
        rho = sigma; /* if converged, restore original shift */
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
      } else {
      } else {
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v,w) */
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v,w) */
        if (power->shift_type == EPS_POWER_SHIFT_WILKINSON) {
        if (power->shift_type == EPS_POWER_SHIFT_WILKINSON) {
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
#else
#else
          /* beta1 is the norm of the residual associated to R(v,w) */
          /* beta1 is the norm of the residual associated to R(v,w) */
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
          ierr = VecScale(v,1.0/delta);CHKERRQ(ierr);
          ierr = VecScale(v,1.0/delta);CHKERRQ(ierr);
          ierr = IPNorm(eps->ip,v,&norm);CHKERRQ(ierr);
          ierr = IPNorm(eps->ip,v,&norm);CHKERRQ(ierr);
          beta1 = norm;
          beta1 = norm;
   
   
          /* alpha2 = (e'*A*e)/(beta1*beta1), where e is the residual */
          /* alpha2 = (e'*A*e)/(beta1*beta1), where e is the residual */
          ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
          ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
          ierr = MatMult(A,v,e);CHKERRQ(ierr);
          ierr = MatMult(A,v,e);CHKERRQ(ierr);
          ierr = VecDot(v,e,&alpha2);CHKERRQ(ierr);
          ierr = VecDot(v,e,&alpha2);CHKERRQ(ierr);
          alpha2 = alpha2 / (beta1 * beta1);
          alpha2 = alpha2 / (beta1 * beta1);
 
 
          /* choose the eigenvalue of [rho beta1; beta1 alpha2] closest to rho */
          /* choose the eigenvalue of [rho beta1; beta1 alpha2] closest to rho */
          LAPACKlaev2_(&rho,&beta1,&alpha2,&rt1,&rt2,&cs1,&sn1);
          LAPACKlaev2_(&rho,&beta1,&alpha2,&rt1,&rt2,&cs1,&sn1);
          if (PetscAbsScalar(rt1-rho) < PetscAbsScalar(rt2-rho)) rho = rt1;
          if (PetscAbsScalar(rt1-rho) < PetscAbsScalar(rt2-rho)) rho = rt1;
          else rho = rt2;
          else rho = rt2;
#endif
#endif
        }
        }
        /* update operator according to new shift */
        /* update operator according to new shift */
        PetscPushErrorHandler(PetscIgnoreErrorHandler,PETSC_NULL);
        PetscPushErrorHandler(PetscIgnoreErrorHandler,PETSC_NULL);
        ierr = STSetShift(eps->OP,rho);
        ierr = STSetShift(eps->OP,rho);
        PetscPopErrorHandler();
        PetscPopErrorHandler();
        if (ierr) {
        if (ierr) {
          eps->eigr[eps->nconv] = rho;
          eps->eigr[eps->nconv] = rho;
          eps->errest[eps->nconv] = PETSC_MACHINE_EPSILON;
          eps->errest[eps->nconv] = PETSC_MACHINE_EPSILON;
          eps->errest_left[eps->nconv] = PETSC_MACHINE_EPSILON;
          eps->errest_left[eps->nconv] = PETSC_MACHINE_EPSILON;
          rho = sigma;
          rho = sigma;
          ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
          ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
        }
        }
      }
      }
    }
    }
 
 
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,eps->nconv+1);
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,eps->nconv+1);
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest_left,eps->nconv+1);
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest_left,eps->nconv+1);
 
 
    /* purge previously converged eigenvectors */
    /* purge previously converged eigenvectors */
    ierr = IPBiOrthogonalize(eps->ip,eps->nconv,eps->V,eps->W,z,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
    ierr = IPBiOrthogonalize(eps->ip,eps->nconv,eps->V,eps->W,z,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
    ierr = IPBiOrthogonalize(eps->ip,eps->nconv,eps->W,eps->V,y,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
    ierr = IPBiOrthogonalize(eps->ip,eps->nconv,eps->W,eps->V,y,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
 
 
    /* normalize so that (y,z)_B=1  */
    /* normalize so that (y,z)_B=1  */
    ierr = VecCopy(y,v);CHKERRQ(ierr);
    ierr = VecCopy(y,v);CHKERRQ(ierr);
    ierr = VecCopy(z,w);CHKERRQ(ierr);
    ierr = VecCopy(z,w);CHKERRQ(ierr);
    ierr = IPInnerProduct(eps->ip,y,z,&alpha);CHKERRQ(ierr);
    ierr = IPInnerProduct(eps->ip,y,z,&alpha);CHKERRQ(ierr);
    if (alpha==0.0) SETERRQ(1,"Breakdown in two-sided Power/RQI");
    if (alpha==0.0) SETERRQ(1,"Breakdown in two-sided Power/RQI");
    delta = PetscSqrtScalar(PetscAbsScalar(alpha));
    delta = PetscSqrtScalar(PetscAbsScalar(alpha));
    beta = 1.0/PetscConj(alpha/delta);
    beta = 1.0/PetscConj(alpha/delta);
    delta = 1.0/delta;
    delta = 1.0/delta;
    ierr = VecScale(w,beta);CHKERRQ(ierr);
    ierr = VecScale(w,beta);CHKERRQ(ierr);
    ierr = VecScale(v,delta);CHKERRQ(ierr);
    ierr = VecScale(v,delta);CHKERRQ(ierr);
 
 
    /* if relerr<tol (both right and left), accept eigenpair */
    /* if relerr<tol (both right and left), accept eigenpair */
    if (eps->errest[eps->nconv]<eps->tol && eps->errest_left[eps->nconv]<eps->tol) {
    if (eps->errest[eps->nconv]<eps->tol && eps->errest_left[eps->nconv]<eps->tol) {
      eps->nconv = eps->nconv + 1;
      eps->nconv = eps->nconv + 1;
      if (eps->nconv==eps->nev) break;
      if (eps->nconv==eps->nev) break;
      v = eps->V[eps->nconv];
      v = eps->V[eps->nconv];
      ierr = EPSGetStartVector(eps,eps->nconv,v,PETSC_NULL);CHKERRQ(ierr);
      ierr = EPSGetStartVector(eps,eps->nconv,v,PETSC_NULL);CHKERRQ(ierr);
      w = eps->W[eps->nconv];
      w = eps->W[eps->nconv];
      ierr = EPSGetStartVectorLeft(eps,eps->nconv,w,PETSC_NULL);CHKERRQ(ierr);
      ierr = EPSGetStartVectorLeft(eps,eps->nconv,w,PETSC_NULL);CHKERRQ(ierr);
    }
    }
  }
  }
 
 
  if( eps->nconv == eps->nev ) eps->reason = EPS_CONVERGED_TOL;
  if( eps->nconv == eps->nev ) eps->reason = EPS_CONVERGED_TOL;
  else eps->reason = EPS_DIVERGED_ITS;
  else eps->reason = EPS_DIVERGED_ITS;
 
 
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSBackTransform_POWER"
#define __FUNCT__ "EPSBackTransform_POWER"
PetscErrorCode EPSBackTransform_POWER(EPS eps)
PetscErrorCode EPSBackTransform_POWER(EPS eps)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER *power = (EPS_POWER *)eps->data;
  EPS_POWER *power = (EPS_POWER *)eps->data;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) {
  if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) {
    ierr = EPSBackTransform_Default(eps);CHKERRQ(ierr);
    ierr = EPSBackTransform_Default(eps);CHKERRQ(ierr);
  }
  }
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSSetFromOptions_POWER"
#define __FUNCT__ "EPSSetFromOptions_POWER"
PetscErrorCode EPSSetFromOptions_POWER(EPS eps)
PetscErrorCode EPSSetFromOptions_POWER(EPS eps)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  PetscTruth     flg;
  PetscTruth     flg;
  PetscInt       i;
  PetscInt       i;
  const char     *shift_list[3] = { "constant", "rayleigh", "wilkinson" };
  const char     *shift_list[3] = { "constant", "rayleigh", "wilkinson" };
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  ierr = PetscOptionsBegin(((PetscObject)eps)->comm,((PetscObject)eps)->prefix,"POWER Options","EPS");CHKERRQ(ierr);
  ierr = PetscOptionsBegin(((PetscObject)eps)->comm,((PetscObject)eps)->prefix,"POWER Options","EPS");CHKERRQ(ierr);
  ierr = PetscOptionsEList("-eps_power_shift_type","Shift type","EPSPowerSetShiftType",shift_list,3,shift_list[power->shift_type],&i,&flg);CHKERRQ(ierr);
  ierr = PetscOptionsEList("-eps_power_shift_type","Shift type","EPSPowerSetShiftType",shift_list,3,shift_list[power->shift_type],&i,&flg);CHKERRQ(ierr);
  if (flg ) power->shift_type = (EPSPowerShiftType)i;
  if (flg ) power->shift_type = (EPSPowerShiftType)i;
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT) {
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT) {
    ierr = STSetType(eps->OP,STSINVERT);CHKERRQ(ierr);
    ierr = STSetType(eps->OP,STSINVERT);CHKERRQ(ierr);
  }
  }
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
EXTERN_C_BEGIN
EXTERN_C_BEGIN
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSPowerSetShiftType_POWER"
#define __FUNCT__ "EPSPowerSetShiftType_POWER"
PetscErrorCode EPSPowerSetShiftType_POWER(EPS eps,EPSPowerShiftType shift)
PetscErrorCode EPSPowerSetShiftType_POWER(EPS eps,EPSPowerShiftType shift)
{
{
  EPS_POWER *power = (EPS_POWER *)eps->data;
  EPS_POWER *power = (EPS_POWER *)eps->data;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  switch (shift) {
  switch (shift) {
    case EPS_POWER_SHIFT_CONSTANT:
    case EPS_POWER_SHIFT_CONSTANT:
    case EPS_POWER_SHIFT_RAYLEIGH:
    case EPS_POWER_SHIFT_RAYLEIGH:
    case EPS_POWER_SHIFT_WILKINSON:
    case EPS_POWER_SHIFT_WILKINSON:
      power->shift_type = shift;
      power->shift_type = shift;
      break;
      break;
    default:
    default:
      SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid shift type");
      SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid shift type");
  }
  }
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
EXTERN_C_END
EXTERN_C_END
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSPowerSetShiftType"
#define __FUNCT__ "EPSPowerSetShiftType"
/*@
/*@
   EPSPowerSetShiftType - Sets the type of shifts used during the power
   EPSPowerSetShiftType - Sets the type of shifts used during the power
   iteration. This can be used to emulate the Rayleigh Quotient Iteration
   iteration. This can be used to emulate the Rayleigh Quotient Iteration
   (RQI) method.
   (RQI) method.
 
 
   Collective on EPS
   Collective on EPS
 
 
   Input Parameters:
   Input Parameters:
+  eps - the eigenproblem solver context
+  eps - the eigenproblem solver context
-  shift - the type of shift
-  shift - the type of shift
 
 
   Options Database Key:
   Options Database Key:
.  -eps_power_shift_type - Sets the shift type (either 'constant' or
.  -eps_power_shift_type - Sets the shift type (either 'constant' or
                           'rayleigh' or 'wilkinson')
                           'rayleigh' or 'wilkinson')
 
 
   Notes:
   Notes:
   By default, shifts are constant (EPS_POWER_SHIFT_CONSTANT) and the iteration
   By default, shifts are constant (EPS_POWER_SHIFT_CONSTANT) and the iteration
   is the simple power method (or inverse iteration if a shift-and-invert
   is the simple power method (or inverse iteration if a shift-and-invert
   transformation is being used).
   transformation is being used).
 
 
   A variable shift can be specified (EPS_POWER_SHIFT_RAYLEIGH or
   A variable shift can be specified (EPS_POWER_SHIFT_RAYLEIGH or
   EPS_POWER_SHIFT_WILKINSON). In this case, the iteration behaves rather like
   EPS_POWER_SHIFT_WILKINSON). In this case, the iteration behaves rather like
   a cubic converging method as RQI. See the users manual for details.
   a cubic converging method as RQI. See the users manual for details.
   
   
   Level: advanced
   Level: advanced
 
 
.seealso: EPSPowerGetShiftType(), STSetShift(), EPSPowerShiftType
.seealso: EPSPowerGetShiftType(), STSetShift(), EPSPowerShiftType
@*/
@*/
PetscErrorCode EPSPowerSetShiftType(EPS eps,EPSPowerShiftType shift)
PetscErrorCode EPSPowerSetShiftType(EPS eps,EPSPowerShiftType shift)
{
{
  PetscErrorCode ierr, (*f)(EPS,EPSPowerShiftType);
  PetscErrorCode ierr, (*f)(EPS,EPSPowerShiftType);
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSPowerSetShiftType_C",(void (**)())&f);CHKERRQ(ierr);
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSPowerSetShiftType_C",(void (**)())&f);CHKERRQ(ierr);
  if (f) {
  if (f) {
    ierr = (*f)(eps,shift);CHKERRQ(ierr);
    ierr = (*f)(eps,shift);CHKERRQ(ierr);
  }
  }
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
EXTERN_C_BEGIN
EXTERN_C_BEGIN
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSPowerGetShiftType_POWER"
#define __FUNCT__ "EPSPowerGetShiftType_POWER"
PetscErrorCode EPSPowerGetShiftType_POWER(EPS eps,EPSPowerShiftType *shift)
PetscErrorCode EPSPowerGetShiftType_POWER(EPS eps,EPSPowerShiftType *shift)
{
{
  EPS_POWER  *power = (EPS_POWER *)eps->data;
  EPS_POWER  *power = (EPS_POWER *)eps->data;
  PetscFunctionBegin;
  PetscFunctionBegin;
  *shift = power->shift_type;
  *shift = power->shift_type;
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
EXTERN_C_END
EXTERN_C_END
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSPowerGetShiftType"
#define __FUNCT__ "EPSPowerGetShiftType"
/*@C
/*@C
   EPSPowerGetShiftType - Gets the type of shifts used during the power
   EPSPowerGetShiftType - Gets the type of shifts used during the power
   iteration.
   iteration.
 
 
   Collective on EPS
   Collective on EPS
 
 
   Input Parameter:
   Input Parameter:
.  eps - the eigenproblem solver context
.  eps - the eigenproblem solver context
 
 
   Input Parameter:
   Input Parameter:
.  shift - the type of shift
.  shift - the type of shift
 
 
   Level: advanced
   Level: advanced
 
 
.seealso: EPSPowerSetShiftType(), EPSPowerShiftType
.seealso: EPSPowerSetShiftType(), EPSPowerShiftType
@*/
@*/
PetscErrorCode EPSPowerGetShiftType(EPS eps,EPSPowerShiftType *shift)
PetscErrorCode EPSPowerGetShiftType(EPS eps,EPSPowerShiftType *shift)
{
{
  PetscErrorCode ierr, (*f)(EPS,EPSPowerShiftType*);
  PetscErrorCode ierr, (*f)(EPS,EPSPowerShiftType*);
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSPowerGetShiftType_C",(void (**)())&f);CHKERRQ(ierr);
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSPowerGetShiftType_C",(void (**)())&f);CHKERRQ(ierr);
  if (f) {
  if (f) {
    ierr = (*f)(eps,shift);CHKERRQ(ierr);
    ierr = (*f)(eps,shift);CHKERRQ(ierr);
  }
  }
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSDestroy_POWER"
#define __FUNCT__ "EPSDestroy_POWER"
PetscErrorCode EPSDestroy_POWER(EPS eps)
PetscErrorCode EPSDestroy_POWER(EPS eps)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
  ierr = EPSDestroy_Default(eps);CHKERRQ(ierr);
  ierr = EPSDestroy_Default(eps);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerSetShiftType_C","",PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerSetShiftType_C","",PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerGetShiftType_C","",PETSC_NULL);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerGetShiftType_C","",PETSC_NULL);CHKERRQ(ierr);
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSView_POWER"
#define __FUNCT__ "EPSView_POWER"
PetscErrorCode EPSView_POWER(EPS eps,PetscViewer viewer)
PetscErrorCode EPSView_POWER(EPS eps,PetscViewer viewer)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  EPS_POWER      *power = (EPS_POWER *)eps->data;
  PetscTruth     isascii;
  PetscTruth     isascii;
  const char     *shift_list[3] = { "constant", "rayleigh", "wilkinson" };
  const char     *shift_list[3] = { "constant", "rayleigh", "wilkinson" };
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
  if (!isascii) {
  if (!isascii) {
    SETERRQ1(1,"Viewer type %s not supported for EPS_POWER",((PetscObject)viewer)->type_name);
    SETERRQ1(1,"Viewer type %s not supported for EPS_POWER",((PetscObject)viewer)->type_name);
  }  
  }  
  ierr = PetscViewerASCIIPrintf(viewer,"shift type: %s\n",shift_list[power->shift_type]);CHKERRQ(ierr);
  ierr = PetscViewerASCIIPrintf(viewer,"shift type: %s\n",shift_list[power->shift_type]);CHKERRQ(ierr);
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
EXTERN_C_BEGIN
EXTERN_C_BEGIN
#undef __FUNCT__  
#undef __FUNCT__  
#define __FUNCT__ "EPSCreate_POWER"
#define __FUNCT__ "EPSCreate_POWER"
PetscErrorCode EPSCreate_POWER(EPS eps)
PetscErrorCode EPSCreate_POWER(EPS eps)
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER      *power;
  EPS_POWER      *power;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  ierr = PetscNew(EPS_POWER,&power);CHKERRQ(ierr);
  ierr = PetscNew(EPS_POWER,&power);CHKERRQ(ierr);
  PetscLogObjectMemory(eps,sizeof(EPS_POWER));
  PetscLogObjectMemory(eps,sizeof(EPS_POWER));
  eps->data                      = (void *) power;
  eps->data                      = (void *) power;
  eps->ops->setup                = EPSSetUp_POWER;
  eps->ops->setup                = EPSSetUp_POWER;
  eps->ops->setfromoptions       = EPSSetFromOptions_POWER;
  eps->ops->setfromoptions       = EPSSetFromOptions_POWER;
  eps->ops->destroy              = EPSDestroy_POWER;
  eps->ops->destroy              = EPSDestroy_POWER;
  eps->ops->view                 = EPSView_POWER;
  eps->ops->view                 = EPSView_POWER;
  eps->ops->backtransform        = EPSBackTransform_POWER;
  eps->ops->backtransform        = EPSBackTransform_POWER;
  eps->ops->computevectors       = EPSComputeVectors_Default;
  eps->ops->computevectors       = EPSComputeVectors_Default;
  power->shift_type              = EPS_POWER_SHIFT_CONSTANT;
  power->shift_type              = EPS_POWER_SHIFT_CONSTANT;
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerSetShiftType_C","EPSPowerSetShiftType_POWER",EPSPowerSetShiftType_POWER);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerSetShiftType_C","EPSPowerSetShiftType_POWER",EPSPowerSetShiftType_POWER);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerGetShiftType_C","EPSPowerGetShiftType_POWER",EPSPowerGetShiftType_POWER);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerGetShiftType_C","EPSPowerGetShiftType_POWER",EPSPowerGetShiftType_POWER);CHKERRQ(ierr);
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
EXTERN_C_END
EXTERN_C_END