Actual source code: svdbasic.c

slepc-3.6.1 2015-09-03
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: }