Actual source code: svdmon.c
1: /*
2: SVD routines related to monitors.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
8: This file is part of SLEPc.
9:
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 <private/svdimpl.h> /*I "slepcsvd.h" I*/
28: /*
29: Runs the user provided monitor routines, if any.
30: */
31: PetscErrorCode SVDMonitor(SVD svd,PetscInt it,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest)
32: {
34: PetscInt i,n = svd->numbermonitors;
37: for (i=0;i<n;i++) {
38: (*svd->monitor[i])(svd,it,nconv,sigma,errest,nest,svd->monitorcontext[i]);
39: }
40: return(0);
41: }
45: /*@C
46: SVDMonitorSet - Sets an ADDITIONAL function to be called at every
47: iteration to monitor the error estimates for each requested singular triplet.
48:
49: Collective on SVD
51: Input Parameters:
52: + svd - singular value solver context obtained from SVDCreate()
53: . monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring)
54: - mctx - [optional] context for private data for the
55: monitor routine (use PETSC_NULL if no context is desired)
57: Calling Sequence of monitor:
58: $ monitor (SVD svd, PetscInt its, PetscInt nconv, PetscReal *sigma, PetscReal* errest, PetscInt nest, void *mctx)
60: + svd - singular value solver context obtained from SVDCreate()
61: . its - iteration number
62: . nconv - number of converged singular triplets
63: . sigma - singular values
64: . errest - relative error estimates for each singular triplet
65: . nest - number of error estimates
66: - mctx - optional monitoring context, as set by SVDMonitorSet()
68: Options Database Keys:
69: + -svd_monitor - print only the first error estimate
70: . -svd_monitor_all - print error estimates at each iteration
71: . -svd_monitor_conv - print the singular value approximations only when
72: convergence has been reached
73: . -svd_monitor_draw - sets line graph monitor for the first unconverged
74: approximate singular value
75: . -svd_monitor_draw_all - sets line graph monitor for all unconverged
76: approximate singular value
77: - -svd_monitor_cancel - cancels all monitors that have been hardwired into
78: a code by calls to SVDMonitorSet(), but does not cancel those set via
79: the options database.
81: Notes:
82: Several different monitoring routines may be set by calling
83: SVDMonitorSet() multiple times; all will be called in the
84: order in which they were set.
86: Level: intermediate
88: .seealso: SVDMonitorFirst(), SVDMonitorAll(), SVDMonitorLG(), SVDMonitorLGAll(), SVDMonitorCancel()
89: @*/
90: PetscErrorCode SVDMonitorSet(SVD svd,PetscErrorCode (*monitor)(SVD,PetscInt,PetscInt,PetscReal*,PetscReal*,PetscInt,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
91: {
94: if (svd->numbermonitors >= MAXSVDMONITORS) {
95: SETERRQ(((PetscObject)svd)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many SVD monitors set");
96: }
97: svd->monitor[svd->numbermonitors] = monitor;
98: svd->monitorcontext[svd->numbermonitors] = (void*)mctx;
99: svd->monitordestroy[svd->numbermonitors++] = monitordestroy;
100: return(0);
101: }
105: /*@
106: SVDMonitorCancel - Clears all monitors for an SVD object.
108: Collective on SVD
110: Input Parameters:
111: . svd - singular value solver context obtained from SVDCreate()
113: Options Database Key:
114: . -svd_monitor_cancel - Cancels all monitors that have been hardwired
115: into a code by calls to SVDMonitorSet(),
116: but does not cancel those set via the options database.
118: Level: intermediate
120: .seealso: SVDMonitorSet()
121: @*/
122: PetscErrorCode SVDMonitorCancel(SVD svd)
123: {
125: PetscInt i;
129: for (i=0; i<svd->numbermonitors; i++) {
130: if (svd->monitordestroy[i]) {
131: (*svd->monitordestroy[i])(&svd->monitorcontext[i]);
132: }
133: }
134: svd->numbermonitors = 0;
135: return(0);
136: }
140: /*@C
141: SVDGetMonitorContext - Gets the monitor context, as set by
142: SVDMonitorSet() for the FIRST monitor only.
144: Not Collective
146: Input Parameter:
147: . svd - singular value solver context obtained from SVDCreate()
149: Output Parameter:
150: . ctx - monitor context
152: Level: intermediate
154: .seealso: SVDMonitorSet()
155: @*/
156: PetscErrorCode SVDGetMonitorContext(SVD svd,void **ctx)
157: {
160: *ctx = (svd->monitorcontext[0]);
161: return(0);
162: }
166: /*@C
167: SVDMonitorAll - Print the current approximate values and
168: error estimates at each iteration of the singular value solver.
170: Collective on SVD
172: Input Parameters:
173: + svd - singular value solver context
174: . its - iteration number
175: . nconv - number of converged singular triplets so far
176: . sigma - singular values
177: . errest - error estimates
178: . nest - number of error estimates to display
179: - dummy - unused monitor context
181: Level: intermediate
183: .seealso: SVDMonitorSet(), SVDMonitorFirst(), SVDMonitorConverged()
184: @*/
185: PetscErrorCode SVDMonitorAll(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *dummy)
186: {
188: PetscInt i;
189: PetscViewer viewer = dummy? (PetscViewer)dummy: PETSC_VIEWER_STDOUT_(((PetscObject)svd)->comm);
192: if (its) {
193: PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel);
194: PetscViewerASCIIPrintf(viewer,"%3D SVD nconv=%D Values (Errors)",its,nconv);
195: for (i=0;i<nest;i++) {
196: PetscViewerASCIIPrintf(viewer," %G (%10.8e)",sigma[i],(double)errest[i]);
197: }
198: PetscViewerASCIIPrintf(viewer,"\n");
199: PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel);
200: }
201: return(0);
202: }
206: /*@C
207: SVDMonitorFirst - Print the first unconverged approximate values and
208: error estimates at each iteration of the singular value solver.
210: Collective on SVD
212: Input Parameters:
213: + svd - singular value solver context
214: . its - iteration number
215: . nconv - number of converged singular triplets so far
216: . sigma - singular values
217: . errest - error estimates
218: . nest - number of error estimates to display
219: - dummy - unused monitor context
221: Level: intermediate
223: .seealso: SVDMonitorSet(), SVDMonitorAll(), SVDMonitorConverged()
224: @*/
225: PetscErrorCode SVDMonitorFirst(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *dummy)
226: {
228: PetscViewer viewer = dummy? (PetscViewer)dummy: PETSC_VIEWER_STDOUT_(((PetscObject)svd)->comm);
231: if (its && nconv<nest) {
232: PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel);
233: PetscViewerASCIIPrintf(viewer,"%3D SVD nconv=%D first unconverged value (error)",its,nconv);
234: PetscViewerASCIIPrintf(viewer," %G (%10.8e)\n",sigma[nconv],(double)errest[nconv]);
235: PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel);
236: }
237: return(0);
238: }
242: /*@C
243: SVDMonitorConverged - Print the approximate values and error estimates as they converge.
245: Collective on SVD
247: Input Parameters:
248: + svd - singular value solver context
249: . its - iteration number
250: . nconv - number of converged singular triplets so far
251: . sigma - singular values
252: . errest - error estimates
253: . nest - number of error estimates to display
254: - dummy - unused monitor context
256: Level: intermediate
258: .seealso: SVDMonitorSet(), SVDMonitorFirst(), SVDMonitorAll()
259: @*/
260: PetscErrorCode SVDMonitorConverged(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *dummy)
261: {
262: PetscErrorCode ierr;
263: PetscInt i;
264: SlepcConvMonitor ctx = (SlepcConvMonitor) dummy;
267: if (!its) {
268: ctx->oldnconv = 0;
269: } else {
270: for (i=ctx->oldnconv;i<nconv;i++) {
271: PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)svd)->tablevel);
272: PetscViewerASCIIPrintf(ctx->viewer,"%3D SVD converged value (error) #%D",its,i);
273: PetscViewerASCIIPrintf(ctx->viewer," %G (%10.8e)\n",sigma[i],(double)errest[i]);
274: PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)svd)->tablevel);
275: }
276: ctx->oldnconv = nconv;
277: }
278: return(0);
279: }
283: PetscErrorCode SVDMonitorLG(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *monctx)
284: {
285: PetscViewer viewer = (PetscViewer) monctx;
286: PetscDraw draw,draw1;
287: PetscDrawLG lg,lg1;
289: PetscReal x,y,p;
292: if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)svd)->comm); }
293: PetscViewerDrawGetDraw(viewer,0,&draw);
294: PetscViewerDrawGetDrawLG(viewer,0,&lg);
295: PetscViewerDrawGetDraw(viewer,1,&draw1);
296: PetscViewerDrawGetDrawLG(viewer,1,&lg1);
298: if (!its) {
299: PetscDrawSetTitle(draw,"Error estimates");
300: PetscDrawSetDoubleBuffer(draw);
301: PetscDrawLGSetDimension(lg,1);
302: PetscDrawLGReset(lg);
303: PetscDrawLGSetLimits(lg,0,1.0,log10(svd->tol)-2,0.0);
305: PetscDrawSetTitle(draw1,"Approximate singular values");
306: PetscDrawSetDoubleBuffer(draw1);
307: PetscDrawLGSetDimension(lg1,1);
308: PetscDrawLGReset(lg1);
309: PetscDrawLGSetLimits(lg1,0,1.0,1.e20,-1.e20);
310: }
312: x = (PetscReal) its;
313: if (errest[nconv] > 0.0) y = log10(errest[nconv]); else y = 0.0;
314: PetscDrawLGAddPoint(lg,&x,&y);
316: PetscDrawLGAddPoint(lg1,&x,svd->sigma);
317: PetscDrawGetPause(draw1,&p);
318: PetscDrawSetPause(draw1,0);
319: PetscDrawLGDraw(lg1);
320: PetscDrawSetPause(draw1,p);
321:
322: PetscDrawLGDraw(lg);
323: return(0);
324: }
328: PetscErrorCode SVDMonitorLGAll(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *monctx)
329: {
330: PetscViewer viewer = (PetscViewer) monctx;
331: PetscDraw draw,draw1;
332: PetscDrawLG lg,lg1;
334: PetscReal *x,*y,p;
335: PetscInt i,n = PetscMin(svd->nsv,255);
338: if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)svd)->comm); }
339: PetscViewerDrawGetDraw(viewer,0,&draw);
340: PetscViewerDrawGetDrawLG(viewer,0,&lg);
341: PetscViewerDrawGetDraw(viewer,1,&draw1);
342: PetscViewerDrawGetDrawLG(viewer,1,&lg1);
344: if (!its) {
345: PetscDrawSetTitle(draw,"Error estimates");
346: PetscDrawSetDoubleBuffer(draw);
347: PetscDrawLGSetDimension(lg,n);
348: PetscDrawLGReset(lg);
349: PetscDrawLGSetLimits(lg,0,1.0,log10(svd->tol)-2,0.0);
351: PetscDrawSetTitle(draw1,"Approximate singular values");
352: PetscDrawSetDoubleBuffer(draw1);
353: PetscDrawLGSetDimension(lg1,n);
354: PetscDrawLGReset(lg1);
355: PetscDrawLGSetLimits(lg1,0,1.0,1.e20,-1.e20);
356: }
358: PetscMalloc(sizeof(PetscReal)*n,&x);
359: PetscMalloc(sizeof(PetscReal)*n,&y);
360: for (i=0;i<n;i++) {
361: x[i] = (PetscReal) its;
362: if (i < nest && errest[i] > 0.0) y[i] = log10(errest[i]);
363: else y[i] = 0.0;
364: }
365: PetscDrawLGAddPoint(lg,x,y);
367: PetscDrawLGAddPoint(lg1,x,svd->sigma);
368: PetscDrawGetPause(draw1,&p);
369: PetscDrawSetPause(draw1,0);
370: PetscDrawLGDraw(lg1);
371: PetscDrawSetPause(draw1,p);
372:
373: PetscDrawLGDraw(lg);
374: PetscFree(x);
375: PetscFree(y);
376: return(0);
377: }