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 SVD111: 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 SVD147: 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 SVD182: 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: SVDType205: @*/
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 SVD300: 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 SVD387: 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: }