Date: 2021-09-20T09:43:43+00:00

Actual source code: bvkrylov.c
slepc-3.15.2 2021-09-20
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-2021, 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: */
     10: /*
     11:    BV routines related to Krylov decompositions
     12: */

     14: #include <slepc/private/bvimpl.h>

     16: /*@
     17:    BVMatArnoldi - Computes an Arnoldi factorization associated with a matrix.

     19:    Collective on V

     21:    Input Parameters:
     22: +  V - basis vectors context
     23: .  A - the matrix
     24: .  H - the upper Hessenberg matrix
     25: .  ldh - leading dimension of H
     26: .  k - number of locked columns
     27: -  m - dimension of the Arnoldi basis

     29:    Output Parameters:
     30: +  m - the modified dimension
     31: .  beta - (optional) norm of last vector before normalization
     32: -  breakdown - (optional) flag indicating that breakdown occurred

     34:    Notes:
     35:    Computes an m-step Arnoldi factorization for matrix A. The first k columns
     36:    are assumed to be locked and therefore they are not modified. On exit, the
     37:    following relation is satisfied:

     39:                     A * V - V * H = beta*v_m * e_m^T

     41:    where the columns of V are the Arnoldi vectors (which are orthonormal), H is
     42:    an upper Hessenberg matrix, e_m is the m-th vector of the canonical basis.
     43:    On exit, beta contains the norm of V[m] before normalization.

     45:    The breakdown flag indicates that orthogonalization failed, see
     46:    BVOrthonormalizeColumn(). In that case, on exit m contains the index of
     47:    the column that failed.

     49:    The values of k and m are not restricted to the active columns of V.

     51:    To create an Arnoldi factorization from scratch, set k=0 and make sure the
     52:    first column contains the normalized initial vector.

     54:    Level: advanced

     56: .seealso: BVMatLanczos(), BVSetActiveColumns(), BVOrthonormalizeColumn()
     57: @*/
     58: PetscErrorCode BVMatArnoldi(BV V,Mat A,PetscScalar *H,PetscInt ldh,PetscInt k,PetscInt *m,PetscReal *beta,PetscBool *breakdown)
     59: {
     61:   PetscScalar    *a;
     62:   PetscInt       j;
     63:   PetscBool      lindep=PETSC_FALSE;
     64:   Vec            buf;

     73:   BVCheckSizes(V,1);

     77:   if (k<0 || k>V->m) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument k has wrong value %D, should be between 0 and %D",k,V->m);
     78:   if (*m<1 || *m>V->m) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument m has wrong value %D, should be between 1 and %D",*m,V->m);
     79:   if (*m<=k) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument m should be at least equal to k+1");

     81:   BVSetActiveColumns(V,0,*m);
     82:   for (j=k;j<*m;j++) {
     83:     BVMatMultColumn(V,A,j);
     84:     if (PetscUnlikely(j==V->N-1)) {   /* safeguard in case the full basis is requested */
     85:       BV_OrthogonalizeColumn_Safe(V,j+1,NULL,beta,&lindep);
     86:     } else {
     87:       BVOrthonormalizeColumn(V,j+1,PETSC_FALSE,beta,&lindep);
     88:     }
     89:     if (lindep) {
     90:       *m = j+1;
     91:       break;
     92:     }
     93:   }
     94:   if (breakdown) *breakdown = lindep;
     95:   if (lindep) { PetscInfo1(V,"Arnoldi finished early at m=%D\n",*m); }
     96:   /* extract Hessenberg matrix from the BV object */
     97:   BVGetBufferVec(V,&buf);
     98:   VecGetArray(buf,&a);
     99:   for (j=k;j<*m;j++) {
    100:     PetscArraycpy(H+j*ldh,a+V->nc+(j+1)*(V->nc+V->m),j+2);
    101:   }
    102:   VecRestoreArray(buf,&a);

    104:   PetscObjectStateIncrease((PetscObject)V);
    105:   return(0);
    106: }

    108: /*@C
    109:    BVMatLanczos - Computes a Lanczos factorization associated with a matrix.

    111:    Collective on V

    113:    Input Parameters:
    114: +  V - basis vectors context
    115: .  A - the matrix
    116: .  alpha - diagonal entries of tridiagonal matrix
    117: .  beta - subdiagonal entries of tridiagonal matrix
    118: .  k - number of locked columns
    119: -  m - dimension of the Lanczos basis

    121:    Output Parameters:
    122: +  m - the modified dimension
    123: -  breakdown - (optional) flag indicating that breakdown occurred

    125:    Notes:
    126:    Computes an m-step Lanczos factorization for matrix A, with full
    127:    reorthogonalization. At each Lanczos step, the corresponding Lanczos
    128:    vector is orthogonalized with respect to all previous Lanczos vectors.
    129:    This is equivalent to computing an m-step Arnoldi factorization and
    130:    exploting symmetry of the operator.

    132:    The first k columns are assumed to be locked and therefore they are
    133:    not modified. On exit, the following relation is satisfied:

    135:                     A * V - V * T = beta_m*v_m * e_m^T

    137:    where the columns of V are the Lanczos vectors (which are B-orthonormal),
    138:    T is a real symmetric tridiagonal matrix, and e_m is the m-th vector of
    139:    the canonical basis. The tridiagonal is stored as two arrays: alpha
    140:    contains the diagonal elements, beta the off-diagonal. On exit, the last
    141:    element of beta contains the B-norm of V[m] before normalization.
    142:    The basis V must have at least m+1 columns, while the arrays alpha and
    143:    beta must have space for at least m elements.

    145:    The breakdown flag indicates that orthogonalization failed, see
    146:    BVOrthonormalizeColumn(). In that case, on exit m contains the index of
    147:    the column that failed.

    149:    The values of k and m are not restricted to the active columns of V.

    151:    To create a Lanczos factorization from scratch, set k=0 and make sure the
    152:    first column contains the normalized initial vector.

    154:    Level: advanced

    156: .seealso: BVMatArnoldi(), BVSetActiveColumns(), BVOrthonormalizeColumn()
    157: @*/
    158: PetscErrorCode BVMatLanczos(BV V,Mat A,PetscReal *alpha,PetscReal *beta,PetscInt k,PetscInt *m,PetscBool *breakdown)
    159: {
    161:   PetscScalar    *a;
    162:   PetscInt       j;
    163:   PetscBool      lindep=PETSC_FALSE;
    164:   Vec            buf;

    175:   BVCheckSizes(V,1);

    179:   if (k<0 || k>V->m) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument k has wrong value %D, should be between 0 and %D",k,V->m);
    180:   if (*m<1 || *m>V->m) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument m has wrong value %D, should be between 1 and %D",*m,V->m);
    181:   if (*m<=k) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument m should be at least equal to k+1");

    183:   BVSetActiveColumns(V,0,*m);
    184:   for (j=k;j<*m;j++) {
    185:     BVMatMultColumn(V,A,j);
    186:     if (PetscUnlikely(j==V->N-1)) {   /* safeguard in case the full basis is requested */
    187:       BV_OrthogonalizeColumn_Safe(V,j+1,NULL,beta+j,&lindep);
    188:     } else {
    189:       BVOrthonormalizeColumn(V,j+1,PETSC_FALSE,beta+j,&lindep);
    190:     }
    191:     if (lindep) {
    192:       *m = j+1;
    193:       break;
    194:     }
    195:   }
    196:   if (breakdown) *breakdown = lindep;

    198:   /* extract Hessenberg matrix from the BV buffer */
    199:   BVGetBufferVec(V,&buf);
    200:   VecGetArray(buf,&a);
    201:   for (j=k;j<*m;j++) alpha[j] = PetscRealPart(a[V->nc+j+(j+1)*(V->nc+V->m)]);
    202:   VecRestoreArray(buf,&a);

    204:   PetscObjectStateIncrease((PetscObject)V);
    205:   return(0);
    206: }