Date: 2016-03-29T14:58:34+00:00

Actual source code: svdbasic.c
slepc-3.6.3 2016-03-29
Report Typos and Errors

      1: /*
      2:    The basic SVD routines, Create, Destroy, etc. are here.

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

      8:    This file is part of SLEPc.

     10:    SLEPc is free software: you can redistribute it and/or modify it under  the
     11:    terms of version 3 of the GNU Lesser General Public License as published by
     12:    the Free Software Foundation.

     14:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
     15:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
     16:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
     17:    more details.

     19:    You  should have received a copy of the GNU Lesser General  Public  License
     20:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
     21:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     22: */

     24: #include <slepc/private/svdimpl.h>      /*I "slepcsvd.h" I*/

     26: PetscFunctionList SVDList = 0;
     27: PetscBool         SVDRegisterAllCalled = PETSC_FALSE;
     28: PetscClassId      SVD_CLASSID = 0;
     29: PetscLogEvent     SVD_SetUp = 0,SVD_Solve = 0;

     33: /*@
     34:    SVDCreate - Creates the default SVD context.

     36:    Collective on MPI_Comm

     38:    Input Parameter:
     39: .  comm - MPI communicator

     41:    Output Parameter:
     42: .  svd - location to put the SVD context

     44:    Note:
     45:    The default SVD type is SVDCROSS

     47:    Level: beginner

     49: .seealso: SVDSetUp(), SVDSolve(), SVDDestroy(), SVD
     50: @*/
     51: PetscErrorCode SVDCreate(MPI_Comm comm,SVD *outsvd)
     52: {
     54:   SVD            svd;

     58:   *outsvd = 0;
     59:   SVDInitializePackage();
     60:   SlepcHeaderCreate(svd,SVD_CLASSID,"SVD","Singular Value Decomposition","SVD",comm,SVDDestroy,SVDView);

     62:   svd->OP             = NULL;
     63:   svd->max_it         = 0;
     64:   svd->nsv            = 1;
     65:   svd->ncv            = 0;
     66:   svd->mpd            = 0;
     67:   svd->nini           = 0;
     68:   svd->ninil          = 0;
     69:   svd->tol            = PETSC_DEFAULT;
     70:   svd->which          = SVD_LARGEST;
     71:   svd->impltrans      = PETSC_FALSE;
     72:   svd->trackall       = PETSC_FALSE;

     74:   svd->numbermonitors = 0;

     76:   svd->ds             = NULL;
     77:   svd->U              = NULL;
     78:   svd->V              = NULL;
     79:   svd->rand           = NULL;
     80:   svd->A              = NULL;
     81:   svd->AT             = NULL;
     82:   svd->IS             = NULL;
     83:   svd->ISL            = NULL;
     84:   svd->sigma          = NULL;
     85:   svd->perm           = NULL;
     86:   svd->errest         = NULL;
     87:   svd->data           = NULL;

     89:   svd->state          = SVD_STATE_INITIAL;
     90:   svd->nconv          = 0;
     91:   svd->its            = 0;
     92:   svd->leftbasis      = PETSC_FALSE;
     93:   svd->reason         = SVD_CONVERGED_ITERATING;

     95:   PetscNewLog(svd,&svd->sc);
     96:   PetscRandomCreate(comm,&svd->rand);
     97:   PetscRandomSetSeed(svd->rand,0x12345678);
     98:   PetscLogObjectParent((PetscObject)svd,(PetscObject)svd->rand);
     99:   *outsvd = svd;
    100:   return(0);
    101: }

    105: /*@
    106:    SVDReset - Resets the SVD context to the initial state and removes any
    107:    allocated objects.

    109:    Collective on SVD

    111:    Input Parameter:
    112: .  svd - singular value solver context obtained from SVDCreate()

    114:    Level: advanced

    116: .seealso: SVDDestroy()
    117: @*/
    118: PetscErrorCode SVDReset(SVD svd)
    119: {
    121:   PetscInt       ncols;

    125:   if (svd->ops->reset) { (svd->ops->reset)(svd); }
    126:   if (svd->ds) { DSReset(svd->ds); }
    127:   MatDestroy(&svd->OP);
    128:   MatDestroy(&svd->A);
    129:   MatDestroy(&svd->AT);
    130:   BVGetSizes(svd->V,NULL,NULL,&ncols);
    131:   if (ncols) {
    132:     PetscFree3(svd->sigma,svd->perm,svd->errest);
    133:   }
    134:   BVDestroy(&svd->U);
    135:   BVDestroy(&svd->V);
    136:   svd->state = SVD_STATE_INITIAL;
    137:   return(0);
    138: }

    142: /*@
    143:    SVDDestroy - Destroys the SVD context.

    145:    Collective on SVD

    147:    Input Parameter:
    148: .  svd - singular value solver context obtained from SVDCreate()

    150:    Level: beginner

    152: .seealso: SVDCreate(), SVDSetUp(), SVDSolve()
    153: @*/
    154: PetscErrorCode SVDDestroy(SVD *svd)
    155: {

    159:   if (!*svd) return(0);
    161:   if (--((PetscObject)(*svd))->refct > 0) { *svd = 0; return(0); }
    162:   SVDReset(*svd);
    163:   if ((*svd)->ops->destroy) { (*(*svd)->ops->destroy)(*svd); }
    164:   DSDestroy(&(*svd)->ds);
    165:   PetscRandomDestroy(&(*svd)->rand);
    166:   PetscFree((*svd)->sc);
    167:   /* just in case the initial vectors have not been used */
    168:   SlepcBasisDestroy_Private(&(*svd)->nini,&(*svd)->IS);
    169:   SlepcBasisDestroy_Private(&(*svd)->ninil,&(*svd)->ISL);
    170:   SVDMonitorCancel(*svd);
    171:   PetscHeaderDestroy(svd);
    172:   return(0);
    173: }

    177: /*@C
    178:    SVDSetType - Selects the particular solver to be used in the SVD object.

    180:    Logically Collective on SVD

    182:    Input Parameters:
    183: +  svd      - the singular value solver context
    184: -  type     - a known method

    186:    Options Database Key:
    187: .  -svd_type <method> - Sets the method; use -help for a list
    188:     of available methods

    190:    Notes:
    191:    See "slepc/include/slepcsvd.h" for available methods. The default
    192:    is SVDCROSS.

    194:    Normally, it is best to use the SVDSetFromOptions() command and
    195:    then set the SVD type from the options database rather than by using
    196:    this routine.  Using the options database provides the user with
    197:    maximum flexibility in evaluating the different available methods.
    198:    The SVDSetType() routine is provided for those situations where it
    199:    is necessary to set the iterative solver independently of the command
    200:    line or options database.

    202:    Level: intermediate

    204: .seealso: SVDType
    205: @*/
    206: PetscErrorCode SVDSetType(SVD svd,SVDType type)
    207: {
    208:   PetscErrorCode ierr,(*r)(SVD);
    209:   PetscBool      match;

    215:   PetscObjectTypeCompare((PetscObject)svd,type,&match);
    216:   if (match) return(0);

    218:   PetscFunctionListFind(SVDList,type,&r);
    219:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown SVD type given: %s",type);

    221:   if (svd->ops->destroy) { (*svd->ops->destroy)(svd); }
    222:   PetscMemzero(svd->ops,sizeof(struct _SVDOps));

    224:   svd->state = SVD_STATE_INITIAL;
    225:   PetscObjectChangeTypeName((PetscObject)svd,type);
    226:   (*r)(svd);
    227:   return(0);
    228: }

    232: /*@C
    233:    SVDGetType - Gets the SVD type as a string from the SVD object.

    235:    Not Collective

    237:    Input Parameter:
    238: .  svd - the singular value solver context

    240:    Output Parameter:
    241: .  name - name of SVD method

    243:    Level: intermediate

    245: .seealso: SVDSetType()
    246: @*/
    247: PetscErrorCode SVDGetType(SVD svd,SVDType *type)
    248: {
    252:   *type = ((PetscObject)svd)->type_name;
    253:   return(0);
    254: }

    258: /*@C
    259:    SVDRegister - Adds a method to the singular value solver package.

    261:    Not Collective

    263:    Input Parameters:
    264: +  name - name of a new user-defined solver
    265: -  function - routine to create the solver context

    267:    Notes:
    268:    SVDRegister() may be called multiple times to add several user-defined solvers.

    270:    Sample usage:
    271: .vb
    272:    SVDRegister("my_solver",MySolverCreate);
    273: .ve

    275:    Then, your solver can be chosen with the procedural interface via
    276: $     SVDSetType(svd,"my_solver")
    277:    or at runtime via the option
    278: $     -svd_type my_solver

    280:    Level: advanced

    282: .seealso: SVDRegisterAll()
    283: @*/
    284: PetscErrorCode SVDRegister(const char *name,PetscErrorCode (*function)(SVD))
    285: {

    289:   PetscFunctionListAdd(&SVDList,name,function);
    290:   return(0);
    291: }

    295: /*@
    296:    SVDSetBV - Associates basis vectors objects to the singular value solver.

    298:    Collective on SVD

    300:    Input Parameters:
    301: +  svd - singular value solver context obtained from SVDCreate()
    302: .  V   - the basis vectors object for right singular vectors
    303: -  U   - the basis vectors object for left singular vectors

    305:    Note:
    306:    Use SVDGetBV() to retrieve the basis vectors contexts (for example,
    307:    to free them at the end of the computations).

    309:    Level: advanced

    311: .seealso: SVDGetBV()
    312: @*/
    313: PetscErrorCode SVDSetBV(SVD svd,BV V,BV U)
    314: {

    319:   if (V) {
    322:     PetscObjectReference((PetscObject)V);
    323:     BVDestroy(&svd->V);
    324:     svd->V = V;
    325:     PetscLogObjectParent((PetscObject)svd,(PetscObject)svd->V);
    326:   }
    327:   if (U) {
    330:     PetscObjectReference((PetscObject)U);
    331:     BVDestroy(&svd->U);
    332:     svd->U = U;
    333:     PetscLogObjectParent((PetscObject)svd,(PetscObject)svd->U);
    334:   }
    335:   return(0);
    336: }

    340: /*@
    341:    SVDGetBV - Obtain the basis vectors objects associated to the singular
    342:    value solver object.

    344:    Not Collective

    346:    Input Parameters:
    347: .  svd - singular value solver context obtained from SVDCreate()

    349:    Output Parameter:
    350: +  V - basis vectors context for right singular vectors
    351: -  U - basis vectors context for left singular vectors

    353:    Level: advanced

    355: .seealso: SVDSetBV()
    356: @*/
    357: PetscErrorCode SVDGetBV(SVD svd,BV *V,BV *U)
    358: {

    363:   if (V) {
    364:     if (!svd->V) {
    365:       BVCreate(PetscObjectComm((PetscObject)svd),&svd->V);
    366:       PetscLogObjectParent((PetscObject)svd,(PetscObject)svd->V);
    367:     }
    368:     *V = svd->V;
    369:   }
    370:   if (U) {
    371:     if (!svd->U) {
    372:       BVCreate(PetscObjectComm((PetscObject)svd),&svd->U);
    373:       PetscLogObjectParent((PetscObject)svd,(PetscObject)svd->U);
    374:     }
    375:     *U = svd->U;
    376:   }
    377:   return(0);
    378: }

    382: /*@
    383:    SVDSetDS - Associates a direct solver object to the singular value solver.

    385:    Collective on SVD

    387:    Input Parameters:
    388: +  svd - singular value solver context obtained from SVDCreate()
    389: -  ds  - the direct solver object

    391:    Note:
    392:    Use SVDGetDS() to retrieve the direct solver context (for example,
    393:    to free it at the end of the computations).

    395:    Level: advanced

    397: .seealso: SVDGetDS()
    398: @*/
    399: PetscErrorCode SVDSetDS(SVD svd,DS ds)
    400: {

    407:   PetscObjectReference((PetscObject)ds);
    408:   DSDestroy(&svd->ds);
    409:   svd->ds = ds;
    410:   PetscLogObjectParent((PetscObject)svd,(PetscObject)svd->ds);
    411:   return(0);
    412: }

    416: /*@
    417:    SVDGetDS - Obtain the direct solver object associated to the singular value
    418:    solver object.

    420:    Not Collective

    422:    Input Parameters:
    423: .  svd - singular value solver context obtained from SVDCreate()

    425:    Output Parameter:
    426: .  ds - direct solver context

    428:    Level: advanced

    430: .seealso: SVDSetDS()
    431: @*/
    432: PetscErrorCode SVDGetDS(SVD svd,DS *ds)
    433: {

    439:   if (!svd->ds) {
    440:     DSCreate(PetscObjectComm((PetscObject)svd),&svd->ds);
    441:     PetscLogObjectParent((PetscObject)svd,(PetscObject)svd->ds);
    442:   }
    443:   *ds = svd->ds;
    444:   return(0);
    445: }