LCOV - code coverage report
Current view: top level - svd/interface - svdbasic.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 181 190 95.3 %
Date: 2025-02-05 00:35:45 Functions: 10 11 90.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, 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             :    Basic SVD routines
      12             : */
      13             : 
      14             : #include <slepc/private/svdimpl.h>      /*I "slepcsvd.h" I*/
      15             : 
      16             : /* Logging support */
      17             : PetscClassId      SVD_CLASSID = 0;
      18             : PetscLogEvent     SVD_SetUp = 0,SVD_Solve = 0;
      19             : 
      20             : /* List of registered SVD routines */
      21             : PetscFunctionList SVDList = NULL;
      22             : PetscBool         SVDRegisterAllCalled = PETSC_FALSE;
      23             : 
      24             : /* List of registered SVD monitors */
      25             : PetscFunctionList SVDMonitorList              = NULL;
      26             : PetscFunctionList SVDMonitorCreateList        = NULL;
      27             : PetscFunctionList SVDMonitorDestroyList       = NULL;
      28             : PetscBool         SVDMonitorRegisterAllCalled = PETSC_FALSE;
      29             : 
      30             : /*@
      31             :    SVDCreate - Creates the default SVD context.
      32             : 
      33             :    Collective
      34             : 
      35             :    Input Parameter:
      36             : .  comm - MPI communicator
      37             : 
      38             :    Output Parameter:
      39             : .  outsvd - location to put the SVD context
      40             : 
      41             :    Note:
      42             :    The default SVD type is SVDCROSS
      43             : 
      44             :    Level: beginner
      45             : 
      46             : .seealso: SVDSetUp(), SVDSolve(), SVDDestroy(), SVD
      47             : @*/
      48         239 : PetscErrorCode SVDCreate(MPI_Comm comm,SVD *outsvd)
      49             : {
      50         239 :   SVD            svd;
      51             : 
      52         239 :   PetscFunctionBegin;
      53         239 :   PetscAssertPointer(outsvd,2);
      54         239 :   PetscCall(SVDInitializePackage());
      55         239 :   PetscCall(SlepcHeaderCreate(svd,SVD_CLASSID,"SVD","Singular Value Decomposition","SVD",comm,SVDDestroy,SVDView));
      56             : 
      57         239 :   svd->OP               = NULL;
      58         239 :   svd->OPb              = NULL;
      59         239 :   svd->omega            = NULL;
      60         239 :   svd->max_it           = PETSC_DETERMINE;
      61         239 :   svd->nsv              = 0;
      62         239 :   svd->ncv              = PETSC_DETERMINE;
      63         239 :   svd->mpd              = PETSC_DETERMINE;
      64         239 :   svd->nini             = 0;
      65         239 :   svd->ninil            = 0;
      66         239 :   svd->tol              = PETSC_DETERMINE;
      67         239 :   svd->thres            = 0.0;
      68         239 :   svd->threlative       = PETSC_FALSE;
      69         239 :   svd->conv             = (SVDConv)-1;
      70         239 :   svd->stop             = SVD_STOP_BASIC;
      71         239 :   svd->which            = SVD_LARGEST;
      72         239 :   svd->problem_type     = (SVDProblemType)0;
      73         239 :   svd->impltrans        = PETSC_FALSE;
      74         239 :   svd->trackall         = PETSC_FALSE;
      75             : 
      76         239 :   svd->converged        = NULL;
      77         239 :   svd->convergeduser    = NULL;
      78         239 :   svd->convergeddestroy = NULL;
      79         239 :   svd->stopping         = SVDStoppingBasic;
      80         239 :   svd->stoppinguser     = NULL;
      81         239 :   svd->stoppingdestroy  = NULL;
      82         239 :   svd->convergedctx     = NULL;
      83         239 :   svd->stoppingctx      = NULL;
      84         239 :   svd->numbermonitors   = 0;
      85             : 
      86         239 :   svd->ds               = NULL;
      87         239 :   svd->U                = NULL;
      88         239 :   svd->V                = NULL;
      89         239 :   svd->A                = NULL;
      90         239 :   svd->B                = NULL;
      91         239 :   svd->AT               = NULL;
      92         239 :   svd->BT               = NULL;
      93         239 :   svd->IS               = NULL;
      94         239 :   svd->ISL              = NULL;
      95         239 :   svd->sigma            = NULL;
      96         239 :   svd->errest           = NULL;
      97         239 :   svd->sign             = NULL;
      98         239 :   svd->perm             = NULL;
      99         239 :   svd->nworkl           = 0;
     100         239 :   svd->nworkr           = 0;
     101         239 :   svd->workl            = NULL;
     102         239 :   svd->workr            = NULL;
     103         239 :   svd->data             = NULL;
     104             : 
     105         239 :   svd->state            = SVD_STATE_INITIAL;
     106         239 :   svd->nconv            = 0;
     107         239 :   svd->its              = 0;
     108         239 :   svd->leftbasis        = PETSC_FALSE;
     109         239 :   svd->swapped          = PETSC_FALSE;
     110         239 :   svd->expltrans        = PETSC_FALSE;
     111         239 :   svd->nrma             = 0.0;
     112         239 :   svd->nrmb             = 0.0;
     113         239 :   svd->isgeneralized    = PETSC_FALSE;
     114         239 :   svd->reason           = SVD_CONVERGED_ITERATING;
     115             : 
     116         239 :   PetscCall(PetscNew(&svd->sc));
     117         239 :   *outsvd = svd;
     118         239 :   PetscFunctionReturn(PETSC_SUCCESS);
     119             : }
     120             : 
     121             : /*@
     122             :    SVDReset - Resets the SVD context to the initial state (prior to setup)
     123             :    and destroys any allocated Vecs and Mats.
     124             : 
     125             :    Collective
     126             : 
     127             :    Input Parameter:
     128             : .  svd - singular value solver context obtained from SVDCreate()
     129             : 
     130             :    Level: advanced
     131             : 
     132             : .seealso: SVDDestroy()
     133             : @*/
     134         245 : PetscErrorCode SVDReset(SVD svd)
     135             : {
     136         245 :   PetscFunctionBegin;
     137         245 :   if (svd) PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     138         245 :   if (!svd) PetscFunctionReturn(PETSC_SUCCESS);
     139         245 :   PetscTryTypeMethod(svd,reset);
     140         245 :   PetscCall(MatDestroy(&svd->OP));
     141         245 :   PetscCall(MatDestroy(&svd->OPb));
     142         245 :   PetscCall(VecDestroy(&svd->omega));
     143         245 :   PetscCall(MatDestroy(&svd->A));
     144         245 :   PetscCall(MatDestroy(&svd->B));
     145         245 :   PetscCall(MatDestroy(&svd->AT));
     146         245 :   PetscCall(MatDestroy(&svd->BT));
     147         245 :   PetscCall(BVDestroy(&svd->U));
     148         245 :   PetscCall(BVDestroy(&svd->V));
     149         245 :   PetscCall(VecDestroyVecs(svd->nworkl,&svd->workl));
     150         245 :   svd->nworkl = 0;
     151         245 :   PetscCall(VecDestroyVecs(svd->nworkr,&svd->workr));
     152         245 :   svd->nworkr = 0;
     153         245 :   svd->swapped = PETSC_FALSE;
     154         245 :   svd->state = SVD_STATE_INITIAL;
     155         245 :   PetscFunctionReturn(PETSC_SUCCESS);
     156             : }
     157             : 
     158             : /*@
     159             :    SVDDestroy - Destroys the SVD context.
     160             : 
     161             :    Collective
     162             : 
     163             :    Input Parameter:
     164             : .  svd - singular value solver context obtained from SVDCreate()
     165             : 
     166             :    Level: beginner
     167             : 
     168             : .seealso: SVDCreate(), SVDSetUp(), SVDSolve()
     169             : @*/
     170         239 : PetscErrorCode SVDDestroy(SVD *svd)
     171             : {
     172         239 :   PetscFunctionBegin;
     173         239 :   if (!*svd) PetscFunctionReturn(PETSC_SUCCESS);
     174         239 :   PetscValidHeaderSpecific(*svd,SVD_CLASSID,1);
     175         239 :   if (--((PetscObject)*svd)->refct > 0) { *svd = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
     176         239 :   PetscCall(SVDReset(*svd));
     177         239 :   PetscTryTypeMethod(*svd,destroy);
     178         239 :   if ((*svd)->sigma) PetscCall(PetscFree3((*svd)->sigma,(*svd)->perm,(*svd)->errest));
     179         239 :   if ((*svd)->sign) PetscCall(PetscFree((*svd)->sign));
     180         239 :   PetscCall(DSDestroy(&(*svd)->ds));
     181         239 :   PetscCall(PetscFree((*svd)->sc));
     182             :   /* just in case the initial vectors have not been used */
     183         239 :   PetscCall(SlepcBasisDestroy_Private(&(*svd)->nini,&(*svd)->IS));
     184         239 :   PetscCall(SlepcBasisDestroy_Private(&(*svd)->ninil,&(*svd)->ISL));
     185         239 :   if ((*svd)->convergeddestroy) PetscCall((*(*svd)->convergeddestroy)(&(*svd)->convergedctx));
     186         239 :   if ((*svd)->stoppingdestroy) PetscCall((*(*svd)->stoppingdestroy)(&(*svd)->stoppingctx));
     187         239 :   PetscCall(SVDMonitorCancel(*svd));
     188         239 :   PetscCall(PetscHeaderDestroy(svd));
     189         239 :   PetscFunctionReturn(PETSC_SUCCESS);
     190             : }
     191             : 
     192             : /*@
     193             :    SVDSetType - Selects the particular solver to be used in the SVD object.
     194             : 
     195             :    Logically Collective
     196             : 
     197             :    Input Parameters:
     198             : +  svd      - the singular value solver context
     199             : -  type     - a known method
     200             : 
     201             :    Options Database Key:
     202             : .  -svd_type <method> - Sets the method; use -help for a list
     203             :     of available methods
     204             : 
     205             :    Notes:
     206             :    See "slepc/include/slepcsvd.h" for available methods. The default
     207             :    is SVDCROSS.
     208             : 
     209             :    Normally, it is best to use the SVDSetFromOptions() command and
     210             :    then set the SVD type from the options database rather than by using
     211             :    this routine.  Using the options database provides the user with
     212             :    maximum flexibility in evaluating the different available methods.
     213             :    The SVDSetType() routine is provided for those situations where it
     214             :    is necessary to set the iterative solver independently of the command
     215             :    line or options database.
     216             : 
     217             :    Level: intermediate
     218             : 
     219             : .seealso: SVDType
     220             : @*/
     221         240 : PetscErrorCode SVDSetType(SVD svd,SVDType type)
     222             : {
     223         240 :   PetscErrorCode (*r)(SVD);
     224         240 :   PetscBool      match;
     225             : 
     226         240 :   PetscFunctionBegin;
     227         240 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     228         240 :   PetscAssertPointer(type,2);
     229             : 
     230         240 :   PetscCall(PetscObjectTypeCompare((PetscObject)svd,type,&match));
     231         240 :   if (match) PetscFunctionReturn(PETSC_SUCCESS);
     232             : 
     233         240 :   PetscCall(PetscFunctionListFind(SVDList,type,&r));
     234         240 :   PetscCheck(r,PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown SVD type given: %s",type);
     235             : 
     236         240 :   PetscTryTypeMethod(svd,destroy);
     237         240 :   PetscCall(PetscMemzero(svd->ops,sizeof(struct _SVDOps)));
     238             : 
     239         240 :   svd->state = SVD_STATE_INITIAL;
     240         240 :   PetscCall(PetscObjectChangeTypeName((PetscObject)svd,type));
     241         240 :   PetscCall((*r)(svd));
     242         240 :   PetscFunctionReturn(PETSC_SUCCESS);
     243             : }
     244             : 
     245             : /*@
     246             :    SVDGetType - Gets the SVD type as a string from the SVD object.
     247             : 
     248             :    Not Collective
     249             : 
     250             :    Input Parameter:
     251             : .  svd - the singular value solver context
     252             : 
     253             :    Output Parameter:
     254             : .  type - name of SVD method
     255             : 
     256             :    Level: intermediate
     257             : 
     258             : .seealso: SVDSetType()
     259             : @*/
     260          56 : PetscErrorCode SVDGetType(SVD svd,SVDType *type)
     261             : {
     262          56 :   PetscFunctionBegin;
     263          56 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     264          56 :   PetscAssertPointer(type,2);
     265          56 :   *type = ((PetscObject)svd)->type_name;
     266          56 :   PetscFunctionReturn(PETSC_SUCCESS);
     267             : }
     268             : 
     269             : /*@C
     270             :    SVDRegister - Adds a method to the singular value solver package.
     271             : 
     272             :    Not Collective
     273             : 
     274             :    Input Parameters:
     275             : +  name - name of a new user-defined solver
     276             : -  function - routine to create the solver context
     277             : 
     278             :    Notes:
     279             :    SVDRegister() may be called multiple times to add several user-defined solvers.
     280             : 
     281             :    Example Usage:
     282             : .vb
     283             :     SVDRegister("my_solver",MySolverCreate);
     284             : .ve
     285             : 
     286             :    Then, your solver can be chosen with the procedural interface via
     287             : $     SVDSetType(svd,"my_solver")
     288             :    or at runtime via the option
     289             : $     -svd_type my_solver
     290             : 
     291             :    Level: advanced
     292             : 
     293             : .seealso: SVDRegisterAll()
     294             : @*/
     295        1680 : PetscErrorCode SVDRegister(const char *name,PetscErrorCode (*function)(SVD))
     296             : {
     297        1680 :   PetscFunctionBegin;
     298        1680 :   PetscCall(SVDInitializePackage());
     299        1680 :   PetscCall(PetscFunctionListAdd(&SVDList,name,function));
     300        1680 :   PetscFunctionReturn(PETSC_SUCCESS);
     301             : }
     302             : 
     303             : /*@C
     304             :    SVDMonitorRegister - Adds SVD monitor routine.
     305             : 
     306             :    Not Collective
     307             : 
     308             :    Input Parameters:
     309             : +  name    - name of a new monitor routine
     310             : .  vtype   - a PetscViewerType for the output
     311             : .  format  - a PetscViewerFormat for the output
     312             : .  monitor - monitor routine
     313             : .  create  - creation routine, or NULL
     314             : -  destroy - destruction routine, or NULL
     315             : 
     316             :    Notes:
     317             :    SVDMonitorRegister() may be called multiple times to add several user-defined monitors.
     318             : 
     319             :    Example Usage:
     320             : .vb
     321             :    SVDMonitorRegister("my_monitor",PETSCVIEWERASCII,PETSC_VIEWER_ASCII_INFO_DETAIL,MyMonitor,NULL,NULL);
     322             : .ve
     323             : 
     324             :    Then, your monitor can be chosen with the procedural interface via
     325             : $      SVDMonitorSetFromOptions(svd,"-svd_monitor_my_monitor","my_monitor",NULL)
     326             :    or at runtime via the option
     327             : $      -svd_monitor_my_monitor
     328             : 
     329             :    Level: advanced
     330             : 
     331             : .seealso: SVDMonitorRegisterAll()
     332             : @*/
     333        1680 : PetscErrorCode SVDMonitorRegister(const char name[],PetscViewerType vtype,PetscViewerFormat format,PetscErrorCode (*monitor)(SVD,PetscInt,PetscInt,PetscReal*,PetscReal*,PetscInt,PetscViewerAndFormat*),PetscErrorCode (*create)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**),PetscErrorCode (*destroy)(PetscViewerAndFormat**))
     334             : {
     335        1680 :   char           key[PETSC_MAX_PATH_LEN];
     336             : 
     337        1680 :   PetscFunctionBegin;
     338        1680 :   PetscCall(SVDInitializePackage());
     339        1680 :   PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
     340        1680 :   PetscCall(PetscFunctionListAdd(&SVDMonitorList,key,monitor));
     341        1680 :   if (create)  PetscCall(PetscFunctionListAdd(&SVDMonitorCreateList,key,create));
     342        1680 :   if (destroy) PetscCall(PetscFunctionListAdd(&SVDMonitorDestroyList,key,destroy));
     343        1680 :   PetscFunctionReturn(PETSC_SUCCESS);
     344             : }
     345             : 
     346             : /*@
     347             :    SVDSetBV - Associates basis vectors objects to the singular value solver.
     348             : 
     349             :    Collective
     350             : 
     351             :    Input Parameters:
     352             : +  svd - singular value solver context obtained from SVDCreate()
     353             : .  V   - the basis vectors object for right singular vectors
     354             : -  U   - the basis vectors object for left singular vectors
     355             : 
     356             :    Note:
     357             :    Use SVDGetBV() to retrieve the basis vectors contexts (for example,
     358             :    to free them at the end of the computations).
     359             : 
     360             :    Level: advanced
     361             : 
     362             : .seealso: SVDGetBV()
     363             : @*/
     364           3 : PetscErrorCode SVDSetBV(SVD svd,BV V,BV U)
     365             : {
     366           3 :   PetscFunctionBegin;
     367           3 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     368           3 :   if (V) {
     369           3 :     PetscValidHeaderSpecific(V,BV_CLASSID,2);
     370           3 :     PetscCheckSameComm(svd,1,V,2);
     371           3 :     PetscCall(PetscObjectReference((PetscObject)V));
     372           3 :     PetscCall(BVDestroy(&svd->V));
     373           3 :     svd->V = V;
     374             :   }
     375           3 :   if (U) {
     376           3 :     PetscValidHeaderSpecific(U,BV_CLASSID,3);
     377           3 :     PetscCheckSameComm(svd,1,U,3);
     378           3 :     PetscCall(PetscObjectReference((PetscObject)U));
     379           3 :     PetscCall(BVDestroy(&svd->U));
     380           3 :     svd->U = U;
     381             :   }
     382           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     383             : }
     384             : 
     385             : /*@
     386             :    SVDGetBV - Obtain the basis vectors objects associated to the singular
     387             :    value solver object.
     388             : 
     389             :    Not Collective
     390             : 
     391             :    Input Parameter:
     392             : .  svd - singular value solver context obtained from SVDCreate()
     393             : 
     394             :    Output Parameters:
     395             : +  V - basis vectors context for right singular vectors
     396             : -  U - basis vectors context for left singular vectors
     397             : 
     398             :    Level: advanced
     399             : 
     400             : .seealso: SVDSetBV()
     401             : @*/
     402         482 : PetscErrorCode SVDGetBV(SVD svd,BV *V,BV *U)
     403             : {
     404         482 :   PetscFunctionBegin;
     405         482 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     406         482 :   if (V) {
     407         242 :     if (!svd->V) {
     408         242 :       PetscCall(BVCreate(PetscObjectComm((PetscObject)svd),&svd->V));
     409         242 :       PetscCall(PetscObjectIncrementTabLevel((PetscObject)svd->V,(PetscObject)svd,0));
     410         242 :       PetscCall(PetscObjectSetOptions((PetscObject)svd->V,((PetscObject)svd)->options));
     411             :     }
     412         242 :     *V = svd->V;
     413             :   }
     414         482 :   if (U) {
     415         240 :     if (!svd->U) {
     416         240 :       PetscCall(BVCreate(PetscObjectComm((PetscObject)svd),&svd->U));
     417         240 :       PetscCall(PetscObjectIncrementTabLevel((PetscObject)svd->U,(PetscObject)svd,0));
     418         240 :       PetscCall(PetscObjectSetOptions((PetscObject)svd->U,((PetscObject)svd)->options));
     419             :     }
     420         240 :     *U = svd->U;
     421             :   }
     422         482 :   PetscFunctionReturn(PETSC_SUCCESS);
     423             : }
     424             : 
     425             : /*@
     426             :    SVDSetDS - Associates a direct solver object to the singular value solver.
     427             : 
     428             :    Collective
     429             : 
     430             :    Input Parameters:
     431             : +  svd - singular value solver context obtained from SVDCreate()
     432             : -  ds  - the direct solver object
     433             : 
     434             :    Note:
     435             :    Use SVDGetDS() to retrieve the direct solver context (for example,
     436             :    to free it at the end of the computations).
     437             : 
     438             :    Level: advanced
     439             : 
     440             : .seealso: SVDGetDS()
     441             : @*/
     442           0 : PetscErrorCode SVDSetDS(SVD svd,DS ds)
     443             : {
     444           0 :   PetscFunctionBegin;
     445           0 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     446           0 :   PetscValidHeaderSpecific(ds,DS_CLASSID,2);
     447           0 :   PetscCheckSameComm(svd,1,ds,2);
     448           0 :   PetscCall(PetscObjectReference((PetscObject)ds));
     449           0 :   PetscCall(DSDestroy(&svd->ds));
     450           0 :   svd->ds = ds;
     451           0 :   PetscFunctionReturn(PETSC_SUCCESS);
     452             : }
     453             : 
     454             : /*@
     455             :    SVDGetDS - Obtain the direct solver object associated to the singular value
     456             :    solver object.
     457             : 
     458             :    Not Collective
     459             : 
     460             :    Input Parameters:
     461             : .  svd - singular value solver context obtained from SVDCreate()
     462             : 
     463             :    Output Parameter:
     464             : .  ds - direct solver context
     465             : 
     466             :    Level: advanced
     467             : 
     468             : .seealso: SVDSetDS()
     469             : @*/
     470         239 : PetscErrorCode SVDGetDS(SVD svd,DS *ds)
     471             : {
     472         239 :   PetscFunctionBegin;
     473         239 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     474         239 :   PetscAssertPointer(ds,2);
     475         239 :   if (!svd->ds) {
     476         239 :     PetscCall(DSCreate(PetscObjectComm((PetscObject)svd),&svd->ds));
     477         239 :     PetscCall(PetscObjectIncrementTabLevel((PetscObject)svd->ds,(PetscObject)svd,0));
     478         239 :     PetscCall(PetscObjectSetOptions((PetscObject)svd->ds,((PetscObject)svd)->options));
     479             :   }
     480         239 :   *ds = svd->ds;
     481         239 :   PetscFunctionReturn(PETSC_SUCCESS);
     482             : }

Generated by: LCOV version 1.14