1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2021, Universitat Politecnica de Valencia, Spain
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 solver options
12: */
14: #include <slepc/private/svdimpl.h> 15: #include <petscdraw.h>
17: /*@
18: SVDSetImplicitTranspose - Indicates how to handle the transpose of the matrix
19: associated with the singular value problem.
21: Logically Collective on svd
23: Input Parameters:
24: + svd - the singular value solver context
25: - impl - how to handle the transpose (implicitly or not)
27: Options Database Key:
28: . -svd_implicittranspose - Activate the implicit transpose mode.
30: Notes:
31: By default, the transpose of the matrix is explicitly built (if the matrix
32: has defined the MatTranspose operation).
34: If this flag is set to true, the solver does not build the transpose, but
35: handles it implicitly via MatMultTranspose() (or MatMultHermitianTranspose()
36: in the complex case) operations. This is likely to be more inefficient
37: than the default behaviour, both in sequential and in parallel, but
38: requires less storage.
40: Level: advanced
42: .seealso: SVDGetImplicitTranspose(), SVDSolve(), SVDSetOperators()
43: @*/
44: PetscErrorCode SVDSetImplicitTranspose(SVD svd,PetscBool impl) 45: {
49: if (svd->impltrans!=impl) {
50: svd->impltrans = impl;
51: svd->state = SVD_STATE_INITIAL;
52: }
53: return(0);
54: }
56: /*@
57: SVDGetImplicitTranspose - Gets the mode used to handle the transpose
58: of the matrix associated with the singular value problem.
60: Not Collective
62: Input Parameter:
63: . svd - the singular value solver context
65: Output Parameter:
66: . impl - how to handle the transpose (implicitly or not)
68: Level: advanced
70: .seealso: SVDSetImplicitTranspose(), SVDSolve(), SVDSetOperators()
71: @*/
72: PetscErrorCode SVDGetImplicitTranspose(SVD svd,PetscBool *impl) 73: {
77: *impl = svd->impltrans;
78: return(0);
79: }
81: /*@
82: SVDSetTolerances - Sets the tolerance and maximum
83: iteration count used by the default SVD convergence testers.
85: Logically Collective on svd
87: Input Parameters:
88: + svd - the singular value solver context
89: . tol - the convergence tolerance
90: - maxits - maximum number of iterations to use
92: Options Database Keys:
93: + -svd_tol <tol> - Sets the convergence tolerance
94: - -svd_max_it <maxits> - Sets the maximum number of iterations allowed
96: Note:
97: Use PETSC_DEFAULT for either argument to assign a reasonably good value.
99: Level: intermediate
101: .seealso: SVDGetTolerances()
102: @*/
103: PetscErrorCode SVDSetTolerances(SVD svd,PetscReal tol,PetscInt maxits)104: {
109: if (tol == PETSC_DEFAULT) {
110: svd->tol = PETSC_DEFAULT;
111: svd->state = SVD_STATE_INITIAL;
112: } else {
113: if (tol <= 0.0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
114: svd->tol = tol;
115: }
116: if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
117: svd->max_it = PETSC_DEFAULT;
118: svd->state = SVD_STATE_INITIAL;
119: } else {
120: if (maxits <= 0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
121: svd->max_it = maxits;
122: }
123: return(0);
124: }
126: /*@C
127: SVDGetTolerances - Gets the tolerance and maximum
128: iteration count used by the default SVD convergence tests.
130: Not Collective
132: Input Parameter:
133: . svd - the singular value solver context
135: Output Parameters:
136: + tol - the convergence tolerance
137: - maxits - maximum number of iterations
139: Notes:
140: The user can specify NULL for any parameter that is not needed.
142: Level: intermediate
144: .seealso: SVDSetTolerances()
145: @*/
146: PetscErrorCode SVDGetTolerances(SVD svd,PetscReal *tol,PetscInt *maxits)147: {
150: if (tol) *tol = svd->tol;
151: if (maxits) *maxits = svd->max_it;
152: return(0);
153: }
155: /*@
156: SVDSetDimensions - Sets the number of singular values to compute
157: and the dimension of the subspace.
159: Logically Collective on svd
161: Input Parameters:
162: + svd - the singular value solver context
163: . nsv - number of singular values to compute
164: . ncv - the maximum dimension of the subspace to be used by the solver
165: - mpd - the maximum dimension allowed for the projected problem
167: Options Database Keys:
168: + -svd_nsv <nsv> - Sets the number of singular values
169: . -svd_ncv <ncv> - Sets the dimension of the subspace
170: - -svd_mpd <mpd> - Sets the maximum projected dimension
172: Notes:
173: Use PETSC_DEFAULT for ncv and mpd to assign a reasonably good value, which is
174: dependent on the solution method and the number of singular values required.
176: The parameters ncv and mpd are intimately related, so that the user is advised
177: to set one of them at most. Normal usage is that
178: (a) in cases where nsv is small, the user sets ncv (a reasonable default is 2*nsv); and
179: (b) in cases where nsv is large, the user sets mpd.
181: The value of ncv should always be between nsv and (nsv+mpd), typically
182: ncv=nsv+mpd. If nsv is not too large, mpd=nsv is a reasonable choice, otherwise
183: a smaller value should be used.
185: Level: intermediate
187: .seealso: SVDGetDimensions()
188: @*/
189: PetscErrorCode SVDSetDimensions(SVD svd,PetscInt nsv,PetscInt ncv,PetscInt mpd)190: {
196: if (nsv<1) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of nsv. Must be > 0");
197: svd->nsv = nsv;
198: if (ncv == PETSC_DEFAULT || ncv == PETSC_DECIDE) {
199: svd->ncv = PETSC_DEFAULT;
200: } else {
201: if (ncv<1) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
202: svd->ncv = ncv;
203: }
204: if (mpd == PETSC_DECIDE || mpd == PETSC_DEFAULT) {
205: svd->mpd = PETSC_DEFAULT;
206: } else {
207: if (mpd<1) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of mpd. Must be > 0");
208: svd->mpd = mpd;
209: }
210: svd->state = SVD_STATE_INITIAL;
211: return(0);
212: }
214: /*@C
215: SVDGetDimensions - Gets the number of singular values to compute
216: and the dimension of the subspace.
218: Not Collective
220: Input Parameter:
221: . svd - the singular value context
223: Output Parameters:
224: + nsv - number of singular values to compute
225: . ncv - the maximum dimension of the subspace to be used by the solver
226: - mpd - the maximum dimension allowed for the projected problem
228: Notes:
229: The user can specify NULL for any parameter that is not needed.
231: Level: intermediate
233: .seealso: SVDSetDimensions()
234: @*/
235: PetscErrorCode SVDGetDimensions(SVD svd,PetscInt *nsv,PetscInt *ncv,PetscInt *mpd)236: {
239: if (nsv) *nsv = svd->nsv;
240: if (ncv) *ncv = svd->ncv;
241: if (mpd) *mpd = svd->mpd;
242: return(0);
243: }
245: /*@
246: SVDSetWhichSingularTriplets - Specifies which singular triplets are
247: to be sought.
249: Logically Collective on svd
251: Input Parameter:
252: . svd - singular value solver context obtained from SVDCreate()
254: Output Parameter:
255: . which - which singular triplets are to be sought
257: Possible values:
258: The parameter 'which' can have one of these values
260: + SVD_LARGEST - largest singular values
261: - SVD_SMALLEST - smallest singular values
263: Options Database Keys:
264: + -svd_largest - Sets largest singular values
265: - -svd_smallest - Sets smallest singular values
267: Level: intermediate
269: .seealso: SVDGetWhichSingularTriplets(), SVDWhich270: @*/
271: PetscErrorCode SVDSetWhichSingularTriplets(SVD svd,SVDWhich which)272: {
276: switch (which) {
277: case SVD_LARGEST:
278: case SVD_SMALLEST:
279: if (svd->which != which) {
280: svd->state = SVD_STATE_INITIAL;
281: svd->which = which;
282: }
283: break;
284: default:285: SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'which' parameter");
286: }
287: return(0);
288: }
290: /*@
291: SVDGetWhichSingularTriplets - Returns which singular triplets are
292: to be sought.
294: Not Collective
296: Input Parameter:
297: . svd - singular value solver context obtained from SVDCreate()
299: Output Parameter:
300: . which - which singular triplets are to be sought
302: Notes:
303: See SVDSetWhichSingularTriplets() for possible values of which
305: Level: intermediate
307: .seealso: SVDSetWhichSingularTriplets(), SVDWhich308: @*/
309: PetscErrorCode SVDGetWhichSingularTriplets(SVD svd,SVDWhich *which)310: {
314: *which = svd->which;
315: return(0);
316: }
318: /*@C
319: SVDSetConvergenceTestFunction - Sets a function to compute the error estimate
320: used in the convergence test.
322: Logically Collective on svd
324: Input Parameters:
325: + svd - singular value solver context obtained from SVDCreate()
326: . func - a pointer to the convergence test function
327: . ctx - context for private data for the convergence routine (may be null)
328: - destroy - a routine for destroying the context (may be null)
330: Calling Sequence of func:
331: $ func(SVD svd,PetscReal sigma,PetscReal res,PetscReal *errest,void *ctx)
333: + svd - singular value solver context obtained from SVDCreate()
334: . sigma - computed singular value
335: . res - residual norm associated to the singular triplet
336: . errest - (output) computed error estimate
337: - ctx - optional context, as set by SVDSetConvergenceTestFunction()
339: Note:
340: If the error estimate returned by the convergence test function is less than
341: the tolerance, then the singular value is accepted as converged.
343: Level: advanced
345: .seealso: SVDSetConvergenceTest(), SVDSetTolerances()
346: @*/
347: PetscErrorCode SVDSetConvergenceTestFunction(SVD svd,PetscErrorCode (*func)(SVD,PetscReal,PetscReal,PetscReal*,void*),void* ctx,PetscErrorCode (*destroy)(void*))348: {
353: if (svd->convergeddestroy) {
354: (*svd->convergeddestroy)(svd->convergedctx);
355: }
356: svd->convergeduser = func;
357: svd->convergeddestroy = destroy;
358: svd->convergedctx = ctx;
359: if (func == SVDConvergedAbsolute) svd->conv = SVD_CONV_ABS;
360: else if (func == SVDConvergedRelative) svd->conv = SVD_CONV_REL;
361: else if (func == SVDConvergedNorm) svd->conv = SVD_CONV_NORM;
362: else if (func == SVDConvergedMaxIt) svd->conv = SVD_CONV_MAXIT;
363: else {
364: svd->conv = SVD_CONV_USER;
365: svd->converged = svd->convergeduser;
366: }
367: return(0);
368: }
370: /*@
371: SVDSetConvergenceTest - Specifies how to compute the error estimate
372: used in the convergence test.
374: Logically Collective on svd
376: Input Parameters:
377: + svd - singular value solver context obtained from SVDCreate()
378: - conv - the type of convergence test
380: Options Database Keys:
381: + -svd_conv_abs - Sets the absolute convergence test
382: . -svd_conv_rel - Sets the convergence test relative to the singular value
383: . -svd_conv_norm - Sets the convergence test relative to the matrix norms
384: . -svd_conv_maxit - Forces the maximum number of iterations as set by -svd_max_it
385: - -svd_conv_user - Selects the user-defined convergence test
387: Note:
388: The parameter 'conv' can have one of these values
389: + SVD_CONV_ABS - absolute error ||r||
390: . SVD_CONV_REL - error relative to the singular value l, ||r||/sigma
391: . SVD_CONV_NORM - error relative to the matrix norms, ||r||/||A||
392: . SVD_CONV_MAXIT - no convergence until maximum number of iterations has been reached
393: - SVD_CONV_USER - function set by SVDSetConvergenceTestFunction()
395: Level: intermediate
397: .seealso: SVDGetConvergenceTest(), SVDSetConvergenceTestFunction(), SVDSetStoppingTest(), SVDConv398: @*/
399: PetscErrorCode SVDSetConvergenceTest(SVD svd,SVDConv conv)400: {
404: switch (conv) {
405: case SVD_CONV_ABS: svd->converged = SVDConvergedAbsolute; break;
406: case SVD_CONV_REL: svd->converged = SVDConvergedRelative; break;
407: case SVD_CONV_NORM: svd->converged = SVDConvergedNorm; break;
408: case SVD_CONV_MAXIT: svd->converged = SVDConvergedMaxIt; break;
409: case SVD_CONV_USER:
410: if (!svd->convergeduser) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ORDER,"Must call SVDSetConvergenceTestFunction() first");
411: svd->converged = svd->convergeduser;
412: break;
413: default:414: SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'conv' value");
415: }
416: svd->conv = conv;
417: return(0);
418: }
420: /*@
421: SVDGetConvergenceTest - Gets the method used to compute the error estimate
422: used in the convergence test.
424: Not Collective
426: Input Parameters:
427: . svd - singular value solver context obtained from SVDCreate()
429: Output Parameters:
430: . conv - the type of convergence test
432: Level: intermediate
434: .seealso: SVDSetConvergenceTest(), SVDConv435: @*/
436: PetscErrorCode SVDGetConvergenceTest(SVD svd,SVDConv *conv)437: {
441: *conv = svd->conv;
442: return(0);
443: }
445: /*@C
446: SVDSetStoppingTestFunction - Sets a function to decide when to stop the outer
447: iteration of the singular value solver.
449: Logically Collective on svd
451: Input Parameters:
452: + svd - singular value solver context obtained from SVDCreate()
453: . func - pointer to the stopping test function
454: . ctx - context for private data for the stopping routine (may be null)
455: - destroy - a routine for destroying the context (may be null)
457: Calling Sequence of func:
458: $ func(SVD svd,PetscInt its,PetscInt max_it,PetscInt nconv,PetscInt nsv,SVDConvergedReason *reason,void *ctx)
460: + svd - singular value solver context obtained from SVDCreate()
461: . its - current number of iterations
462: . max_it - maximum number of iterations
463: . nconv - number of currently converged singular triplets
464: . nsv - number of requested singular triplets
465: . reason - (output) result of the stopping test
466: - ctx - optional context, as set by SVDSetStoppingTestFunction()
468: Note:
469: Normal usage is to first call the default routine SVDStoppingBasic() and then
470: set reason to SVD_CONVERGED_USER if some user-defined conditions have been
471: met. To let the singular value solver continue iterating, the result must be
472: left as SVD_CONVERGED_ITERATING.
474: Level: advanced
476: .seealso: SVDSetStoppingTest(), SVDStoppingBasic()
477: @*/
478: PetscErrorCode SVDSetStoppingTestFunction(SVD svd,PetscErrorCode (*func)(SVD,PetscInt,PetscInt,PetscInt,PetscInt,SVDConvergedReason*,void*),void* ctx,PetscErrorCode (*destroy)(void*))479: {
484: if (svd->stoppingdestroy) {
485: (*svd->stoppingdestroy)(svd->stoppingctx);
486: }
487: svd->stoppinguser = func;
488: svd->stoppingdestroy = destroy;
489: svd->stoppingctx = ctx;
490: if (func == SVDStoppingBasic) svd->stop = SVD_STOP_BASIC;
491: else {
492: svd->stop = SVD_STOP_USER;
493: svd->stopping = svd->stoppinguser;
494: }
495: return(0);
496: }
498: /*@
499: SVDSetStoppingTest - Specifies how to decide the termination of the outer
500: loop of the singular value solver.
502: Logically Collective on svd
504: Input Parameters:
505: + svd - singular value solver context obtained from SVDCreate()
506: - stop - the type of stopping test
508: Options Database Keys:
509: + -svd_stop_basic - Sets the default stopping test
510: - -svd_stop_user - Selects the user-defined stopping test
512: Note:
513: The parameter 'stop' can have one of these values
514: + SVD_STOP_BASIC - default stopping test
515: - SVD_STOP_USER - function set by SVDSetStoppingTestFunction()
517: Level: advanced
519: .seealso: SVDGetStoppingTest(), SVDSetStoppingTestFunction(), SVDSetConvergenceTest(), SVDStop520: @*/
521: PetscErrorCode SVDSetStoppingTest(SVD svd,SVDStop stop)522: {
526: switch (stop) {
527: case SVD_STOP_BASIC: svd->stopping = SVDStoppingBasic; break;
528: case SVD_STOP_USER:
529: if (!svd->stoppinguser) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ORDER,"Must call SVDSetStoppingTestFunction() first");
530: svd->stopping = svd->stoppinguser;
531: break;
532: default:533: SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'stop' value");
534: }
535: svd->stop = stop;
536: return(0);
537: }
539: /*@
540: SVDGetStoppingTest - Gets the method used to decide the termination of the outer
541: loop of the singular value solver.
543: Not Collective
545: Input Parameters:
546: . svd - singular value solver context obtained from SVDCreate()
548: Output Parameters:
549: . stop - the type of stopping test
551: Level: advanced
553: .seealso: SVDSetStoppingTest(), SVDStop554: @*/
555: PetscErrorCode SVDGetStoppingTest(SVD svd,SVDStop *stop)556: {
560: *stop = svd->stop;
561: return(0);
562: }
564: /*@C
565: SVDMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
566: indicated by the user.
568: Collective on svd
570: Input Parameters:
571: + svd - the singular value solver context
572: . opt - the command line option for this monitor
573: . name - the monitor type one is seeking
574: . ctx - an optional user context for the monitor, or NULL
575: - trackall - whether this monitor tracks all singular values or not
577: Level: developer
579: .seealso: SVDMonitorSet(), SVDSetTrackAll()
580: @*/
581: PetscErrorCode SVDMonitorSetFromOptions(SVD svd,const char opt[],const char name[],void *ctx,PetscBool trackall)582: {
583: PetscErrorCode (*mfunc)(SVD,PetscInt,PetscInt,PetscReal*,PetscReal*,PetscInt,void*);
584: PetscErrorCode (*cfunc)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);
585: PetscErrorCode (*dfunc)(PetscViewerAndFormat**);
586: PetscViewerAndFormat *vf;
587: PetscViewer viewer;
588: PetscViewerFormat format;
589: PetscViewerType vtype;
590: char key[PETSC_MAX_PATH_LEN];
591: PetscBool flg;
592: PetscErrorCode ierr;
595: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,opt,&viewer,&format,&flg);
596: if (!flg) return(0);
598: PetscViewerGetType(viewer,&vtype);
599: SlepcMonitorMakeKey_Internal(name,vtype,format,key);
600: PetscFunctionListFind(SVDMonitorList,key,&mfunc);
601: PetscFunctionListFind(SVDMonitorCreateList,key,&cfunc);
602: PetscFunctionListFind(SVDMonitorDestroyList,key,&dfunc);
603: if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
604: if (!dfunc) dfunc = PetscViewerAndFormatDestroy;
606: (*cfunc)(viewer,format,ctx,&vf);
607: PetscObjectDereference((PetscObject)viewer);
608: SVDMonitorSet(svd,mfunc,vf,(PetscErrorCode(*)(void **))dfunc);
609: if (trackall) {
610: SVDSetTrackAll(svd,PETSC_TRUE);
611: }
612: return(0);
613: }
615: /*@
616: SVDSetFromOptions - Sets SVD options from the options database.
617: This routine must be called before SVDSetUp() if the user is to be
618: allowed to set the solver type.
620: Collective on svd
622: Input Parameters:
623: . svd - the singular value solver context
625: Notes:
626: To see all options, run your program with the -help option.
628: Level: beginner
630: .seealso:
631: @*/
632: PetscErrorCode SVDSetFromOptions(SVD svd)633: {
635: char type[256];
636: PetscBool set,flg,val,flg1,flg2,flg3;
637: PetscInt i,j,k;
638: PetscReal r;
642: SVDRegisterAll();
643: PetscObjectOptionsBegin((PetscObject)svd);
644: PetscOptionsFList("-svd_type","SVD solver method","SVDSetType",SVDList,(char*)(((PetscObject)svd)->type_name?((PetscObject)svd)->type_name:SVDCROSS),type,sizeof(type),&flg);
645: if (flg) {
646: SVDSetType(svd,type);
647: } else if (!((PetscObject)svd)->type_name) {
648: SVDSetType(svd,SVDCROSS);
649: }
651: PetscOptionsBoolGroupBegin("-svd_standard","Singular value decomposition (SVD)","SVDSetProblemType",&flg);
652: if (flg) { SVDSetProblemType(svd,SVD_STANDARD); }
653: PetscOptionsBoolGroupEnd("-svd_generalized","Generalized singular value decomposition (GSVD)","SVDSetProblemType",&flg);
654: if (flg) { SVDSetProblemType(svd,SVD_GENERALIZED); }
656: PetscOptionsBool("-svd_implicittranspose","Handle matrix transpose implicitly","SVDSetImplicitTranspose",svd->impltrans,&val,&flg);
657: if (flg) { SVDSetImplicitTranspose(svd,val); }
659: i = svd->max_it;
660: PetscOptionsInt("-svd_max_it","Maximum number of iterations","SVDSetTolerances",svd->max_it,&i,&flg1);
661: r = svd->tol;
662: PetscOptionsReal("-svd_tol","Tolerance","SVDSetTolerances",SlepcDefaultTol(svd->tol),&r,&flg2);
663: if (flg1 || flg2) { SVDSetTolerances(svd,r,i); }
665: PetscOptionsBoolGroupBegin("-svd_conv_abs","Absolute error convergence test","SVDSetConvergenceTest",&flg);
666: if (flg) { SVDSetConvergenceTest(svd,SVD_CONV_ABS); }
667: PetscOptionsBoolGroup("-svd_conv_rel","Relative error convergence test","SVDSetConvergenceTest",&flg);
668: if (flg) { SVDSetConvergenceTest(svd,SVD_CONV_REL); }
669: PetscOptionsBoolGroup("-svd_conv_norm","Convergence test relative to the matrix norms","SVDSetConvergenceTest",&flg);
670: if (flg) { SVDSetConvergenceTest(svd,SVD_CONV_NORM); }
671: PetscOptionsBoolGroup("-svd_conv_maxit","Maximum iterations convergence test","SVDSetConvergenceTest",&flg);
672: if (flg) { SVDSetConvergenceTest(svd,SVD_CONV_MAXIT); }
673: PetscOptionsBoolGroupEnd("-svd_conv_user","User-defined convergence test","SVDSetConvergenceTest",&flg);
674: if (flg) { SVDSetConvergenceTest(svd,SVD_CONV_USER); }
676: PetscOptionsBoolGroupBegin("-svd_stop_basic","Stop iteration if all singular values converged or max_it reached","SVDSetStoppingTest",&flg);
677: if (flg) { SVDSetStoppingTest(svd,SVD_STOP_BASIC); }
678: PetscOptionsBoolGroupEnd("-svd_stop_user","User-defined stopping test","SVDSetStoppingTest",&flg);
679: if (flg) { SVDSetStoppingTest(svd,SVD_STOP_USER); }
681: i = svd->nsv;
682: PetscOptionsInt("-svd_nsv","Number of singular values to compute","SVDSetDimensions",svd->nsv,&i,&flg1);
683: j = svd->ncv;
684: PetscOptionsInt("-svd_ncv","Number of basis vectors","SVDSetDimensions",svd->ncv,&j,&flg2);
685: k = svd->mpd;
686: PetscOptionsInt("-svd_mpd","Maximum dimension of projected problem","SVDSetDimensions",svd->mpd,&k,&flg3);
687: if (flg1 || flg2 || flg3) { SVDSetDimensions(svd,i,j,k); }
689: PetscOptionsBoolGroupBegin("-svd_largest","Compute largest singular values","SVDSetWhichSingularTriplets",&flg);
690: if (flg) { SVDSetWhichSingularTriplets(svd,SVD_LARGEST); }
691: PetscOptionsBoolGroupEnd("-svd_smallest","Compute smallest singular values","SVDSetWhichSingularTriplets",&flg);
692: if (flg) { SVDSetWhichSingularTriplets(svd,SVD_SMALLEST); }
694: /* -----------------------------------------------------------------------*/
695: /*
696: Cancels all monitors hardwired into code before call to SVDSetFromOptions()
697: */
698: PetscOptionsBool("-svd_monitor_cancel","Remove any hardwired monitor routines","SVDMonitorCancel",PETSC_FALSE,&flg,&set);
699: if (set && flg) { SVDMonitorCancel(svd); }
700: SVDMonitorSetFromOptions(svd,"-svd_monitor","first_approximation",NULL,PETSC_FALSE);
701: SVDMonitorSetFromOptions(svd,"-svd_monitor_all","all_approximations",NULL,PETSC_TRUE);
702: SVDMonitorSetFromOptions(svd,"-svd_monitor_conv","convergence_history",NULL,PETSC_FALSE);
704: /* -----------------------------------------------------------------------*/
705: PetscOptionsName("-svd_view","Print detailed information on solver used","SVDView",NULL);
706: PetscOptionsName("-svd_view_vectors","View computed singular vectors","SVDVectorsView",NULL);
707: PetscOptionsName("-svd_view_values","View computed singular values","SVDValuesView",NULL);
708: PetscOptionsName("-svd_converged_reason","Print reason for convergence, and number of iterations","SVDConvergedReasonView",NULL);
709: PetscOptionsName("-svd_error_absolute","Print absolute errors of each singular triplet","SVDErrorView",NULL);
710: PetscOptionsName("-svd_error_relative","Print relative errors of each singular triplet","SVDErrorView",NULL);
712: if (svd->ops->setfromoptions) {
713: (*svd->ops->setfromoptions)(PetscOptionsObject,svd);
714: }
715: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)svd);
716: PetscOptionsEnd();
718: if (!svd->V) { SVDGetBV(svd,&svd->V,NULL); }
719: BVSetFromOptions(svd->V);
720: if (!svd->U) { SVDGetBV(svd,NULL,&svd->U); }
721: BVSetFromOptions(svd->U);
722: if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
723: DSSetFromOptions(svd->ds);
724: return(0);
725: }
727: /*@
728: SVDSetProblemType - Specifies the type of the singular value problem.
730: Logically Collective on svd
732: Input Parameters:
733: + svd - the singular value solver context
734: - type - a known type of singular value problem
736: Options Database Keys:
737: + -svd_standard - standard singular value decomposition (SVD)
738: - -svd_generalized - generalized singular value problem (GSVD)
740: Notes:
741: The GSVD requires that two matrices have been passed via SVDSetOperators().
743: Level: intermediate
745: .seealso: SVDSetOperators(), SVDSetType(), SVDGetProblemType(), SVDProblemType746: @*/
747: PetscErrorCode SVDSetProblemType(SVD svd,SVDProblemType type)748: {
752: if (type == svd->problem_type) return(0);
753: switch (type) {
754: case SVD_STANDARD:
755: svd->isgeneralized = PETSC_FALSE;
756: break;
757: case SVD_GENERALIZED:
758: svd->isgeneralized = PETSC_TRUE;
759: break;
760: default:761: SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_WRONG,"Unknown singular value problem type");
762: }
763: svd->problem_type = type;
764: svd->state = SVD_STATE_INITIAL;
765: return(0);
766: }
768: /*@
769: SVDGetProblemType - Gets the problem type from the SVD object.
771: Not Collective
773: Input Parameter:
774: . svd - the singular value solver context
776: Output Parameter:
777: . type - the problem type
779: Level: intermediate
781: .seealso: SVDSetProblemType(), SVDProblemType782: @*/
783: PetscErrorCode SVDGetProblemType(SVD svd,SVDProblemType *type)784: {
788: *type = svd->problem_type;
789: return(0);
790: }
792: /*@
793: SVDIsGeneralized - Ask if the SVD object corresponds to a generalized
794: singular value problem.
796: Not collective
798: Input Parameter:
799: . svd - the singular value solver context
801: Output Parameter:
802: . is - the answer
804: Level: intermediate
806: .seealso: SVDIsHermitian(), SVDIsPositive()
807: @*/
808: PetscErrorCode SVDIsGeneralized(SVD svd,PetscBool* is)809: {
813: *is = svd->isgeneralized;
814: return(0);
815: }
817: /*@
818: SVDSetTrackAll - Specifies if the solver must compute the residual norm of all
819: approximate singular value or not.
821: Logically Collective on svd
823: Input Parameters:
824: + svd - the singular value solver context
825: - trackall - whether to compute all residuals or not
827: Notes:
828: If the user sets trackall=PETSC_TRUE then the solver computes (or estimates)
829: the residual norm for each singular value approximation. Computing the residual is
830: usually an expensive operation and solvers commonly compute only the residual
831: associated to the first unconverged singular value.
833: The option '-svd_monitor_all' automatically activates this option.
835: Level: developer
837: .seealso: SVDGetTrackAll()
838: @*/
839: PetscErrorCode SVDSetTrackAll(SVD svd,PetscBool trackall)840: {
844: svd->trackall = trackall;
845: return(0);
846: }
848: /*@
849: SVDGetTrackAll - Returns the flag indicating whether all residual norms must
850: be computed or not.
852: Not Collective
854: Input Parameter:
855: . svd - the singular value solver context
857: Output Parameter:
858: . trackall - the returned flag
860: Level: developer
862: .seealso: SVDSetTrackAll()
863: @*/
864: PetscErrorCode SVDGetTrackAll(SVD svd,PetscBool *trackall)865: {
869: *trackall = svd->trackall;
870: return(0);
871: }
873: /*@C
874: SVDSetOptionsPrefix - Sets the prefix used for searching for all
875: SVD options in the database.
877: Logically Collective on svd
879: Input Parameters:
880: + svd - the singular value solver context
881: - prefix - the prefix string to prepend to all SVD option requests
883: Notes:
884: A hyphen (-) must NOT be given at the beginning of the prefix name.
885: The first character of all runtime options is AUTOMATICALLY the
886: hyphen.
888: For example, to distinguish between the runtime options for two
889: different SVD contexts, one could call
890: .vb
891: SVDSetOptionsPrefix(svd1,"svd1_")
892: SVDSetOptionsPrefix(svd2,"svd2_")
893: .ve
895: Level: advanced
897: .seealso: SVDAppendOptionsPrefix(), SVDGetOptionsPrefix()
898: @*/
899: PetscErrorCode SVDSetOptionsPrefix(SVD svd,const char *prefix)900: {
905: if (!svd->V) { SVDGetBV(svd,&svd->V,&svd->U); }
906: BVSetOptionsPrefix(svd->V,prefix);
907: BVSetOptionsPrefix(svd->U,prefix);
908: if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
909: DSSetOptionsPrefix(svd->ds,prefix);
910: PetscObjectSetOptionsPrefix((PetscObject)svd,prefix);
911: return(0);
912: }
914: /*@C
915: SVDAppendOptionsPrefix - Appends to the prefix used for searching for all
916: SVD options in the database.
918: Logically Collective on svd
920: Input Parameters:
921: + svd - the singular value solver context
922: - prefix - the prefix string to prepend to all SVD option requests
924: Notes:
925: A hyphen (-) must NOT be given at the beginning of the prefix name.
926: The first character of all runtime options is AUTOMATICALLY the hyphen.
928: Level: advanced
930: .seealso: SVDSetOptionsPrefix(), SVDGetOptionsPrefix()
931: @*/
932: PetscErrorCode SVDAppendOptionsPrefix(SVD svd,const char *prefix)933: {
938: if (!svd->V) { SVDGetBV(svd,&svd->V,&svd->U); }
939: BVAppendOptionsPrefix(svd->V,prefix);
940: BVAppendOptionsPrefix(svd->U,prefix);
941: if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
942: DSAppendOptionsPrefix(svd->ds,prefix);
943: PetscObjectAppendOptionsPrefix((PetscObject)svd,prefix);
944: return(0);
945: }
947: /*@C
948: SVDGetOptionsPrefix - Gets the prefix used for searching for all
949: SVD options in the database.
951: Not Collective
953: Input Parameters:
954: . svd - the singular value solver context
956: Output Parameters:
957: . prefix - pointer to the prefix string used is returned
959: Note:
960: On the Fortran side, the user should pass in a string 'prefix' of
961: sufficient length to hold the prefix.
963: Level: advanced
965: .seealso: SVDSetOptionsPrefix(), SVDAppendOptionsPrefix()
966: @*/
967: PetscErrorCode SVDGetOptionsPrefix(SVD svd,const char *prefix[])968: {
974: PetscObjectGetOptionsPrefix((PetscObject)svd,prefix);
975: return(0);
976: }