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 related to monitors
12 : */
13 :
14 : #include <slepc/private/svdimpl.h> /*I "slepcsvd.h" I*/
15 : #include <petscdraw.h>
16 :
17 3 : PetscErrorCode SVDMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],const char metric[],PetscInt l,const char *names[],int x,int y,int m,int n,PetscDrawLG *lgctx)
18 : {
19 3 : PetscDraw draw;
20 3 : PetscDrawAxis axis;
21 3 : PetscDrawLG lg;
22 :
23 3 : PetscFunctionBegin;
24 3 : PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
25 3 : PetscCall(PetscDrawSetFromOptions(draw));
26 3 : PetscCall(PetscDrawLGCreate(draw,l,&lg));
27 3 : if (names) PetscCall(PetscDrawLGSetLegend(lg,names));
28 3 : PetscCall(PetscDrawLGSetFromOptions(lg));
29 3 : PetscCall(PetscDrawLGGetAxis(lg,&axis));
30 3 : PetscCall(PetscDrawAxisSetLabels(axis,"Convergence","Iteration",metric));
31 3 : PetscCall(PetscDrawDestroy(&draw));
32 3 : *lgctx = lg;
33 3 : PetscFunctionReturn(PETSC_SUCCESS);
34 : }
35 :
36 : /*
37 : Runs the user provided monitor routines, if any.
38 : */
39 2792 : PetscErrorCode SVDMonitor(SVD svd,PetscInt it,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest)
40 : {
41 2792 : PetscInt i,n = svd->numbermonitors;
42 :
43 2792 : PetscFunctionBegin;
44 2815 : for (i=0;i<n;i++) PetscCall((*svd->monitor[i])(svd,it,nconv,sigma,errest,nest,svd->monitorcontext[i]));
45 2792 : PetscFunctionReturn(PETSC_SUCCESS);
46 : }
47 :
48 : /*@C
49 : SVDMonitorSet - Sets an ADDITIONAL function to be called at every
50 : iteration to monitor the error estimates for each requested singular triplet.
51 :
52 : Logically Collective
53 :
54 : Input Parameters:
55 : + svd - singular value solver context obtained from SVDCreate()
56 : . monitor - pointer to function (if this is NULL, it turns off monitoring)
57 : . mctx - [optional] context for private data for the
58 : monitor routine (use NULL if no context is desired)
59 : - monitordestroy - [optional] routine that frees monitor context (may be NULL)
60 :
61 : Calling sequence of monitor:
62 : $ PetscErrorCode monitor(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *mctx)
63 : + svd - singular value solver context obtained from SVDCreate()
64 : . its - iteration number
65 : . nconv - number of converged singular triplets
66 : . sigma - singular values
67 : . errest - relative error estimates for each singular triplet
68 : . nest - number of error estimates
69 : - mctx - optional monitoring context, as set by SVDMonitorSet()
70 :
71 : Options Database Keys:
72 : + -svd_monitor - print only the first error estimate
73 : . -svd_monitor_all - print error estimates at each iteration
74 : . -svd_monitor_conv - print the singular value approximations only when
75 : convergence has been reached
76 : . -svd_monitor_conditioning - print the condition number when available
77 : . -svd_monitor draw::draw_lg - sets line graph monitor for the first unconverged
78 : approximate singular value
79 : . -svd_monitor_all draw::draw_lg - sets line graph monitor for all unconverged
80 : approximate singular values
81 : . -svd_monitor_conv draw::draw_lg - sets line graph monitor for convergence history
82 : - -svd_monitor_cancel - cancels all monitors that have been hardwired into
83 : a code by calls to SVDMonitorSet(), but does not cancel those set via
84 : the options database.
85 :
86 : Notes:
87 : Several different monitoring routines may be set by calling
88 : SVDMonitorSet() multiple times; all will be called in the
89 : order in which they were set.
90 :
91 : Level: intermediate
92 :
93 : .seealso: SVDMonitorFirst(), SVDMonitorAll(), SVDMonitorConditioning(), SVDMonitorCancel()
94 : @*/
95 20 : PetscErrorCode SVDMonitorSet(SVD svd,PetscErrorCode (*monitor)(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *mctx),void *mctx,PetscErrorCode (*monitordestroy)(void**))
96 : {
97 20 : PetscFunctionBegin;
98 20 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
99 20 : PetscCheck(svd->numbermonitors<MAXSVDMONITORS,PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Too many SVD monitors set");
100 20 : svd->monitor[svd->numbermonitors] = monitor;
101 20 : svd->monitorcontext[svd->numbermonitors] = (void*)mctx;
102 20 : svd->monitordestroy[svd->numbermonitors++] = monitordestroy;
103 20 : PetscFunctionReturn(PETSC_SUCCESS);
104 : }
105 :
106 : /*@
107 : SVDMonitorCancel - Clears all monitors for an SVD object.
108 :
109 : Logically Collective
110 :
111 : Input Parameters:
112 : . svd - singular value solver context obtained from SVDCreate()
113 :
114 : Options Database Key:
115 : . -svd_monitor_cancel - Cancels all monitors that have been hardwired
116 : into a code by calls to SVDMonitorSet(),
117 : but does not cancel those set via the options database.
118 :
119 : Level: intermediate
120 :
121 : .seealso: SVDMonitorSet()
122 : @*/
123 211 : PetscErrorCode SVDMonitorCancel(SVD svd)
124 : {
125 211 : PetscInt i;
126 :
127 211 : PetscFunctionBegin;
128 211 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
129 231 : for (i=0; i<svd->numbermonitors; i++) {
130 20 : if (svd->monitordestroy[i]) PetscCall((*svd->monitordestroy[i])(&svd->monitorcontext[i]));
131 : }
132 211 : svd->numbermonitors = 0;
133 211 : PetscFunctionReturn(PETSC_SUCCESS);
134 : }
135 :
136 : /*@C
137 : SVDGetMonitorContext - Gets the monitor context, as set by
138 : SVDMonitorSet() for the FIRST monitor only.
139 :
140 : Not Collective
141 :
142 : Input Parameter:
143 : . svd - singular value solver context obtained from SVDCreate()
144 :
145 : Output Parameter:
146 : . ctx - monitor context
147 :
148 : Level: intermediate
149 :
150 : .seealso: SVDMonitorSet()
151 : @*/
152 0 : PetscErrorCode SVDGetMonitorContext(SVD svd,void *ctx)
153 : {
154 0 : PetscFunctionBegin;
155 0 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
156 0 : *(void**)ctx = svd->monitorcontext[0];
157 0 : PetscFunctionReturn(PETSC_SUCCESS);
158 : }
159 :
160 : /*@C
161 : SVDMonitorFirst - Print the first unconverged approximate value and
162 : error estimate at each iteration of the singular value solver.
163 :
164 : Collective
165 :
166 : Input Parameters:
167 : + svd - singular value solver context
168 : . its - iteration number
169 : . nconv - number of converged singular triplets so far
170 : . sigma - singular values
171 : . errest - error estimates
172 : . nest - number of error estimates to display
173 : - vf - viewer and format for monitoring
174 :
175 : Options Database Key:
176 : . -svd_monitor - activates SVDMonitorFirst()
177 :
178 : Level: intermediate
179 :
180 : .seealso: SVDMonitorSet(), SVDMonitorAll(), SVDMonitorConditioning(), SVDMonitorConverged()
181 : @*/
182 7 : PetscErrorCode SVDMonitorFirst(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
183 : {
184 7 : PetscViewer viewer = vf->viewer;
185 :
186 7 : PetscFunctionBegin;
187 7 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
188 7 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,7);
189 7 : if (its==1 && ((PetscObject)svd)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Singular value approximations and residual norms for %s solve.\n",((PetscObject)svd)->prefix));
190 7 : if (nconv<nest) {
191 7 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
192 7 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel));
193 7 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SVD nconv=%" PetscInt_FMT " first unconverged value (error)",its,nconv));
194 7 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
195 7 : PetscCall(PetscViewerASCIIPrintf(viewer," %g (%10.8e)\n",(double)sigma[nconv],(double)errest[nconv]));
196 7 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
197 7 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel));
198 7 : PetscCall(PetscViewerPopFormat(viewer));
199 : }
200 7 : PetscFunctionReturn(PETSC_SUCCESS);
201 : }
202 :
203 : /*@C
204 : SVDMonitorAll - Print the current approximate values and
205 : error estimates at each iteration of the singular value solver.
206 :
207 : Collective
208 :
209 : Input Parameters:
210 : + svd - singular value solver context
211 : . its - iteration number
212 : . nconv - number of converged singular triplets so far
213 : . sigma - singular values
214 : . errest - error estimates
215 : . nest - number of error estimates to display
216 : - vf - viewer and format for monitoring
217 :
218 : Options Database Key:
219 : . -svd_monitor_all - activates SVDMonitorAll()
220 :
221 : Level: intermediate
222 :
223 : .seealso: SVDMonitorSet(), SVDMonitorFirst(), SVDMonitorConditioning(), SVDMonitorConverged()
224 : @*/
225 2 : PetscErrorCode SVDMonitorAll(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
226 : {
227 2 : PetscInt i;
228 2 : PetscViewer viewer = vf->viewer;
229 :
230 2 : PetscFunctionBegin;
231 2 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
232 2 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,7);
233 2 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
234 2 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel));
235 2 : if (its==1 && ((PetscObject)svd)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Singular value approximations and residual norms for %s solve.\n",((PetscObject)svd)->prefix));
236 2 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SVD nconv=%" PetscInt_FMT " Values (Errors)",its,nconv));
237 2 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
238 14 : for (i=0;i<nest;i++) PetscCall(PetscViewerASCIIPrintf(viewer," %g (%10.8e)",(double)sigma[i],(double)errest[i]));
239 2 : PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
240 2 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
241 2 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel));
242 2 : PetscCall(PetscViewerPopFormat(viewer));
243 2 : PetscFunctionReturn(PETSC_SUCCESS);
244 : }
245 :
246 : /*@C
247 : SVDMonitorConverged - Print the approximate values and
248 : error estimates as they converge.
249 :
250 : Collective
251 :
252 : Input Parameters:
253 : + svd - singular value solver context
254 : . its - iteration number
255 : . nconv - number of converged singular triplets so far
256 : . sigma - singular values
257 : . errest - error estimates
258 : . nest - number of error estimates to display
259 : - vf - viewer and format for monitoring
260 :
261 : Options Database Key:
262 : . -svd_monitor_conv - activates SVDMonitorConverged()
263 :
264 : Level: intermediate
265 :
266 : .seealso: SVDMonitorSet(), SVDMonitorFirst(), SVDMonitorConditioning(), SVDMonitorAll()
267 : @*/
268 2 : PetscErrorCode SVDMonitorConverged(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
269 : {
270 2 : PetscInt i;
271 2 : PetscViewer viewer = vf->viewer;
272 2 : SlepcConvMon ctx;
273 :
274 2 : PetscFunctionBegin;
275 2 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
276 2 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,7);
277 2 : ctx = (SlepcConvMon)vf->data;
278 2 : if (its==1 && ((PetscObject)svd)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Convergence history for %s solve.\n",((PetscObject)svd)->prefix));
279 2 : if (its==1) ctx->oldnconv = 0;
280 2 : if (ctx->oldnconv!=nconv) {
281 2 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
282 2 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel));
283 14 : for (i=ctx->oldnconv;i<nconv;i++) {
284 12 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SVD converged value (error) #%" PetscInt_FMT,its,i));
285 12 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
286 12 : PetscCall(PetscViewerASCIIPrintf(viewer," %g (%10.8e)\n",(double)sigma[i],(double)errest[i]));
287 12 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
288 : }
289 2 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel));
290 2 : PetscCall(PetscViewerPopFormat(viewer));
291 2 : ctx->oldnconv = nconv;
292 : }
293 2 : PetscFunctionReturn(PETSC_SUCCESS);
294 : }
295 :
296 2 : PetscErrorCode SVDMonitorConvergedCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
297 : {
298 2 : SlepcConvMon mctx;
299 :
300 2 : PetscFunctionBegin;
301 2 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
302 2 : PetscCall(PetscNew(&mctx));
303 2 : mctx->ctx = ctx;
304 2 : (*vf)->data = (void*)mctx;
305 2 : PetscFunctionReturn(PETSC_SUCCESS);
306 : }
307 :
308 2 : PetscErrorCode SVDMonitorConvergedDestroy(PetscViewerAndFormat **vf)
309 : {
310 2 : PetscFunctionBegin;
311 2 : if (!*vf) PetscFunctionReturn(PETSC_SUCCESS);
312 2 : PetscCall(PetscFree((*vf)->data));
313 2 : PetscCall(PetscOptionsRestoreViewer(&(*vf)->viewer));
314 2 : PetscCall(PetscDrawLGDestroy(&(*vf)->lg));
315 2 : PetscCall(PetscFree(*vf));
316 2 : PetscFunctionReturn(PETSC_SUCCESS);
317 : }
318 :
319 : /*@C
320 : SVDMonitorFirstDrawLG - Plots the error estimate of the first unconverged
321 : approximation at each iteration of the singular value solver.
322 :
323 : Collective
324 :
325 : Input Parameters:
326 : + svd - singular value solver context
327 : . its - iteration number
328 : . nconv - number of converged singular triplets so far
329 : . sigma - singular values
330 : . errest - error estimates
331 : . nest - number of error estimates to display
332 : - vf - viewer and format for monitoring
333 :
334 : Options Database Key:
335 : . -svd_monitor draw::draw_lg - activates SVDMonitorFirstDrawLG()
336 :
337 : Level: intermediate
338 :
339 : .seealso: SVDMonitorSet()
340 : @*/
341 4 : PetscErrorCode SVDMonitorFirstDrawLG(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
342 : {
343 4 : PetscViewer viewer = vf->viewer;
344 4 : PetscDrawLG lg = vf->lg;
345 4 : PetscReal x,y;
346 :
347 4 : PetscFunctionBegin;
348 4 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
349 4 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,7);
350 4 : PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,7);
351 4 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
352 4 : if (its==1) {
353 2 : PetscCall(PetscDrawLGReset(lg));
354 2 : PetscCall(PetscDrawLGSetDimension(lg,1));
355 2 : PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(svd->tol)-2,0.0));
356 : }
357 4 : if (nconv<nest) {
358 3 : x = (PetscReal)its;
359 3 : if (errest[nconv] > 0.0) y = PetscLog10Real(errest[nconv]);
360 0 : else y = 0.0;
361 3 : PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
362 3 : if (its <= 20 || !(its % 5) || svd->reason) {
363 3 : PetscCall(PetscDrawLGDraw(lg));
364 3 : PetscCall(PetscDrawLGSave(lg));
365 : }
366 : }
367 4 : PetscCall(PetscViewerPopFormat(viewer));
368 4 : PetscFunctionReturn(PETSC_SUCCESS);
369 : }
370 :
371 : /*@C
372 : SVDMonitorFirstDrawLGCreate - Creates the plotter for the first error estimate.
373 :
374 : Collective
375 :
376 : Input Parameters:
377 : + viewer - the viewer
378 : . format - the viewer format
379 : - ctx - an optional user context
380 :
381 : Output Parameter:
382 : . vf - the viewer and format context
383 :
384 : Level: intermediate
385 :
386 : .seealso: SVDMonitorSet()
387 : @*/
388 2 : PetscErrorCode SVDMonitorFirstDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
389 : {
390 2 : PetscFunctionBegin;
391 2 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
392 2 : (*vf)->data = ctx;
393 2 : PetscCall(SVDMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"First Error Estimate","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
394 2 : PetscFunctionReturn(PETSC_SUCCESS);
395 : }
396 :
397 : /*@C
398 : SVDMonitorAllDrawLG - Plots the error estimate of all unconverged
399 : approximations at each iteration of the singular value solver.
400 :
401 : Collective
402 :
403 : Input Parameters:
404 : + svd - singular value solver context
405 : . its - iteration number
406 : . nconv - number of converged singular triplets so far
407 : . sigma - singular values
408 : . errest - error estimates
409 : . nest - number of error estimates to display
410 : - vf - viewer and format for monitoring
411 :
412 : Options Database Key:
413 : . -svd_monitor_all draw::draw_lg - activates SVDMonitorAllDrawLG()
414 :
415 : Level: intermediate
416 :
417 : .seealso: SVDMonitorSet()
418 : @*/
419 1 : PetscErrorCode SVDMonitorAllDrawLG(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
420 : {
421 1 : PetscViewer viewer = vf->viewer;
422 1 : PetscDrawLG lg = vf->lg;
423 1 : PetscInt i,n = PetscMin(svd->nsv,255);
424 1 : PetscReal *x,*y;
425 :
426 1 : PetscFunctionBegin;
427 1 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
428 1 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,7);
429 1 : PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,7);
430 1 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
431 1 : if (its==1) {
432 1 : PetscCall(PetscDrawLGReset(lg));
433 1 : PetscCall(PetscDrawLGSetDimension(lg,n));
434 1 : PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(svd->tol)-2,0.0));
435 : }
436 1 : PetscCall(PetscMalloc2(n,&x,n,&y));
437 2 : for (i=0;i<n;i++) {
438 1 : x[i] = (PetscReal)its;
439 1 : if (i < nest && errest[i] > 0.0) y[i] = PetscLog10Real(errest[i]);
440 1 : else y[i] = 0.0;
441 : }
442 1 : PetscCall(PetscDrawLGAddPoint(lg,x,y));
443 1 : if (its <= 20 || !(its % 5) || svd->reason) {
444 1 : PetscCall(PetscDrawLGDraw(lg));
445 1 : PetscCall(PetscDrawLGSave(lg));
446 : }
447 1 : PetscCall(PetscFree2(x,y));
448 1 : PetscCall(PetscViewerPopFormat(viewer));
449 1 : PetscFunctionReturn(PETSC_SUCCESS);
450 : }
451 :
452 : /*@C
453 : SVDMonitorAllDrawLGCreate - Creates the plotter for all the error estimates.
454 :
455 : Collective
456 :
457 : Input Parameters:
458 : + viewer - the viewer
459 : . format - the viewer format
460 : - ctx - an optional user context
461 :
462 : Output Parameter:
463 : . vf - the viewer and format context
464 :
465 : Level: intermediate
466 :
467 : .seealso: SVDMonitorSet()
468 : @*/
469 1 : PetscErrorCode SVDMonitorAllDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
470 : {
471 1 : PetscFunctionBegin;
472 1 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
473 1 : (*vf)->data = ctx;
474 1 : PetscCall(SVDMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"All Error Estimates","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
475 1 : PetscFunctionReturn(PETSC_SUCCESS);
476 : }
477 :
478 : /*@C
479 : SVDMonitorConvergedDrawLG - Plots the number of converged eigenvalues
480 : at each iteration of the singular value solver.
481 :
482 : Collective
483 :
484 : Input Parameters:
485 : + svd - singular value solver context
486 : . its - iteration number
487 : . nconv - number of converged singular triplets so far
488 : . sigma - singular values
489 : . errest - error estimates
490 : . nest - number of error estimates to display
491 : - vf - viewer and format for monitoring
492 :
493 : Options Database Key:
494 : . -svd_monitor_conv draw::draw_lg - activates SVDMonitorConvergedDrawLG()
495 :
496 : Level: intermediate
497 :
498 : .seealso: SVDMonitorSet()
499 : @*/
500 0 : PetscErrorCode SVDMonitorConvergedDrawLG(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
501 : {
502 0 : PetscViewer viewer = vf->viewer;
503 0 : PetscDrawLG lg = vf->lg;
504 0 : PetscReal x,y;
505 :
506 0 : PetscFunctionBegin;
507 0 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
508 0 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,7);
509 0 : PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,7);
510 0 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
511 0 : if (its==1) {
512 0 : PetscCall(PetscDrawLGReset(lg));
513 0 : PetscCall(PetscDrawLGSetDimension(lg,1));
514 0 : PetscCall(PetscDrawLGSetLimits(lg,1,1,0,svd->nsv));
515 : }
516 0 : x = (PetscReal)its;
517 0 : y = (PetscReal)svd->nconv;
518 0 : PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
519 0 : if (its <= 20 || !(its % 5) || svd->reason) {
520 0 : PetscCall(PetscDrawLGDraw(lg));
521 0 : PetscCall(PetscDrawLGSave(lg));
522 : }
523 0 : PetscCall(PetscViewerPopFormat(viewer));
524 0 : PetscFunctionReturn(PETSC_SUCCESS);
525 : }
526 :
527 : /*@C
528 : SVDMonitorConvergedDrawLGCreate - Creates the plotter for the convergence history.
529 :
530 : Collective
531 :
532 : Input Parameters:
533 : + viewer - the viewer
534 : . format - the viewer format
535 : - ctx - an optional user context
536 :
537 : Output Parameter:
538 : . vf - the viewer and format context
539 :
540 : Level: intermediate
541 :
542 : .seealso: SVDMonitorSet()
543 : @*/
544 0 : PetscErrorCode SVDMonitorConvergedDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
545 : {
546 0 : SlepcConvMon mctx;
547 :
548 0 : PetscFunctionBegin;
549 0 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
550 0 : PetscCall(PetscNew(&mctx));
551 0 : mctx->ctx = ctx;
552 0 : (*vf)->data = (void*)mctx;
553 0 : PetscCall(SVDMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"Convergence History","Number Converged",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
554 0 : PetscFunctionReturn(PETSC_SUCCESS);
555 : }
556 :
557 : /*@C
558 : SVDMonitorConditioning - Print the condition number at each iteration of the singular
559 : value solver.
560 :
561 : Collective
562 :
563 : Input Parameters:
564 : + svd - singular value solver context
565 : . its - iteration number
566 : . nconv - (unused) number of converged singular triplets so far
567 : . sigma - (unused) singular values
568 : . errest - (unused) error estimates
569 : . nest - (unused) number of error estimates to display
570 : - vf - viewer and format for monitoring
571 :
572 : Options Database Key:
573 : . -svd_monitor_conditioning - activates SVDMonitorConditioning()
574 :
575 : Note:
576 : Works only for solvers that use a DS of type GSVD. The printed information corresponds
577 : to the maximum of the condition number of the two generated bidiagonal matrices.
578 :
579 : Level: intermediate
580 :
581 : .seealso: SVDMonitorSet(), SVDMonitorAll(), SVDMonitorFirst(), SVDMonitorConverged()
582 : @*/
583 7 : PetscErrorCode SVDMonitorConditioning(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
584 : {
585 7 : PetscViewer viewer = vf->viewer;
586 7 : PetscBool isgsvd;
587 7 : PetscReal cond;
588 :
589 7 : PetscFunctionBegin;
590 7 : PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
591 7 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,7);
592 7 : PetscCall(PetscObjectTypeCompare((PetscObject)svd->ds,DSGSVD,&isgsvd));
593 7 : if (!isgsvd) PetscFunctionReturn(PETSC_SUCCESS);
594 7 : if (its==1 && ((PetscObject)svd)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Condition number of bidiagonal matrices for %s solve.\n",((PetscObject)svd)->prefix));
595 7 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
596 7 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel));
597 7 : PetscCall(DSCond(svd->ds,&cond));
598 7 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SVD condition number = %g\n",its,(double)cond));
599 7 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel));
600 7 : PetscCall(PetscViewerPopFormat(viewer));
601 7 : PetscFunctionReturn(PETSC_SUCCESS);
602 : }
|