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 : SVD routines for setting solver options
12 : */
13 :
14 : #include <slepc/private/svdimpl.h> /*I "slepcsvd.h" I*/
15 : #include <petscdraw.h>
16 :
17 : /*@
18 : SVDSetImplicitTranspose - Indicates how to handle the transpose of the matrix
19 : associated with the singular value problem.
20 :
21 : Logically Collective
22 :
23 : Input Parameters:
24 : + svd - the singular value solver context
25 : - impl - how to handle the transpose (implicitly or not)
26 :
27 : Options Database Key:
28 : . -svd_implicittranspose - Activate the implicit transpose mode.
29 :
30 : Notes:
31 : By default, the transpose of the matrix is explicitly built (if the matrix
32 : has defined the MatTranspose operation).
33 :
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.
39 :
40 : Level: advanced
41 :
42 : .seealso: SVDGetImplicitTranspose(), SVDSolve(), SVDSetOperators()
43 : @*/
44 25 : PetscErrorCode SVDSetImplicitTranspose(SVD svd,PetscBool impl)
45 : {
46 25 : PetscFunctionBegin;
47 25 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
48 100 : PetscValidLogicalCollectiveBool(svd,impl,2);
49 25 : if (svd->impltrans!=impl) {
50 19 : svd->impltrans = impl;
51 19 : svd->state = SVD_STATE_INITIAL;
52 : }
53 25 : PetscFunctionReturn(PETSC_SUCCESS);
54 : }
55 :
56 : /*@
57 : SVDGetImplicitTranspose - Gets the mode used to handle the transpose
58 : of the matrix associated with the singular value problem.
59 :
60 : Not Collective
61 :
62 : Input Parameter:
63 : . svd - the singular value solver context
64 :
65 : Output Parameter:
66 : . impl - how to handle the transpose (implicitly or not)
67 :
68 : Level: advanced
69 :
70 : .seealso: SVDSetImplicitTranspose(), SVDSolve(), SVDSetOperators()
71 : @*/
72 12 : PetscErrorCode SVDGetImplicitTranspose(SVD svd,PetscBool *impl)
73 : {
74 12 : PetscFunctionBegin;
75 12 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
76 12 : PetscAssertPointer(impl,2);
77 12 : *impl = svd->impltrans;
78 12 : PetscFunctionReturn(PETSC_SUCCESS);
79 : }
80 :
81 : /*@
82 : SVDSetTolerances - Sets the tolerance and maximum
83 : iteration count used by the default SVD convergence testers.
84 :
85 : Logically Collective
86 :
87 : Input Parameters:
88 : + svd - the singular value solver context
89 : . tol - the convergence tolerance
90 : - maxits - maximum number of iterations to use
91 :
92 : Options Database Keys:
93 : + -svd_tol <tol> - Sets the convergence tolerance
94 : - -svd_max_it <maxits> - Sets the maximum number of iterations allowed
95 :
96 : Note:
97 : Use PETSC_DEFAULT for either argument to assign a reasonably good value.
98 :
99 : Level: intermediate
100 :
101 : .seealso: SVDGetTolerances()
102 : @*/
103 61 : PetscErrorCode SVDSetTolerances(SVD svd,PetscReal tol,PetscInt maxits)
104 : {
105 61 : PetscFunctionBegin;
106 61 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
107 244 : PetscValidLogicalCollectiveReal(svd,tol,2);
108 244 : PetscValidLogicalCollectiveInt(svd,maxits,3);
109 61 : if (tol == (PetscReal)PETSC_DEFAULT) {
110 21 : svd->tol = PETSC_DEFAULT;
111 21 : svd->state = SVD_STATE_INITIAL;
112 : } else {
113 40 : PetscCheck(tol>0.0,PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
114 40 : svd->tol = tol;
115 : }
116 61 : if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
117 19 : svd->max_it = PETSC_DEFAULT;
118 19 : svd->state = SVD_STATE_INITIAL;
119 : } else {
120 42 : PetscCheck(maxits>0,PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
121 42 : svd->max_it = maxits;
122 : }
123 61 : PetscFunctionReturn(PETSC_SUCCESS);
124 : }
125 :
126 : /*@C
127 : SVDGetTolerances - Gets the tolerance and maximum
128 : iteration count used by the default SVD convergence tests.
129 :
130 : Not Collective
131 :
132 : Input Parameter:
133 : . svd - the singular value solver context
134 :
135 : Output Parameters:
136 : + tol - the convergence tolerance
137 : - maxits - maximum number of iterations
138 :
139 : Notes:
140 : The user can specify NULL for any parameter that is not needed.
141 :
142 : Level: intermediate
143 :
144 : .seealso: SVDSetTolerances()
145 : @*/
146 85 : PetscErrorCode SVDGetTolerances(SVD svd,PetscReal *tol,PetscInt *maxits)
147 : {
148 85 : PetscFunctionBegin;
149 85 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
150 85 : if (tol) *tol = svd->tol;
151 85 : if (maxits) *maxits = svd->max_it;
152 85 : PetscFunctionReturn(PETSC_SUCCESS);
153 : }
154 :
155 : /*@
156 : SVDSetDimensions - Sets the number of singular values to compute
157 : and the dimension of the subspace.
158 :
159 : Logically Collective
160 :
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
166 :
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
171 :
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.
175 :
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.
180 :
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.
184 :
185 : Level: intermediate
186 :
187 : .seealso: SVDGetDimensions()
188 : @*/
189 211 : PetscErrorCode SVDSetDimensions(SVD svd,PetscInt nsv,PetscInt ncv,PetscInt mpd)
190 : {
191 211 : PetscFunctionBegin;
192 211 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
193 844 : PetscValidLogicalCollectiveInt(svd,nsv,2);
194 844 : PetscValidLogicalCollectiveInt(svd,ncv,3);
195 844 : PetscValidLogicalCollectiveInt(svd,mpd,4);
196 211 : PetscCheck(nsv>0,PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of nsv. Must be > 0");
197 211 : svd->nsv = nsv;
198 211 : if (ncv == PETSC_DEFAULT || ncv == PETSC_DECIDE) {
199 136 : svd->ncv = PETSC_DEFAULT;
200 : } else {
201 75 : PetscCheck(ncv>0,PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
202 75 : svd->ncv = ncv;
203 : }
204 211 : if (mpd == PETSC_DECIDE || mpd == PETSC_DEFAULT) {
205 209 : svd->mpd = PETSC_DEFAULT;
206 : } else {
207 2 : PetscCheck(mpd>0,PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of mpd. Must be > 0");
208 2 : svd->mpd = mpd;
209 : }
210 211 : svd->state = SVD_STATE_INITIAL;
211 211 : PetscFunctionReturn(PETSC_SUCCESS);
212 : }
213 :
214 : /*@C
215 : SVDGetDimensions - Gets the number of singular values to compute
216 : and the dimension of the subspace.
217 :
218 : Not Collective
219 :
220 : Input Parameter:
221 : . svd - the singular value context
222 :
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
227 :
228 : Notes:
229 : The user can specify NULL for any parameter that is not needed.
230 :
231 : Level: intermediate
232 :
233 : .seealso: SVDSetDimensions()
234 : @*/
235 91 : PetscErrorCode SVDGetDimensions(SVD svd,PetscInt *nsv,PetscInt *ncv,PetscInt *mpd)
236 : {
237 91 : PetscFunctionBegin;
238 91 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
239 91 : if (nsv) *nsv = svd->nsv;
240 91 : if (ncv) *ncv = svd->ncv;
241 91 : if (mpd) *mpd = svd->mpd;
242 91 : PetscFunctionReturn(PETSC_SUCCESS);
243 : }
244 :
245 : /*@
246 : SVDSetWhichSingularTriplets - Specifies which singular triplets are
247 : to be sought.
248 :
249 : Logically Collective
250 :
251 : Input Parameter:
252 : . svd - singular value solver context obtained from SVDCreate()
253 :
254 : Output Parameter:
255 : . which - which singular triplets are to be sought
256 :
257 : Options Database Keys:
258 : + -svd_largest - Sets largest singular values
259 : - -svd_smallest - Sets smallest singular values
260 :
261 : Notes:
262 : The parameter 'which' can have one of these values
263 :
264 : + SVD_LARGEST - largest singular values
265 : - SVD_SMALLEST - smallest singular values
266 :
267 : Level: intermediate
268 :
269 : .seealso: SVDGetWhichSingularTriplets(), SVDWhich
270 : @*/
271 55 : PetscErrorCode SVDSetWhichSingularTriplets(SVD svd,SVDWhich which)
272 : {
273 55 : PetscFunctionBegin;
274 55 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
275 220 : PetscValidLogicalCollectiveEnum(svd,which,2);
276 55 : switch (which) {
277 55 : case SVD_LARGEST:
278 : case SVD_SMALLEST:
279 55 : if (svd->which != which) {
280 39 : svd->state = SVD_STATE_INITIAL;
281 39 : svd->which = which;
282 : }
283 55 : break;
284 0 : default:
285 0 : SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'which' parameter");
286 : }
287 55 : PetscFunctionReturn(PETSC_SUCCESS);
288 : }
289 :
290 : /*@
291 : SVDGetWhichSingularTriplets - Returns which singular triplets are
292 : to be sought.
293 :
294 : Not Collective
295 :
296 : Input Parameter:
297 : . svd - singular value solver context obtained from SVDCreate()
298 :
299 : Output Parameter:
300 : . which - which singular triplets are to be sought
301 :
302 : Notes:
303 : See SVDSetWhichSingularTriplets() for possible values of which
304 :
305 : Level: intermediate
306 :
307 : .seealso: SVDSetWhichSingularTriplets(), SVDWhich
308 : @*/
309 12 : PetscErrorCode SVDGetWhichSingularTriplets(SVD svd,SVDWhich *which)
310 : {
311 12 : PetscFunctionBegin;
312 12 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
313 12 : PetscAssertPointer(which,2);
314 12 : *which = svd->which;
315 12 : PetscFunctionReturn(PETSC_SUCCESS);
316 : }
317 :
318 : /*@C
319 : SVDSetConvergenceTestFunction - Sets a function to compute the error estimate
320 : used in the convergence test.
321 :
322 : Logically Collective
323 :
324 : Input Parameters:
325 : + svd - singular value solver context obtained from SVDCreate()
326 : . conv - 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)
329 :
330 : Calling sequence of conv:
331 : $ PetscErrorCode conv(SVD svd,PetscReal sigma,PetscReal res,PetscReal *errest,void *ctx)
332 : + svd - singular value solver context obtained from SVDCreate()
333 : . sigma - computed singular value
334 : . res - residual norm associated to the singular triplet
335 : . errest - (output) computed error estimate
336 : - ctx - optional context, as set by SVDSetConvergenceTestFunction()
337 :
338 : Note:
339 : If the error estimate returned by the convergence test function is less than
340 : the tolerance, then the singular value is accepted as converged.
341 :
342 : Level: advanced
343 :
344 : .seealso: SVDSetConvergenceTest(), SVDSetTolerances()
345 : @*/
346 1 : PetscErrorCode SVDSetConvergenceTestFunction(SVD svd,PetscErrorCode (*conv)(SVD svd,PetscReal sigma,PetscReal res,PetscReal *errest,void *ctx),void* ctx,PetscErrorCode (*destroy)(void*))
347 : {
348 1 : PetscFunctionBegin;
349 1 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
350 1 : if (svd->convergeddestroy) PetscCall((*svd->convergeddestroy)(svd->convergedctx));
351 1 : svd->convergeduser = conv;
352 1 : svd->convergeddestroy = destroy;
353 1 : svd->convergedctx = ctx;
354 1 : if (conv == SVDConvergedAbsolute) svd->conv = SVD_CONV_ABS;
355 1 : else if (conv == SVDConvergedRelative) svd->conv = SVD_CONV_REL;
356 1 : else if (conv == SVDConvergedNorm) svd->conv = SVD_CONV_NORM;
357 1 : else if (conv == SVDConvergedMaxIt) svd->conv = SVD_CONV_MAXIT;
358 : else {
359 1 : svd->conv = SVD_CONV_USER;
360 1 : svd->converged = svd->convergeduser;
361 : }
362 1 : PetscFunctionReturn(PETSC_SUCCESS);
363 : }
364 :
365 : /*@
366 : SVDSetConvergenceTest - Specifies how to compute the error estimate
367 : used in the convergence test.
368 :
369 : Logically Collective
370 :
371 : Input Parameters:
372 : + svd - singular value solver context obtained from SVDCreate()
373 : - conv - the type of convergence test
374 :
375 : Options Database Keys:
376 : + -svd_conv_abs - Sets the absolute convergence test
377 : . -svd_conv_rel - Sets the convergence test relative to the singular value
378 : . -svd_conv_norm - Sets the convergence test relative to the matrix norm
379 : . -svd_conv_maxit - Forces the maximum number of iterations as set by -svd_max_it
380 : - -svd_conv_user - Selects the user-defined convergence test
381 :
382 : Notes:
383 : The parameter 'conv' can have one of these values
384 : + SVD_CONV_ABS - absolute error ||r||
385 : . SVD_CONV_REL - error relative to the singular value sigma, ||r||/sigma
386 : . SVD_CONV_NORM - error relative to the matrix norms, ||r||/||Z||, with Z=A or Z=[A;B]
387 : . SVD_CONV_MAXIT - no convergence until maximum number of iterations has been reached
388 : - SVD_CONV_USER - function set by SVDSetConvergenceTestFunction()
389 :
390 : The default in standard SVD is SVD_CONV_REL, while in GSVD the default is SVD_CONV_NORM.
391 :
392 : Level: intermediate
393 :
394 : .seealso: SVDGetConvergenceTest(), SVDSetConvergenceTestFunction(), SVDSetStoppingTest(), SVDConv
395 : @*/
396 227 : PetscErrorCode SVDSetConvergenceTest(SVD svd,SVDConv conv)
397 : {
398 227 : PetscFunctionBegin;
399 227 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
400 908 : PetscValidLogicalCollectiveEnum(svd,conv,2);
401 227 : switch (conv) {
402 12 : case SVD_CONV_ABS: svd->converged = SVDConvergedAbsolute; break;
403 125 : case SVD_CONV_REL: svd->converged = SVDConvergedRelative; break;
404 88 : case SVD_CONV_NORM: svd->converged = SVDConvergedNorm; break;
405 2 : case SVD_CONV_MAXIT: svd->converged = SVDConvergedMaxIt; break;
406 0 : case SVD_CONV_USER:
407 0 : PetscCheck(svd->convergeduser,PetscObjectComm((PetscObject)svd),PETSC_ERR_ORDER,"Must call SVDSetConvergenceTestFunction() first");
408 0 : svd->converged = svd->convergeduser;
409 0 : break;
410 0 : default:
411 0 : SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'conv' value");
412 : }
413 227 : svd->conv = conv;
414 227 : PetscFunctionReturn(PETSC_SUCCESS);
415 : }
416 :
417 : /*@
418 : SVDGetConvergenceTest - Gets the method used to compute the error estimate
419 : used in the convergence test.
420 :
421 : Not Collective
422 :
423 : Input Parameters:
424 : . svd - singular value solver context obtained from SVDCreate()
425 :
426 : Output Parameters:
427 : . conv - the type of convergence test
428 :
429 : Level: intermediate
430 :
431 : .seealso: SVDSetConvergenceTest(), SVDConv
432 : @*/
433 12 : PetscErrorCode SVDGetConvergenceTest(SVD svd,SVDConv *conv)
434 : {
435 12 : PetscFunctionBegin;
436 12 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
437 12 : PetscAssertPointer(conv,2);
438 12 : *conv = svd->conv;
439 12 : PetscFunctionReturn(PETSC_SUCCESS);
440 : }
441 :
442 : /*@C
443 : SVDSetStoppingTestFunction - Sets a function to decide when to stop the outer
444 : iteration of the singular value solver.
445 :
446 : Logically Collective
447 :
448 : Input Parameters:
449 : + svd - singular value solver context obtained from SVDCreate()
450 : . stop - pointer to the stopping test function
451 : . ctx - context for private data for the stopping routine (may be null)
452 : - destroy - a routine for destroying the context (may be null)
453 :
454 : Calling sequence of stop:
455 : $ PetscErrorCode stop(SVD svd,PetscInt its,PetscInt max_it,PetscInt nconv,PetscInt nsv,SVDConvergedReason *reason,void *ctx)
456 : + svd - singular value solver context obtained from SVDCreate()
457 : . its - current number of iterations
458 : . max_it - maximum number of iterations
459 : . nconv - number of currently converged singular triplets
460 : . nsv - number of requested singular triplets
461 : . reason - (output) result of the stopping test
462 : - ctx - optional context, as set by SVDSetStoppingTestFunction()
463 :
464 : Note:
465 : Normal usage is to first call the default routine SVDStoppingBasic() and then
466 : set reason to SVD_CONVERGED_USER if some user-defined conditions have been
467 : met. To let the singular value solver continue iterating, the result must be
468 : left as SVD_CONVERGED_ITERATING.
469 :
470 : Level: advanced
471 :
472 : .seealso: SVDSetStoppingTest(), SVDStoppingBasic()
473 : @*/
474 1 : PetscErrorCode SVDSetStoppingTestFunction(SVD svd,PetscErrorCode (*stop)(SVD svd,PetscInt its,PetscInt max_it,PetscInt nconv,PetscInt nsv,SVDConvergedReason *reason,void *ctx),void* ctx,PetscErrorCode (*destroy)(void*))
475 : {
476 1 : PetscFunctionBegin;
477 1 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
478 1 : if (svd->stoppingdestroy) PetscCall((*svd->stoppingdestroy)(svd->stoppingctx));
479 1 : svd->stoppinguser = stop;
480 1 : svd->stoppingdestroy = destroy;
481 1 : svd->stoppingctx = ctx;
482 1 : if (stop == SVDStoppingBasic) svd->stop = SVD_STOP_BASIC;
483 : else {
484 1 : svd->stop = SVD_STOP_USER;
485 1 : svd->stopping = svd->stoppinguser;
486 : }
487 1 : PetscFunctionReturn(PETSC_SUCCESS);
488 : }
489 :
490 : /*@
491 : SVDSetStoppingTest - Specifies how to decide the termination of the outer
492 : loop of the singular value solver.
493 :
494 : Logically Collective
495 :
496 : Input Parameters:
497 : + svd - singular value solver context obtained from SVDCreate()
498 : - stop - the type of stopping test
499 :
500 : Options Database Keys:
501 : + -svd_stop_basic - Sets the default stopping test
502 : - -svd_stop_user - Selects the user-defined stopping test
503 :
504 : Note:
505 : The parameter 'stop' can have one of these values
506 : + SVD_STOP_BASIC - default stopping test
507 : - SVD_STOP_USER - function set by SVDSetStoppingTestFunction()
508 :
509 : Level: advanced
510 :
511 : .seealso: SVDGetStoppingTest(), SVDSetStoppingTestFunction(), SVDSetConvergenceTest(), SVDStop
512 : @*/
513 12 : PetscErrorCode SVDSetStoppingTest(SVD svd,SVDStop stop)
514 : {
515 12 : PetscFunctionBegin;
516 12 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
517 48 : PetscValidLogicalCollectiveEnum(svd,stop,2);
518 12 : switch (stop) {
519 12 : case SVD_STOP_BASIC: svd->stopping = SVDStoppingBasic; break;
520 0 : case SVD_STOP_USER:
521 0 : PetscCheck(svd->stoppinguser,PetscObjectComm((PetscObject)svd),PETSC_ERR_ORDER,"Must call SVDSetStoppingTestFunction() first");
522 0 : svd->stopping = svd->stoppinguser;
523 0 : break;
524 0 : default:
525 0 : SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'stop' value");
526 : }
527 12 : svd->stop = stop;
528 12 : PetscFunctionReturn(PETSC_SUCCESS);
529 : }
530 :
531 : /*@
532 : SVDGetStoppingTest - Gets the method used to decide the termination of the outer
533 : loop of the singular value solver.
534 :
535 : Not Collective
536 :
537 : Input Parameters:
538 : . svd - singular value solver context obtained from SVDCreate()
539 :
540 : Output Parameters:
541 : . stop - the type of stopping test
542 :
543 : Level: advanced
544 :
545 : .seealso: SVDSetStoppingTest(), SVDStop
546 : @*/
547 12 : PetscErrorCode SVDGetStoppingTest(SVD svd,SVDStop *stop)
548 : {
549 12 : PetscFunctionBegin;
550 12 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
551 12 : PetscAssertPointer(stop,2);
552 12 : *stop = svd->stop;
553 12 : PetscFunctionReturn(PETSC_SUCCESS);
554 : }
555 :
556 : /*@C
557 : SVDMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
558 : indicated by the user.
559 :
560 : Collective
561 :
562 : Input Parameters:
563 : + svd - the singular value solver context
564 : . opt - the command line option for this monitor
565 : . name - the monitor type one is seeking
566 : . ctx - an optional user context for the monitor, or NULL
567 : - trackall - whether this monitor tracks all singular values or not
568 :
569 : Level: developer
570 :
571 : .seealso: SVDMonitorSet(), SVDSetTrackAll()
572 : @*/
573 876 : PetscErrorCode SVDMonitorSetFromOptions(SVD svd,const char opt[],const char name[],void *ctx,PetscBool trackall)
574 : {
575 876 : PetscErrorCode (*mfunc)(SVD,PetscInt,PetscInt,PetscReal*,PetscReal*,PetscInt,void*);
576 876 : PetscErrorCode (*cfunc)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);
577 876 : PetscErrorCode (*dfunc)(PetscViewerAndFormat**);
578 876 : PetscViewerAndFormat *vf;
579 876 : PetscViewer viewer;
580 876 : PetscViewerFormat format;
581 876 : PetscViewerType vtype;
582 876 : char key[PETSC_MAX_PATH_LEN];
583 876 : PetscBool flg;
584 :
585 876 : PetscFunctionBegin;
586 876 : PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,opt,&viewer,&format,&flg));
587 876 : if (!flg) PetscFunctionReturn(PETSC_SUCCESS);
588 :
589 6 : PetscCall(PetscViewerGetType(viewer,&vtype));
590 6 : PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
591 6 : PetscCall(PetscFunctionListFind(SVDMonitorList,key,&mfunc));
592 6 : PetscCheck(mfunc,PetscObjectComm((PetscObject)svd),PETSC_ERR_SUP,"Specified viewer and format not supported");
593 6 : PetscCall(PetscFunctionListFind(SVDMonitorCreateList,key,&cfunc));
594 6 : PetscCall(PetscFunctionListFind(SVDMonitorDestroyList,key,&dfunc));
595 6 : if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
596 6 : if (!dfunc) dfunc = PetscViewerAndFormatDestroy;
597 :
598 6 : PetscCall((*cfunc)(viewer,format,ctx,&vf));
599 6 : PetscCall(PetscOptionsRestoreViewer(&viewer));
600 6 : PetscCall(SVDMonitorSet(svd,mfunc,vf,(PetscErrorCode(*)(void **))dfunc));
601 6 : if (trackall) PetscCall(SVDSetTrackAll(svd,PETSC_TRUE));
602 6 : PetscFunctionReturn(PETSC_SUCCESS);
603 : }
604 :
605 : /*@
606 : SVDSetFromOptions - Sets SVD options from the options database.
607 : This routine must be called before SVDSetUp() if the user is to be
608 : allowed to set the solver type.
609 :
610 : Collective
611 :
612 : Input Parameters:
613 : . svd - the singular value solver context
614 :
615 : Notes:
616 : To see all options, run your program with the -help option.
617 :
618 : Level: beginner
619 :
620 : .seealso: SVDSetOptionsPrefix()
621 : @*/
622 219 : PetscErrorCode SVDSetFromOptions(SVD svd)
623 : {
624 219 : char type[256];
625 219 : PetscBool set,flg,val,flg1,flg2,flg3;
626 219 : PetscInt i,j,k;
627 219 : PetscReal r;
628 :
629 219 : PetscFunctionBegin;
630 219 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
631 219 : PetscCall(SVDRegisterAll());
632 657 : PetscObjectOptionsBegin((PetscObject)svd);
633 243 : PetscCall(PetscOptionsFList("-svd_type","SVD solver method","SVDSetType",SVDList,(char*)(((PetscObject)svd)->type_name?((PetscObject)svd)->type_name:SVDCROSS),type,sizeof(type),&flg));
634 219 : if (flg) PetscCall(SVDSetType(svd,type));
635 26 : else if (!((PetscObject)svd)->type_name) PetscCall(SVDSetType(svd,SVDCROSS));
636 :
637 219 : PetscCall(PetscOptionsBoolGroupBegin("-svd_standard","Singular value decomposition (SVD)","SVDSetProblemType",&flg));
638 219 : if (flg) PetscCall(SVDSetProblemType(svd,SVD_STANDARD));
639 219 : PetscCall(PetscOptionsBoolGroup("-svd_generalized","Generalized singular value decomposition (GSVD)","SVDSetProblemType",&flg));
640 219 : if (flg) PetscCall(SVDSetProblemType(svd,SVD_GENERALIZED));
641 219 : PetscCall(PetscOptionsBoolGroupEnd("-svd_hyperbolic","Hyperbolic singular value decomposition (HSVD)","SVDSetProblemType",&flg));
642 219 : if (flg) PetscCall(SVDSetProblemType(svd,SVD_HYPERBOLIC));
643 :
644 219 : PetscCall(PetscOptionsBool("-svd_implicittranspose","Handle matrix transpose implicitly","SVDSetImplicitTranspose",svd->impltrans,&val,&flg));
645 219 : if (flg) PetscCall(SVDSetImplicitTranspose(svd,val));
646 :
647 219 : i = svd->max_it;
648 219 : PetscCall(PetscOptionsInt("-svd_max_it","Maximum number of iterations","SVDSetTolerances",svd->max_it,&i,&flg1));
649 219 : r = svd->tol;
650 417 : PetscCall(PetscOptionsReal("-svd_tol","Tolerance","SVDSetTolerances",SlepcDefaultTol(svd->tol),&r,&flg2));
651 219 : if (flg1 || flg2) PetscCall(SVDSetTolerances(svd,r,i));
652 :
653 219 : PetscCall(PetscOptionsBoolGroupBegin("-svd_conv_abs","Absolute error convergence test","SVDSetConvergenceTest",&flg));
654 219 : if (flg) PetscCall(SVDSetConvergenceTest(svd,SVD_CONV_ABS));
655 219 : PetscCall(PetscOptionsBoolGroup("-svd_conv_rel","Relative error convergence test","SVDSetConvergenceTest",&flg));
656 219 : if (flg) PetscCall(SVDSetConvergenceTest(svd,SVD_CONV_REL));
657 219 : PetscCall(PetscOptionsBoolGroup("-svd_conv_norm","Convergence test relative to the matrix norms","SVDSetConvergenceTest",&flg));
658 219 : if (flg) PetscCall(SVDSetConvergenceTest(svd,SVD_CONV_NORM));
659 219 : PetscCall(PetscOptionsBoolGroup("-svd_conv_maxit","Maximum iterations convergence test","SVDSetConvergenceTest",&flg));
660 219 : if (flg) PetscCall(SVDSetConvergenceTest(svd,SVD_CONV_MAXIT));
661 219 : PetscCall(PetscOptionsBoolGroupEnd("-svd_conv_user","User-defined convergence test","SVDSetConvergenceTest",&flg));
662 219 : if (flg) PetscCall(SVDSetConvergenceTest(svd,SVD_CONV_USER));
663 :
664 219 : PetscCall(PetscOptionsBoolGroupBegin("-svd_stop_basic","Stop iteration if all singular values converged or max_it reached","SVDSetStoppingTest",&flg));
665 219 : if (flg) PetscCall(SVDSetStoppingTest(svd,SVD_STOP_BASIC));
666 219 : PetscCall(PetscOptionsBoolGroupEnd("-svd_stop_user","User-defined stopping test","SVDSetStoppingTest",&flg));
667 219 : if (flg) PetscCall(SVDSetStoppingTest(svd,SVD_STOP_USER));
668 :
669 219 : i = svd->nsv;
670 219 : PetscCall(PetscOptionsInt("-svd_nsv","Number of singular values to compute","SVDSetDimensions",svd->nsv,&i,&flg1));
671 219 : j = svd->ncv;
672 219 : PetscCall(PetscOptionsInt("-svd_ncv","Number of basis vectors","SVDSetDimensions",svd->ncv,&j,&flg2));
673 219 : k = svd->mpd;
674 219 : PetscCall(PetscOptionsInt("-svd_mpd","Maximum dimension of projected problem","SVDSetDimensions",svd->mpd,&k,&flg3));
675 219 : if (flg1 || flg2 || flg3) PetscCall(SVDSetDimensions(svd,i,j,k));
676 :
677 219 : PetscCall(PetscOptionsBoolGroupBegin("-svd_largest","Compute largest singular values","SVDSetWhichSingularTriplets",&flg));
678 219 : if (flg) PetscCall(SVDSetWhichSingularTriplets(svd,SVD_LARGEST));
679 219 : PetscCall(PetscOptionsBoolGroupEnd("-svd_smallest","Compute smallest singular values","SVDSetWhichSingularTriplets",&flg));
680 219 : if (flg) PetscCall(SVDSetWhichSingularTriplets(svd,SVD_SMALLEST));
681 :
682 : /* -----------------------------------------------------------------------*/
683 : /*
684 : Cancels all monitors hardwired into code before call to SVDSetFromOptions()
685 : */
686 219 : PetscCall(PetscOptionsBool("-svd_monitor_cancel","Remove any hardwired monitor routines","SVDMonitorCancel",PETSC_FALSE,&flg,&set));
687 219 : if (set && flg) PetscCall(SVDMonitorCancel(svd));
688 219 : PetscCall(SVDMonitorSetFromOptions(svd,"-svd_monitor","first_approximation",NULL,PETSC_FALSE));
689 219 : PetscCall(SVDMonitorSetFromOptions(svd,"-svd_monitor_all","all_approximations",NULL,PETSC_TRUE));
690 219 : PetscCall(SVDMonitorSetFromOptions(svd,"-svd_monitor_conv","convergence_history",NULL,PETSC_FALSE));
691 219 : PetscCall(SVDMonitorSetFromOptions(svd,"-svd_monitor_conditioning","conditioning",NULL,PETSC_FALSE));
692 :
693 : /* -----------------------------------------------------------------------*/
694 219 : PetscCall(PetscOptionsName("-svd_view","Print detailed information on solver used","SVDView",&set));
695 219 : PetscCall(PetscOptionsName("-svd_view_vectors","View computed singular vectors","SVDVectorsView",&set));
696 219 : PetscCall(PetscOptionsName("-svd_view_values","View computed singular values","SVDValuesView",&set));
697 219 : PetscCall(PetscOptionsName("-svd_converged_reason","Print reason for convergence, and number of iterations","SVDConvergedReasonView",&set));
698 219 : PetscCall(PetscOptionsName("-svd_error_absolute","Print absolute errors of each singular triplet","SVDErrorView",&set));
699 219 : PetscCall(PetscOptionsName("-svd_error_relative","Print relative errors of each singular triplet","SVDErrorView",&set));
700 219 : PetscCall(PetscOptionsName("-svd_error_norm","Print errors relative to the matrix norms of each singular triplet","SVDErrorView",&set));
701 :
702 219 : PetscTryTypeMethod(svd,setfromoptions,PetscOptionsObject);
703 219 : PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)svd,PetscOptionsObject));
704 219 : PetscOptionsEnd();
705 :
706 219 : if (!svd->V) PetscCall(SVDGetBV(svd,&svd->V,NULL));
707 219 : PetscCall(BVSetFromOptions(svd->V));
708 219 : if (!svd->U) PetscCall(SVDGetBV(svd,NULL,&svd->U));
709 219 : PetscCall(BVSetFromOptions(svd->U));
710 219 : if (!svd->ds) PetscCall(SVDGetDS(svd,&svd->ds));
711 219 : PetscCall(SVDSetDSType(svd));
712 219 : PetscCall(DSSetFromOptions(svd->ds));
713 219 : PetscFunctionReturn(PETSC_SUCCESS);
714 : }
715 :
716 : /*@
717 : SVDSetProblemType - Specifies the type of the singular value problem.
718 :
719 : Logically Collective
720 :
721 : Input Parameters:
722 : + svd - the singular value solver context
723 : - type - a known type of singular value problem
724 :
725 : Options Database Keys:
726 : + -svd_standard - standard singular value decomposition (SVD)
727 : . -svd_generalized - generalized singular value problem (GSVD)
728 : - -svd_hyperbolic - hyperbolic singular value problem (HSVD)
729 :
730 : Notes:
731 : The GSVD requires that two matrices have been passed via SVDSetOperators().
732 : The HSVD requires that a signature matrix has been passed via SVDSetSignature().
733 :
734 : Level: intermediate
735 :
736 : .seealso: SVDSetOperators(), SVDSetSignature(), SVDSetType(), SVDGetProblemType(), SVDProblemType
737 : @*/
738 227 : PetscErrorCode SVDSetProblemType(SVD svd,SVDProblemType type)
739 : {
740 227 : PetscFunctionBegin;
741 227 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
742 908 : PetscValidLogicalCollectiveEnum(svd,type,2);
743 227 : if (type == svd->problem_type) PetscFunctionReturn(PETSC_SUCCESS);
744 227 : switch (type) {
745 104 : case SVD_STANDARD:
746 104 : svd->isgeneralized = PETSC_FALSE;
747 104 : svd->ishyperbolic = PETSC_FALSE;
748 104 : break;
749 87 : case SVD_GENERALIZED:
750 87 : svd->isgeneralized = PETSC_TRUE;
751 87 : svd->ishyperbolic = PETSC_FALSE;
752 87 : break;
753 36 : case SVD_HYPERBOLIC:
754 36 : svd->isgeneralized = PETSC_FALSE;
755 36 : svd->ishyperbolic = PETSC_TRUE;
756 36 : break;
757 0 : default:
758 0 : SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_WRONG,"Unknown singular value problem type");
759 : }
760 227 : svd->problem_type = type;
761 227 : svd->state = SVD_STATE_INITIAL;
762 227 : PetscFunctionReturn(PETSC_SUCCESS);
763 : }
764 :
765 : /*@
766 : SVDGetProblemType - Gets the problem type from the SVD object.
767 :
768 : Not Collective
769 :
770 : Input Parameter:
771 : . svd - the singular value solver context
772 :
773 : Output Parameter:
774 : . type - the problem type
775 :
776 : Level: intermediate
777 :
778 : .seealso: SVDSetProblemType(), SVDProblemType
779 : @*/
780 12 : PetscErrorCode SVDGetProblemType(SVD svd,SVDProblemType *type)
781 : {
782 12 : PetscFunctionBegin;
783 12 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
784 12 : PetscAssertPointer(type,2);
785 12 : *type = svd->problem_type;
786 12 : PetscFunctionReturn(PETSC_SUCCESS);
787 : }
788 :
789 : /*@
790 : SVDIsGeneralized - Ask if the SVD object corresponds to a generalized
791 : singular value problem.
792 :
793 : Not Collective
794 :
795 : Input Parameter:
796 : . svd - the singular value solver context
797 :
798 : Output Parameter:
799 : . is - the answer
800 :
801 : Level: intermediate
802 :
803 : .seealso: SVDIsHyperbolic()
804 : @*/
805 12 : PetscErrorCode SVDIsGeneralized(SVD svd,PetscBool* is)
806 : {
807 12 : PetscFunctionBegin;
808 12 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
809 12 : PetscAssertPointer(is,2);
810 12 : *is = svd->isgeneralized;
811 12 : PetscFunctionReturn(PETSC_SUCCESS);
812 : }
813 :
814 : /*@
815 : SVDIsHyperbolic - Ask if the SVD object corresponds to a hyperbolic
816 : singular value problem.
817 :
818 : Not Collective
819 :
820 : Input Parameter:
821 : . svd - the singular value solver context
822 :
823 : Output Parameter:
824 : . is - the answer
825 :
826 : Level: intermediate
827 :
828 : .seealso: SVDIsGeneralized()
829 : @*/
830 23 : PetscErrorCode SVDIsHyperbolic(SVD svd,PetscBool* is)
831 : {
832 23 : PetscFunctionBegin;
833 23 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
834 23 : PetscAssertPointer(is,2);
835 23 : *is = svd->ishyperbolic;
836 23 : PetscFunctionReturn(PETSC_SUCCESS);
837 : }
838 :
839 : /*@
840 : SVDSetTrackAll - Specifies if the solver must compute the residual norm of all
841 : approximate singular value or not.
842 :
843 : Logically Collective
844 :
845 : Input Parameters:
846 : + svd - the singular value solver context
847 : - trackall - whether to compute all residuals or not
848 :
849 : Notes:
850 : If the user sets trackall=PETSC_TRUE then the solver computes (or estimates)
851 : the residual norm for each singular value approximation. Computing the residual is
852 : usually an expensive operation and solvers commonly compute only the residual
853 : associated to the first unconverged singular value.
854 :
855 : The option '-svd_monitor_all' automatically activates this option.
856 :
857 : Level: developer
858 :
859 : .seealso: SVDGetTrackAll()
860 : @*/
861 2 : PetscErrorCode SVDSetTrackAll(SVD svd,PetscBool trackall)
862 : {
863 2 : PetscFunctionBegin;
864 2 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
865 8 : PetscValidLogicalCollectiveBool(svd,trackall,2);
866 2 : svd->trackall = trackall;
867 2 : PetscFunctionReturn(PETSC_SUCCESS);
868 : }
869 :
870 : /*@
871 : SVDGetTrackAll - Returns the flag indicating whether all residual norms must
872 : be computed or not.
873 :
874 : Not Collective
875 :
876 : Input Parameter:
877 : . svd - the singular value solver context
878 :
879 : Output Parameter:
880 : . trackall - the returned flag
881 :
882 : Level: developer
883 :
884 : .seealso: SVDSetTrackAll()
885 : @*/
886 104 : PetscErrorCode SVDGetTrackAll(SVD svd,PetscBool *trackall)
887 : {
888 104 : PetscFunctionBegin;
889 104 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
890 104 : PetscAssertPointer(trackall,2);
891 104 : *trackall = svd->trackall;
892 104 : PetscFunctionReturn(PETSC_SUCCESS);
893 : }
894 :
895 : /*@C
896 : SVDSetOptionsPrefix - Sets the prefix used for searching for all
897 : SVD options in the database.
898 :
899 : Logically Collective
900 :
901 : Input Parameters:
902 : + svd - the singular value solver context
903 : - prefix - the prefix string to prepend to all SVD option requests
904 :
905 : Notes:
906 : A hyphen (-) must NOT be given at the beginning of the prefix name.
907 : The first character of all runtime options is AUTOMATICALLY the
908 : hyphen.
909 :
910 : For example, to distinguish between the runtime options for two
911 : different SVD contexts, one could call
912 : .vb
913 : SVDSetOptionsPrefix(svd1,"svd1_")
914 : SVDSetOptionsPrefix(svd2,"svd2_")
915 : .ve
916 :
917 : Level: advanced
918 :
919 : .seealso: SVDAppendOptionsPrefix(), SVDGetOptionsPrefix()
920 : @*/
921 3 : PetscErrorCode SVDSetOptionsPrefix(SVD svd,const char *prefix)
922 : {
923 3 : PetscFunctionBegin;
924 3 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
925 3 : if (!svd->V) PetscCall(SVDGetBV(svd,&svd->V,&svd->U));
926 3 : PetscCall(BVSetOptionsPrefix(svd->V,prefix));
927 3 : PetscCall(BVSetOptionsPrefix(svd->U,prefix));
928 3 : if (!svd->ds) PetscCall(SVDGetDS(svd,&svd->ds));
929 3 : PetscCall(DSSetOptionsPrefix(svd->ds,prefix));
930 3 : PetscCall(PetscObjectSetOptionsPrefix((PetscObject)svd,prefix));
931 3 : PetscFunctionReturn(PETSC_SUCCESS);
932 : }
933 :
934 : /*@C
935 : SVDAppendOptionsPrefix - Appends to the prefix used for searching for all
936 : SVD options in the database.
937 :
938 : Logically Collective
939 :
940 : Input Parameters:
941 : + svd - the singular value solver context
942 : - prefix - the prefix string to prepend to all SVD option requests
943 :
944 : Notes:
945 : A hyphen (-) must NOT be given at the beginning of the prefix name.
946 : The first character of all runtime options is AUTOMATICALLY the hyphen.
947 :
948 : Level: advanced
949 :
950 : .seealso: SVDSetOptionsPrefix(), SVDGetOptionsPrefix()
951 : @*/
952 3 : PetscErrorCode SVDAppendOptionsPrefix(SVD svd,const char *prefix)
953 : {
954 3 : PetscFunctionBegin;
955 3 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
956 3 : if (!svd->V) PetscCall(SVDGetBV(svd,&svd->V,&svd->U));
957 3 : PetscCall(BVAppendOptionsPrefix(svd->V,prefix));
958 3 : PetscCall(BVAppendOptionsPrefix(svd->U,prefix));
959 3 : if (!svd->ds) PetscCall(SVDGetDS(svd,&svd->ds));
960 3 : PetscCall(DSAppendOptionsPrefix(svd->ds,prefix));
961 3 : PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)svd,prefix));
962 3 : PetscFunctionReturn(PETSC_SUCCESS);
963 : }
964 :
965 : /*@C
966 : SVDGetOptionsPrefix - Gets the prefix used for searching for all
967 : SVD options in the database.
968 :
969 : Not Collective
970 :
971 : Input Parameters:
972 : . svd - the singular value solver context
973 :
974 : Output Parameters:
975 : . prefix - pointer to the prefix string used is returned
976 :
977 : Note:
978 : On the Fortran side, the user should pass in a string 'prefix' of
979 : sufficient length to hold the prefix.
980 :
981 : Level: advanced
982 :
983 : .seealso: SVDSetOptionsPrefix(), SVDAppendOptionsPrefix()
984 : @*/
985 3 : PetscErrorCode SVDGetOptionsPrefix(SVD svd,const char *prefix[])
986 : {
987 3 : PetscFunctionBegin;
988 3 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
989 3 : PetscAssertPointer(prefix,2);
990 3 : PetscCall(PetscObjectGetOptionsPrefix((PetscObject)svd,prefix));
991 3 : PetscFunctionReturn(PETSC_SUCCESS);
992 : }
|