LCOV - code coverage report
Current view: top level - svd/interface - svdsetup.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 209 220 95.0 %
Date: 2021-08-02 00:32:28 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-2021, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : /*
      11             :    SVD routines for setting up the solver
      12             : */
      13             : 
      14             : #include <slepc/private/svdimpl.h>      /*I "slepcsvd.h" I*/
      15             : 
      16             : /*@
      17             :    SVDSetOperators - Set the matrices associated with the singular value problem.
      18             : 
      19             :    Collective on svd
      20             : 
      21             :    Input Parameters:
      22             : +  svd - the singular value solver context
      23             : .  A   - the matrix associated with the singular value problem
      24             : -  B   - the second matrix in the case of GSVD
      25             : 
      26             :    Level: beginner
      27             : 
      28             : .seealso: SVDSolve(), SVDGetOperators()
      29             : @*/
      30         171 : PetscErrorCode SVDSetOperators(SVD svd,Mat A,Mat B)
      31             : {
      32         171 :   PetscErrorCode ierr;
      33         171 :   PetscInt       Ma,Na,Mb,Nb,ma,na,mb,nb,M0,N0,m0,n0;
      34         171 :   PetscBool      samesize=PETSC_TRUE;
      35             : 
      36         171 :   PetscFunctionBegin;
      37         171 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
      38         171 :   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
      39         171 :   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
      40         171 :   PetscCheckSameComm(svd,1,A,2);
      41         171 :   if (B) PetscCheckSameComm(svd,1,B,3);
      42             : 
      43             :   /* Check matrix sizes */
      44         171 :   ierr = MatGetSize(A,&Ma,&Na);CHKERRQ(ierr);
      45         171 :   ierr = MatGetLocalSize(A,&ma,&na);CHKERRQ(ierr);
      46         171 :   if (svd->OP) {
      47          22 :     ierr = MatGetSize(svd->OP,&M0,&N0);CHKERRQ(ierr);
      48          22 :     ierr = MatGetLocalSize(svd->OP,&m0,&n0);CHKERRQ(ierr);
      49          22 :     if (M0!=Ma || N0!=Na || m0!=ma || n0!=na) samesize = PETSC_FALSE;
      50             :   }
      51         171 :   if (B) {
      52          47 :     ierr = MatGetSize(B,&Mb,&Nb);CHKERRQ(ierr);
      53          47 :     ierr = MatGetLocalSize(B,&mb,&nb);CHKERRQ(ierr);
      54          47 :     if (Na!=Nb) SETERRQ2(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_WRONG,"Different number of columns in A (%D) and B (%D)",Na,Nb);
      55          47 :     if (na!=nb) SETERRQ2(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_WRONG,"Different local column size in A (%D) and B (%D)",na,nb);
      56          47 :     if (svd->OPb) {
      57           8 :       ierr = MatGetSize(svd->OPb,&M0,&N0);CHKERRQ(ierr);
      58           8 :       ierr = MatGetLocalSize(svd->OPb,&m0,&n0);CHKERRQ(ierr);
      59           8 :       if (M0!=Mb || N0!=Nb || m0!=mb || n0!=nb) samesize = PETSC_FALSE;
      60             :     }
      61             :   }
      62             : 
      63         171 :   ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
      64         171 :   if (B) { ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); }
      65         171 :   if (svd->state && !samesize) {
      66           0 :     ierr = SVDReset(svd);CHKERRQ(ierr);
      67             :   } else {
      68         171 :     ierr = MatDestroy(&svd->OP);CHKERRQ(ierr);
      69         171 :     ierr = MatDestroy(&svd->OPb);CHKERRQ(ierr);
      70         171 :     ierr = MatDestroy(&svd->A);CHKERRQ(ierr);
      71         171 :     ierr = MatDestroy(&svd->B);CHKERRQ(ierr);
      72         171 :     ierr = MatDestroy(&svd->AT);CHKERRQ(ierr);
      73         171 :     ierr = MatDestroy(&svd->BT);CHKERRQ(ierr);
      74             :   }
      75         171 :   svd->nrma = 0.0;
      76         171 :   svd->nrmb = 0.0;
      77         171 :   svd->OP   = A;
      78         171 :   svd->OPb  = B;
      79         171 :   svd->state = SVD_STATE_INITIAL;
      80         171 :   PetscFunctionReturn(0);
      81             : }
      82             : 
      83             : /*@
      84             :    SVDGetOperators - Get the matrices associated with the singular value problem.
      85             : 
      86             :    Collective on svd
      87             : 
      88             :    Input Parameter:
      89             : .  svd - the singular value solver context
      90             : 
      91             :    Output Parameters:
      92             : +  A  - the matrix associated with the singular value problem
      93             : -  B  - the second matrix in the case of GSVD
      94             : 
      95             :    Level: intermediate
      96             : 
      97             : .seealso: SVDSolve(), SVDSetOperators()
      98             : @*/
      99          12 : PetscErrorCode SVDGetOperators(SVD svd,Mat *A,Mat *B)
     100             : {
     101          12 :   PetscFunctionBegin;
     102          12 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     103          12 :   if (A) *A = svd->OP;
     104          12 :   if (B) *B = svd->OPb;
     105          12 :   PetscFunctionReturn(0);
     106             : }
     107             : 
     108             : /*@
     109             :    SVDSetUp - Sets up all the internal data structures necessary for the
     110             :    execution of the singular value solver.
     111             : 
     112             :    Collective on svd
     113             : 
     114             :    Input Parameter:
     115             : .  svd   - singular value solver context
     116             : 
     117             :    Notes:
     118             :    This function need not be called explicitly in most cases, since SVDSolve()
     119             :    calls it. It can be useful when one wants to measure the set-up time
     120             :    separately from the solve time.
     121             : 
     122             :    Level: developer
     123             : 
     124             : .seealso: SVDCreate(), SVDSolve(), SVDDestroy()
     125             : @*/
     126         187 : PetscErrorCode SVDSetUp(SVD svd)
     127             : {
     128         187 :   PetscErrorCode ierr;
     129         187 :   PetscBool      flg;
     130         187 :   PetscInt       M,N,P=0,k,maxnsol;
     131         187 :   SlepcSC        sc;
     132         187 :   Vec            *T;
     133         187 :   BV             bv;
     134             : 
     135         187 :   PetscFunctionBegin;
     136         187 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     137         187 :   if (svd->state) PetscFunctionReturn(0);
     138         187 :   ierr = PetscLogEventBegin(SVD_SetUp,svd,0,0,0);CHKERRQ(ierr);
     139             : 
     140             :   /* reset the convergence flag from the previous solves */
     141         187 :   svd->reason = SVD_CONVERGED_ITERATING;
     142             : 
     143             :   /* Set default solver type (SVDSetFromOptions was not called) */
     144         187 :   if (!((PetscObject)svd)->type_name) {
     145           0 :     ierr = SVDSetType(svd,SVDCROSS);CHKERRQ(ierr);
     146             :   }
     147         187 :   if (!svd->ds) { ierr = SVDGetDS(svd,&svd->ds);CHKERRQ(ierr); }
     148             : 
     149             :   /* check matrices */
     150         187 :   if (!svd->OP) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_WRONGSTATE,"SVDSetOperators() must be called first");
     151             : 
     152             :   /* Set default problem type */
     153         187 :   if (!svd->problem_type) {
     154         111 :     if (svd->OPb) {
     155          12 :       ierr = SVDSetProblemType(svd,SVD_GENERALIZED);CHKERRQ(ierr);
     156             :     } else {
     157          99 :       ierr = SVDSetProblemType(svd,SVD_STANDARD);CHKERRQ(ierr);
     158             :     }
     159          76 :   } else if (!svd->OPb && svd->isgeneralized) {
     160           0 :     ierr = PetscInfo(svd,"Problem type set as generalized but no matrix B was provided; reverting to a standard singular value problem\n");CHKERRQ(ierr);
     161           0 :     svd->isgeneralized = PETSC_FALSE;
     162           0 :     svd->problem_type = SVD_STANDARD;
     163          76 :   } else if (svd->OPb && !svd->isgeneralized) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_INCOMP,"Inconsistent SVD state: the problem type does not match the number of matrices");
     164             : 
     165             :   /* determine how to handle the transpose */
     166         187 :   svd->expltrans = PETSC_TRUE;
     167         187 :   if (svd->impltrans) svd->expltrans = PETSC_FALSE;
     168             :   else {
     169         174 :     ierr = MatHasOperation(svd->OP,MATOP_TRANSPOSE,&flg);CHKERRQ(ierr);
     170         174 :     if (!flg) svd->expltrans = PETSC_FALSE;
     171             :     else {
     172         174 :       ierr = PetscObjectTypeCompareAny((PetscObject)svd,&flg,SVDLAPACK,SVDSCALAPACK,SVDELEMENTAL,"");CHKERRQ(ierr);
     173         174 :       if (flg) svd->expltrans = PETSC_FALSE;
     174             :     }
     175             :   }
     176             : 
     177             :   /* get matrix dimensions */
     178         187 :   ierr = MatGetSize(svd->OP,&M,&N);CHKERRQ(ierr);
     179         187 :   if (svd->isgeneralized) {
     180          47 :     ierr = MatGetSize(svd->OPb,&P,NULL);CHKERRQ(ierr);
     181          47 :     if (M+P<N) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_SUP,"The case when [A;B] has less rows than columns is not supported");
     182             :   }
     183             : 
     184             :   /* build transpose matrix */
     185         187 :   ierr = MatDestroy(&svd->A);CHKERRQ(ierr);
     186         187 :   ierr = MatDestroy(&svd->AT);CHKERRQ(ierr);
     187         187 :   ierr = PetscObjectReference((PetscObject)svd->OP);CHKERRQ(ierr);
     188         187 :   if (svd->expltrans) {
     189         153 :     if (svd->isgeneralized || M>=N) {
     190         125 :       svd->A = svd->OP;
     191         125 :       ierr = MatHermitianTranspose(svd->OP,MAT_INITIAL_MATRIX,&svd->AT);CHKERRQ(ierr);
     192             :     } else {
     193          28 :       ierr = MatHermitianTranspose(svd->OP,MAT_INITIAL_MATRIX,&svd->A);CHKERRQ(ierr);
     194          28 :       svd->AT = svd->OP;
     195             :     }
     196             :   } else {
     197          34 :     if (svd->isgeneralized || M>=N) {
     198          29 :       svd->A = svd->OP;
     199          29 :       ierr = MatCreateHermitianTranspose(svd->OP,&svd->AT);CHKERRQ(ierr);
     200             :     } else {
     201           5 :       ierr = MatCreateHermitianTranspose(svd->OP,&svd->A);CHKERRQ(ierr);
     202           5 :       svd->AT = svd->OP;
     203             :     }
     204             :   }
     205             : 
     206             :   /* build transpose matrix B for GSVD */
     207         187 :   if (svd->isgeneralized) {
     208          47 :     ierr = MatDestroy(&svd->B);CHKERRQ(ierr);
     209          47 :     ierr = MatDestroy(&svd->BT);CHKERRQ(ierr);
     210          47 :     ierr = PetscObjectReference((PetscObject)svd->OPb);CHKERRQ(ierr);
     211          47 :     if (svd->expltrans) {
     212          41 :       svd->B = svd->OPb;
     213          41 :       ierr = MatHermitianTranspose(svd->OPb,MAT_INITIAL_MATRIX,&svd->BT);CHKERRQ(ierr);
     214             :     } else {
     215           6 :       svd->B = svd->OPb;
     216           6 :       ierr = MatCreateHermitianTranspose(svd->OPb,&svd->BT);CHKERRQ(ierr);
     217             :     }
     218             :   }
     219             : 
     220         187 :   if (!svd->isgeneralized && M<N) {
     221             :     /* swap initial vectors */
     222          33 :     if (svd->nini || svd->ninil) {
     223           0 :       T=svd->ISL; svd->ISL=svd->IS; svd->IS=T;
     224           0 :       k=svd->ninil; svd->ninil=svd->nini; svd->nini=k;
     225             :     }
     226             :     /* swap basis vectors */
     227          33 :     if (!svd->swapped) {  /* only the first time in case of multiple calls */
     228          26 :       bv=svd->V; svd->V=svd->U; svd->U=bv;
     229          26 :       svd->swapped = PETSC_TRUE;
     230             :     }
     231             :   }
     232             : 
     233         187 :   maxnsol = svd->isgeneralized? PetscMin(PetscMin(M,N),P): PetscMin(M,N);
     234         187 :   svd->ncv = PetscMin(svd->ncv,maxnsol);
     235         187 :   svd->nsv = PetscMin(svd->nsv,maxnsol);
     236         187 :   if (svd->ncv!=PETSC_DEFAULT && svd->nsv > svd->ncv) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"nsv bigger than ncv");
     237             : 
     238             :   /* initialization of matrix norms */
     239         187 :   if (svd->conv==SVD_CONV_NORM) {
     240           5 :     if (!svd->nrma) {
     241           5 :       ierr = MatNorm(svd->OP,NORM_INFINITY,&svd->nrma);CHKERRQ(ierr);
     242             :     }
     243           5 :     if (svd->isgeneralized && !svd->nrmb) {
     244           4 :       ierr = MatNorm(svd->OPb,NORM_INFINITY,&svd->nrmb);CHKERRQ(ierr);
     245             :     }
     246             :   }
     247             : 
     248             :   /* call specific solver setup */
     249         187 :   ierr = (*svd->ops->setup)(svd);CHKERRQ(ierr);
     250             : 
     251             :   /* set tolerance if not yet set */
     252         187 :   if (svd->tol==PETSC_DEFAULT) svd->tol = SLEPC_DEFAULT_TOL;
     253             : 
     254             :   /* fill sorting criterion context */
     255         187 :   ierr = DSGetSlepcSC(svd->ds,&sc);CHKERRQ(ierr);
     256         187 :   sc->comparison    = (svd->which==SVD_LARGEST)? SlepcCompareLargestReal: SlepcCompareSmallestReal;
     257         187 :   sc->comparisonctx = NULL;
     258         187 :   sc->map           = NULL;
     259         187 :   sc->mapobj        = NULL;
     260             : 
     261             :   /* process initial vectors */
     262         187 :   if (svd->nini<0) {
     263          20 :     k = -svd->nini;
     264          20 :     if (k>svd->ncv) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_USER_INPUT,"The number of initial vectors is larger than ncv");
     265          20 :     ierr = BVInsertVecs(svd->V,0,&k,svd->IS,PETSC_TRUE);CHKERRQ(ierr);
     266          20 :     ierr = SlepcBasisDestroy_Private(&svd->nini,&svd->IS);CHKERRQ(ierr);
     267          20 :     svd->nini = k;
     268             :   }
     269         187 :   if (svd->ninil<0) {
     270          25 :     k = 0;
     271          25 :     if (svd->leftbasis) {
     272          18 :       k = -svd->ninil;
     273          18 :       if (k>svd->ncv) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_USER_INPUT,"The number of left initial vectors is larger than ncv");
     274          18 :       ierr = BVInsertVecs(svd->U,0,&k,svd->ISL,PETSC_TRUE);CHKERRQ(ierr);
     275             :     } else {
     276           7 :       ierr = PetscInfo(svd,"Ignoring initial left vectors\n");CHKERRQ(ierr);
     277             :     }
     278          25 :     ierr = SlepcBasisDestroy_Private(&svd->ninil,&svd->ISL);CHKERRQ(ierr);
     279          25 :     svd->ninil = k;
     280             :   }
     281             : 
     282         187 :   ierr = PetscLogEventEnd(SVD_SetUp,svd,0,0,0);CHKERRQ(ierr);
     283         187 :   svd->state = SVD_STATE_SETUP;
     284         187 :   PetscFunctionReturn(0);
     285             : }
     286             : 
     287             : /*@C
     288             :    SVDSetInitialSpaces - Specify two basis of vectors that constitute the initial
     289             :    right and/or left spaces, that is, a rough approximation to the right and/or
     290             :    left singular subspaces from which the solver starts to iterate.
     291             : 
     292             :    Collective on svd
     293             : 
     294             :    Input Parameters:
     295             : +  svd   - the singular value solver context
     296             : .  nr    - number of right vectors
     297             : .  isr   - set of basis vectors of the right initial space
     298             : .  nl    - number of left vectors
     299             : -  isl   - set of basis vectors of the left initial space
     300             : 
     301             :    Notes:
     302             :    It is not necessary to provide both sets of vectors.
     303             : 
     304             :    Some solvers start to iterate on a single vector (initial vector). In that case,
     305             :    the other vectors are ignored.
     306             : 
     307             :    These vectors do not persist from one SVDSolve() call to the other, so the
     308             :    initial space should be set every time.
     309             : 
     310             :    The vectors do not need to be mutually orthonormal, since they are explicitly
     311             :    orthonormalized internally.
     312             : 
     313             :    Common usage of this function is when the user can provide a rough approximation
     314             :    of the wanted singular space. Then, convergence may be faster.
     315             : 
     316             :    Level: intermediate
     317             : @*/
     318          28 : PetscErrorCode SVDSetInitialSpaces(SVD svd,PetscInt nr,Vec isr[],PetscInt nl,Vec isl[])
     319             : {
     320          28 :   PetscErrorCode ierr;
     321             : 
     322          28 :   PetscFunctionBegin;
     323          28 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     324          56 :   PetscValidLogicalCollectiveInt(svd,nr,2);
     325          56 :   PetscValidLogicalCollectiveInt(svd,nl,4);
     326          28 :   if (nr<0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Argument nr cannot be negative");
     327          28 :   if (nr>0) {
     328          28 :     PetscValidPointer(isr,3);
     329          28 :     PetscValidHeaderSpecific(*isr,VEC_CLASSID,3);
     330             :   }
     331          28 :   if (nl<0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Argument nl cannot be negative");
     332          28 :   if (nl>0) {
     333          28 :     PetscValidPointer(isl,5);
     334          28 :     PetscValidHeaderSpecific(*isl,VEC_CLASSID,5);
     335             :   }
     336          28 :   ierr = SlepcBasisReference_Private(nr,isr,&svd->nini,&svd->IS);CHKERRQ(ierr);
     337          28 :   ierr = SlepcBasisReference_Private(nl,isl,&svd->ninil,&svd->ISL);CHKERRQ(ierr);
     338          28 :   if (nr>0 || nl>0) svd->state = SVD_STATE_INITIAL;
     339          28 :   PetscFunctionReturn(0);
     340             : }
     341             : 
     342             : /*
     343             :   SVDSetDimensions_Default - Set reasonable values for ncv, mpd if not set
     344             :   by the user. This is called at setup.
     345             :  */
     346          86 : PetscErrorCode SVDSetDimensions_Default(SVD svd)
     347             : {
     348          86 :   PetscErrorCode ierr;
     349          86 :   PetscInt       N,M,P,maxnsol;
     350             : 
     351          86 :   PetscFunctionBegin;
     352          86 :   ierr = MatGetSize(svd->OP,&M,&N);CHKERRQ(ierr);
     353          86 :   maxnsol = PetscMin(M,N);
     354          86 :   if (svd->isgeneralized) {
     355          21 :     ierr = MatGetSize(svd->OPb,&P,NULL);CHKERRQ(ierr);
     356          21 :     maxnsol = PetscMin(maxnsol,P);
     357             :   }
     358          86 :   if (svd->ncv!=PETSC_DEFAULT) { /* ncv set */
     359          37 :     if (svd->ncv<svd->nsv) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_USER_INPUT,"The value of ncv must be at least nsv");
     360          49 :   } else if (svd->mpd!=PETSC_DEFAULT) { /* mpd set */
     361           0 :     svd->ncv = PetscMin(maxnsol,svd->nsv+svd->mpd);
     362             :   } else { /* neither set: defaults depend on nsv being small or large */
     363          49 :     if (svd->nsv<500) svd->ncv = PetscMin(maxnsol,PetscMax(2*svd->nsv,10));
     364             :     else {
     365           0 :       svd->mpd = 500;
     366           0 :       svd->ncv = PetscMin(maxnsol,svd->nsv+svd->mpd);
     367             :     }
     368             :   }
     369          86 :   if (svd->mpd==PETSC_DEFAULT) svd->mpd = svd->ncv;
     370          86 :   PetscFunctionReturn(0);
     371             : }
     372             : 
     373             : /*@
     374             :    SVDAllocateSolution - Allocate memory storage for common variables such
     375             :    as the singular values and the basis vectors.
     376             : 
     377             :    Collective on svd
     378             : 
     379             :    Input Parameters:
     380             : +  svd   - eigensolver context
     381             : -  extra - number of additional positions, used for methods that require a
     382             :            working basis slightly larger than ncv
     383             : 
     384             :    Developers Notes:
     385             :    This is SLEPC_EXTERN because it may be required by user plugin SVD
     386             :    implementations.
     387             : 
     388             :    This is called at setup after setting the value of ncv and the flag leftbasis.
     389             : 
     390             :    Level: developer
     391             : @*/
     392         187 : PetscErrorCode SVDAllocateSolution(SVD svd,PetscInt extra)
     393             : {
     394         187 :   PetscErrorCode ierr;
     395         187 :   PetscInt       oldsize,requested;
     396         187 :   Vec            tr,tl;
     397             : 
     398         187 :   PetscFunctionBegin;
     399         187 :   requested = svd->ncv + extra;
     400             : 
     401             :   /* oldsize is zero if this is the first time setup is called */
     402         187 :   ierr = BVGetSizes(svd->V,NULL,NULL,&oldsize);CHKERRQ(ierr);
     403             : 
     404             :   /* allocate sigma */
     405         187 :   if (requested != oldsize || !svd->sigma) {
     406         156 :     ierr = PetscFree3(svd->sigma,svd->perm,svd->errest);CHKERRQ(ierr);
     407         156 :     ierr = PetscMalloc3(requested,&svd->sigma,requested,&svd->perm,requested,&svd->errest);CHKERRQ(ierr);
     408         156 :     ierr = PetscLogObjectMemory((PetscObject)svd,PetscMax(0,requested-oldsize)*(2*sizeof(PetscReal)+sizeof(PetscInt)));CHKERRQ(ierr);
     409             :   }
     410             :   /* allocate V */
     411         187 :   if (!svd->V) { ierr = SVDGetBV(svd,&svd->V,NULL);CHKERRQ(ierr); }
     412         187 :   if (!oldsize) {
     413         146 :     if (!((PetscObject)(svd->V))->type_name) {
     414          14 :       ierr = BVSetType(svd->V,BVSVEC);CHKERRQ(ierr);
     415             :     }
     416         146 :     ierr = MatCreateVecsEmpty(svd->A,&tr,NULL);CHKERRQ(ierr);
     417         146 :     ierr = BVSetSizesFromVec(svd->V,tr,requested);CHKERRQ(ierr);
     418         146 :     ierr = VecDestroy(&tr);CHKERRQ(ierr);
     419             :   } else {
     420          41 :     ierr = BVResize(svd->V,requested,PETSC_FALSE);CHKERRQ(ierr);
     421             :   }
     422             :   /* allocate U */
     423         187 :   if (svd->leftbasis && !svd->isgeneralized) {
     424         104 :     if (!svd->U) { ierr = SVDGetBV(svd,NULL,&svd->U);CHKERRQ(ierr); }
     425         104 :     if (!oldsize) {
     426          79 :       if (!((PetscObject)(svd->U))->type_name) {
     427          11 :         ierr = BVSetType(svd->U,BVSVEC);CHKERRQ(ierr);
     428             :       }
     429          79 :       ierr = MatCreateVecsEmpty(svd->A,NULL,&tl);CHKERRQ(ierr);
     430          79 :       ierr = BVSetSizesFromVec(svd->U,tl,requested);CHKERRQ(ierr);
     431          79 :       ierr = VecDestroy(&tl);CHKERRQ(ierr);
     432             :     } else {
     433          25 :       ierr = BVResize(svd->U,requested,PETSC_FALSE);CHKERRQ(ierr);
     434             :     }
     435          83 :   } else if (svd->isgeneralized) {  /* left basis for the GSVD */
     436          47 :     if (!svd->U) { ierr = SVDGetBV(svd,NULL,&svd->U);CHKERRQ(ierr); }
     437          47 :     if (!oldsize) {
     438          39 :       if (!((PetscObject)(svd->U))->type_name) {
     439           0 :         ierr = BVSetType(svd->U,BVSVEC);CHKERRQ(ierr);
     440             :       }
     441          39 :       ierr = SVDCreateLeftTemplate(svd,&tl);CHKERRQ(ierr);
     442          39 :       ierr = BVSetSizesFromVec(svd->U,tl,requested);CHKERRQ(ierr);
     443          39 :       ierr = VecDestroy(&tl);CHKERRQ(ierr);
     444             :     } else {
     445           8 :       ierr = BVResize(svd->U,requested,PETSC_FALSE);CHKERRQ(ierr);
     446             :     }
     447             :   }
     448         187 :   PetscFunctionReturn(0);
     449             : }
     450             : 

Generated by: LCOV version 1.14