1: /*
2: SVD routines for setting solver options.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2014, 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*/
28: /*@
29: SVDSetImplicitTranspose - Indicates how to handle the transpose of the matrix
30: associated with the singular value problem.
32: Logically Collective on SVD 34: Input Parameters:
35: + svd - the singular value solver context
36: - impl - how to handle the transpose (implicitly or not)
38: Options Database Key:
39: . -svd_implicittranspose - Activate the implicit transpose mode.
41: Notes:
42: By default, the transpose of the matrix is explicitly built (if the matrix
43: has defined the MatTranspose operation).
45: If this flag is set to true, the solver does not build the transpose, but
46: handles it implicitly via MatMultTranspose() (or MatMultHermitianTranspose()
47: in the complex case) operations. This is likely to be more inefficient
48: than the default behaviour, both in sequential and in parallel, but
49: requires less storage.
51: Level: advanced
53: .seealso: SVDGetImplicitTranspose(), SVDSolve(), SVDSetOperator()
54: @*/
55: PetscErrorCode SVDSetImplicitTranspose(SVD svd,PetscBool impl) 56: {
60: if (svd->impltrans!=impl) {
61: svd->impltrans = impl;
62: svd->setupcalled = 0;
63: }
64: return(0);
65: }
69: /*@
70: SVDGetImplicitTranspose - Gets the mode used to handle the transpose
71: of the matrix associated with the singular value problem.
73: Not Collective
75: Input Parameter:
76: . svd - the singular value solver context
78: Output paramter:
79: . impl - how to handle the transpose (implicitly or not)
81: Level: advanced
83: .seealso: SVDSetImplicitTranspose(), SVDSolve(), SVDSetOperator()
84: @*/
85: PetscErrorCode SVDGetImplicitTranspose(SVD svd,PetscBool *impl) 86: {
90: *impl = svd->impltrans;
91: return(0);
92: }
96: /*@
97: SVDSetTolerances - Sets the tolerance and maximum
98: iteration count used by the default SVD convergence testers.
100: Logically Collective on SVD102: Input Parameters:
103: + svd - the singular value solver context
104: . tol - the convergence tolerance
105: - maxits - maximum number of iterations to use
107: Options Database Keys:
108: + -svd_tol <tol> - Sets the convergence tolerance
109: - -svd_max_it <maxits> - Sets the maximum number of iterations allowed
110: (use PETSC_DECIDE to compute an educated guess based on basis and matrix sizes)
112: Note:
113: Use PETSC_DEFAULT for either argument to assign a reasonably good value.
115: Level: intermediate
117: .seealso: SVDGetTolerances()
118: @*/
119: PetscErrorCode SVDSetTolerances(SVD svd,PetscReal tol,PetscInt maxits)120: {
125: if (tol == PETSC_DEFAULT) {
126: tol = PETSC_DEFAULT;
127: svd->setupcalled = 0;
128: } else {
129: if (tol <= 0.0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
130: svd->tol = tol;
131: }
132: if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
133: svd->max_it = 0;
134: svd->setupcalled = 0;
135: } else {
136: if (maxits <= 0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
137: svd->max_it = maxits;
138: }
139: return(0);
140: }
144: /*@
145: SVDGetTolerances - Gets the tolerance and maximum
146: iteration count used by the default SVD convergence tests.
148: Not Collective
150: Input Parameter:
151: . svd - the singular value solver context
153: Output Parameters:
154: + tol - the convergence tolerance
155: - maxits - maximum number of iterations
157: Notes:
158: The user can specify NULL for any parameter that is not needed.
160: Level: intermediate
162: .seealso: SVDSetTolerances()
163: @*/
164: PetscErrorCode SVDGetTolerances(SVD svd,PetscReal *tol,PetscInt *maxits)165: {
168: if (tol) *tol = svd->tol;
169: if (maxits) *maxits = svd->max_it;
170: return(0);
171: }
175: /*@
176: SVDSetDimensions - Sets the number of singular values to compute
177: and the dimension of the subspace.
179: Logically Collective on SVD181: Input Parameters:
182: + svd - the singular value solver context
183: . nsv - number of singular values to compute
184: . ncv - the maximum dimension of the subspace to be used by the solver
185: - mpd - the maximum dimension allowed for the projected problem
187: Options Database Keys:
188: + -svd_nsv <nsv> - Sets the number of singular values
189: . -svd_ncv <ncv> - Sets the dimension of the subspace
190: - -svd_mpd <mpd> - Sets the maximum projected dimension
192: Notes:
193: Use PETSC_DEFAULT for ncv and mpd to assign a reasonably good value, which is
194: dependent on the solution method and the number of singular values required.
196: The parameters ncv and mpd are intimately related, so that the user is advised
197: to set one of them at most. Normal usage is that
198: (a) in cases where nsv is small, the user sets ncv (a reasonable default is 2*nsv); and
199: (b) in cases where nsv is large, the user sets mpd.
201: The value of ncv should always be between nsv and (nsv+mpd), typically
202: ncv=nsv+mpd. If nev is not too large, mpd=nsv is a reasonable choice, otherwise
203: a smaller value should be used.
205: Level: intermediate
207: .seealso: SVDGetDimensions()
208: @*/
209: PetscErrorCode SVDSetDimensions(SVD svd,PetscInt nsv,PetscInt ncv,PetscInt mpd)210: {
216: if (nsv<1) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of nsv. Must be > 0");
217: svd->nsv = nsv;
218: if (ncv == PETSC_DEFAULT || ncv == PETSC_DECIDE) {
219: svd->ncv = 0;
220: } else {
221: if (ncv<1) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
222: svd->ncv = ncv;
223: }
224: if (mpd == PETSC_DECIDE || mpd == PETSC_DEFAULT) {
225: svd->mpd = 0;
226: } else {
227: if (mpd<1) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of mpd. Must be > 0");
228: svd->mpd = mpd;
229: }
230: svd->setupcalled = 0;
231: return(0);
232: }
236: /*@
237: SVDGetDimensions - Gets the number of singular values to compute
238: and the dimension of the subspace.
240: Not Collective
242: Input Parameter:
243: . svd - the singular value context
245: Output Parameters:
246: + nsv - number of singular values to compute
247: . ncv - the maximum dimension of the subspace to be used by the solver
248: - mpd - the maximum dimension allowed for the projected problem
250: Notes:
251: The user can specify NULL for any parameter that is not needed.
253: Level: intermediate
255: .seealso: SVDSetDimensions()
256: @*/
257: PetscErrorCode SVDGetDimensions(SVD svd,PetscInt *nsv,PetscInt *ncv,PetscInt *mpd)258: {
261: if (nsv) *nsv = svd->nsv;
262: if (ncv) *ncv = svd->ncv;
263: if (mpd) *mpd = svd->mpd;
264: return(0);
265: }
269: /*@
270: SVDSetWhichSingularTriplets - Specifies which singular triplets are
271: to be sought.
273: Logically Collective on SVD275: Input Parameter:
276: . svd - singular value solver context obtained from SVDCreate()
278: Output Parameter:
279: . which - which singular triplets are to be sought
281: Possible values:
282: The parameter 'which' can have one of these values:
284: + SVD_LARGEST - largest singular values
285: - SVD_SMALLEST - smallest singular values
287: Options Database Keys:
288: + -svd_largest - Sets largest singular values
289: - -svd_smallest - Sets smallest singular values
291: Level: intermediate
293: .seealso: SVDGetWhichSingularTriplets(), SVDWhich294: @*/
295: PetscErrorCode SVDSetWhichSingularTriplets(SVD svd,SVDWhich which)296: {
300: switch (which) {
301: case SVD_LARGEST:
302: case SVD_SMALLEST:
303: if (svd->which != which) {
304: svd->setupcalled = 0;
305: svd->which = which;
306: }
307: break;
308: default:309: SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'which' parameter");
310: }
311: return(0);
312: }
316: /*@C
317: SVDGetWhichSingularTriplets - Returns which singular triplets are
318: to be sought.
320: Not Collective
322: Input Parameter:
323: . svd - singular value solver context obtained from SVDCreate()
325: Output Parameter:
326: . which - which singular triplets are to be sought
328: Notes:
329: See SVDSetWhichSingularTriplets() for possible values of which
331: Level: intermediate
333: .seealso: SVDSetWhichSingularTriplets(), SVDWhich334: @*/
335: PetscErrorCode SVDGetWhichSingularTriplets(SVD svd,SVDWhich *which)336: {
340: *which = svd->which;
341: return(0);
342: }
346: /*@
347: SVDSetFromOptions - Sets SVD options from the options database.
348: This routine must be called before SVDSetUp() if the user is to be
349: allowed to set the solver type.
351: Collective on SVD353: Input Parameters:
354: . svd - the singular value solver context
356: Notes:
357: To see all options, run your program with the -help option.
359: Level: beginner
361: .seealso:
362: @*/
363: PetscErrorCode SVDSetFromOptions(SVD svd)364: {
365: PetscErrorCode ierr;
366: char type[256],monfilename[PETSC_MAX_PATH_LEN];
367: PetscBool flg,val,flg1,flg2,flg3;
368: PetscInt i,j,k;
369: PetscReal r;
370: PetscViewer monviewer;
371: SlepcConvMonitor ctx;
375: svd->setupcalled = 0;
376: if (!SVDRegisterAllCalled) { SVDRegisterAll(); }
377: PetscObjectOptionsBegin((PetscObject)svd);
378: PetscOptionsFList("-svd_type","Singular Value Solver method","SVDSetType",SVDList,(char*)(((PetscObject)svd)->type_name?((PetscObject)svd)->type_name:SVDCROSS),type,256,&flg);
379: if (flg) {
380: SVDSetType(svd,type);
381: } else if (!((PetscObject)svd)->type_name) {
382: SVDSetType(svd,SVDCROSS);
383: }
385: PetscOptionsName("-svd_view","Print detailed information on solver used","SVDView",&flg);
387: PetscOptionsBool("-svd_implicittranspose","Handle matrix transpose implicitly","SVDSetImplicitTranspose",svd->impltrans,&val,&flg);
388: if (flg) {
389: SVDSetImplicitTranspose(svd,val);
390: }
392: i = svd->max_it? svd->max_it: PETSC_DEFAULT;
393: PetscOptionsInt("-svd_max_it","Maximum number of iterations","SVDSetTolerances",svd->max_it,&i,&flg1);
394: r = svd->tol;
395: PetscOptionsReal("-svd_tol","Tolerance","SVDSetTolerances",svd->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:svd->tol,&r,&flg2);
396: if (flg1 || flg2) {
397: SVDSetTolerances(svd,r,i);
398: }
400: i = svd->nsv;
401: PetscOptionsInt("-svd_nsv","Number of singular values to compute","SVDSetDimensions",svd->nsv,&i,&flg1);
402: j = svd->ncv? svd->ncv: PETSC_DEFAULT;
403: PetscOptionsInt("-svd_ncv","Number of basis vectors","SVDSetDimensions",svd->ncv,&j,&flg2);
404: k = svd->mpd? svd->mpd: PETSC_DEFAULT;
405: PetscOptionsInt("-svd_mpd","Maximum dimension of projected problem","SVDSetDimensions",svd->mpd,&k,&flg3);
406: if (flg1 || flg2 || flg3) {
407: SVDSetDimensions(svd,i,j,k);
408: }
410: PetscOptionsBoolGroupBegin("-svd_largest","compute largest singular values","SVDSetWhichSingularTriplets",&flg);
411: if (flg) { SVDSetWhichSingularTriplets(svd,SVD_LARGEST); }
412: PetscOptionsBoolGroupEnd("-svd_smallest","compute smallest singular values","SVDSetWhichSingularTriplets",&flg);
413: if (flg) { SVDSetWhichSingularTriplets(svd,SVD_SMALLEST); }
415: flg = PETSC_FALSE;
416: PetscOptionsBool("-svd_monitor_cancel","Remove any hardwired monitor routines","SVDMonitorCancel",flg,&flg,NULL);
417: if (flg) {
418: SVDMonitorCancel(svd);
419: }
421: PetscOptionsString("-svd_monitor_all","Monitor approximate singular values and error estimates","SVDMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
422: if (flg) {
423: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)svd),monfilename,&monviewer);
424: SVDMonitorSet(svd,SVDMonitorAll,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
425: SVDSetTrackAll(svd,PETSC_TRUE);
426: }
427: PetscOptionsString("-svd_monitor_conv","Monitor approximate singular values and error estimates as they converge","SVDMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
428: if (flg) {
429: PetscNew(&ctx);
430: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)svd),monfilename,&ctx->viewer);
431: SVDMonitorSet(svd,SVDMonitorConverged,ctx,(PetscErrorCode (*)(void**))SlepcConvMonitorDestroy);
432: }
433: PetscOptionsString("-svd_monitor","Monitor first unconverged approximate singular value and error estimate","SVDMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
434: if (flg) {
435: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)svd),monfilename,&monviewer);
436: SVDMonitorSet(svd,SVDMonitorFirst,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
437: }
438: flg = PETSC_FALSE;
439: PetscOptionsBool("-svd_monitor_lg","Monitor first unconverged approximate singular value and error estimate graphically","SVDMonitorSet",flg,&flg,NULL);
440: if (flg) {
441: SVDMonitorSet(svd,SVDMonitorLG,NULL,NULL);
442: }
443: flg = PETSC_FALSE;
444: PetscOptionsBool("-svd_monitor_lg_all","Monitor error estimates graphically","SVDMonitorSet",flg,&flg,NULL);
445: if (flg) {
446: SVDMonitorSet(svd,SVDMonitorLGAll,NULL,NULL);
447: SVDSetTrackAll(svd,PETSC_TRUE);
448: }
450: if (svd->ops->setfromoptions) {
451: (*svd->ops->setfromoptions)(svd);
452: }
453: PetscObjectProcessOptionsHandlers((PetscObject)svd);
454: PetscOptionsEnd();
456: if (!svd->V) { SVDGetBV(svd,&svd->V,&svd->U); }
457: BVSetFromOptions(svd->V);
458: BVSetFromOptions(svd->U);
459: if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
460: DSSetFromOptions(svd->ds);
461: PetscRandomSetFromOptions(svd->rand);
462: return(0);
463: }
467: /*@
468: SVDSetTrackAll - Specifies if the solver must compute the residual norm of all
469: approximate singular value or not.
471: Logically Collective on SVD473: Input Parameters:
474: + svd - the singular value solver context
475: - trackall - whether to compute all residuals or not
477: Notes:
478: If the user sets trackall=PETSC_TRUE then the solver computes (or estimates)
479: the residual norm for each singular value approximation. Computing the residual is
480: usually an expensive operation and solvers commonly compute only the residual
481: associated to the first unconverged singular value.
483: The options '-svd_monitor_all' and '-svd_monitor_lg_all' automatically
484: activate this option.
486: Level: intermediate
488: .seealso: SVDGetTrackAll()
489: @*/
490: PetscErrorCode SVDSetTrackAll(SVD svd,PetscBool trackall)491: {
495: svd->trackall = trackall;
496: return(0);
497: }
501: /*@
502: SVDGetTrackAll - Returns the flag indicating whether all residual norms must
503: be computed or not.
505: Not Collective
507: Input Parameter:
508: . svd - the singular value solver context
510: Output Parameter:
511: . trackall - the returned flag
513: Level: intermediate
515: .seealso: SVDSetTrackAll()
516: @*/
517: PetscErrorCode SVDGetTrackAll(SVD svd,PetscBool *trackall)518: {
522: *trackall = svd->trackall;
523: return(0);
524: }
529: /*@C
530: SVDSetOptionsPrefix - Sets the prefix used for searching for all
531: SVD options in the database.
533: Logically Collective on SVD535: Input Parameters:
536: + svd - the singular value solver context
537: - prefix - the prefix string to prepend to all SVD option requests
539: Notes:
540: A hyphen (-) must NOT be given at the beginning of the prefix name.
541: The first character of all runtime options is AUTOMATICALLY the
542: hyphen.
544: For example, to distinguish between the runtime options for two
545: different SVD contexts, one could call
546: .vb
547: SVDSetOptionsPrefix(svd1,"svd1_")
548: SVDSetOptionsPrefix(svd2,"svd2_")
549: .ve
551: Level: advanced
553: .seealso: SVDAppendOptionsPrefix(), SVDGetOptionsPrefix()
554: @*/
555: PetscErrorCode SVDSetOptionsPrefix(SVD svd,const char *prefix)556: {
558: PetscBool flg1,flg2;
559: EPS eps;
563: if (!svd->V) { SVDGetBV(svd,&svd->V,&svd->U); }
564: BVSetOptionsPrefix(svd->V,prefix);
565: BVSetOptionsPrefix(svd->U,prefix);
566: if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
567: DSSetOptionsPrefix(svd->ds,prefix);
568: PetscObjectSetOptionsPrefix((PetscObject)svd,prefix);
569: PetscObjectTypeCompare((PetscObject)svd,SVDCROSS,&flg1);
570: PetscObjectTypeCompare((PetscObject)svd,SVDCYCLIC,&flg2);
571: if (flg1) {
572: SVDCrossGetEPS(svd,&eps);
573: } else if (flg2) {
574: SVDCyclicGetEPS(svd,&eps);
575: }
576: if (flg1 || flg2) {
577: EPSSetOptionsPrefix(eps,prefix);
578: EPSAppendOptionsPrefix(eps,"svd_");
579: }
580: return(0);
581: }
585: /*@C
586: SVDAppendOptionsPrefix - Appends to the prefix used for searching for all
587: SVD options in the database.
589: Logically Collective on SVD591: Input Parameters:
592: + svd - the singular value solver context
593: - prefix - the prefix string to prepend to all SVD option requests
595: Notes:
596: A hyphen (-) must NOT be given at the beginning of the prefix name.
597: The first character of all runtime options is AUTOMATICALLY the hyphen.
599: Level: advanced
601: .seealso: SVDSetOptionsPrefix(), SVDGetOptionsPrefix()
602: @*/
603: PetscErrorCode SVDAppendOptionsPrefix(SVD svd,const char *prefix)604: {
606: PetscBool flg1,flg2;
607: EPS eps;
611: if (!svd->V) { SVDGetBV(svd,&svd->V,&svd->U); }
612: BVSetOptionsPrefix(svd->V,prefix);
613: BVSetOptionsPrefix(svd->U,prefix);
614: if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
615: DSSetOptionsPrefix(svd->ds,prefix);
616: PetscObjectAppendOptionsPrefix((PetscObject)svd,prefix);
617: PetscObjectTypeCompare((PetscObject)svd,SVDCROSS,&flg1);
618: PetscObjectTypeCompare((PetscObject)svd,SVDCYCLIC,&flg2);
619: if (flg1) {
620: SVDCrossGetEPS(svd,&eps);
621: } else if (flg2) {
622: SVDCyclicGetEPS(svd,&eps);
623: }
624: if (flg1 || flg2) {
625: EPSSetOptionsPrefix(eps,((PetscObject)svd)->prefix);
626: EPSAppendOptionsPrefix(eps,"svd_");
627: }
628: return(0);
629: }
633: /*@C
634: SVDGetOptionsPrefix - Gets the prefix used for searching for all
635: SVD options in the database.
637: Not Collective
639: Input Parameters:
640: . svd - the singular value solver context
642: Output Parameters:
643: . prefix - pointer to the prefix string used is returned
645: Notes: On the fortran side, the user should pass in a string 'prefix' of
646: sufficient length to hold the prefix.
648: Level: advanced
650: .seealso: SVDSetOptionsPrefix(), SVDAppendOptionsPrefix()
651: @*/
652: PetscErrorCode SVDGetOptionsPrefix(SVD svd,const char *prefix[])653: {
659: PetscObjectGetOptionsPrefix((PetscObject)svd,prefix);
660: return(0);
661: }