Subversion Repositories slepc-dev

Rev

Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1288 slepc 1
/*
2
      SVD routines related to monitors.
1376 slepc 3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 6
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
1376 slepc 7
 
1672 slepc 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.
13
 
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.
18
 
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/>.
1376 slepc 21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1288 slepc 22
*/
1376 slepc 23
 
1521 slepc 24
#include "private/svdimpl.h"   /*I "slepcsvd.h" I*/
1288 slepc 25
 
26
#undef __FUNCT__  
1331 slepc 27
#define __FUNCT__ "SVDMonitorSet"
1288 slepc 28
/*@C
1331 slepc 29
   SVDMonitorSet - Sets an ADDITIONAL function to be called at every
1288 slepc 30
   iteration to monitor the error estimates for each requested singular triplet.
31
 
32
   Collective on SVD
33
 
34
   Input Parameters:
35
+  svd     - singular value solver context obtained from SVDCreate()
36
.  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring)
37
-  mctx    - [optional] context for private data for the
38
             monitor routine (use PETSC_NULL if no context is desired)
39
 
40
   Calling Sequence of monitor:
1504 slepc 41
$     monitor (SVD svd, PetscInt its, PetscInt nconv, PetscReal *sigma, PetscReal* errest, PetscInt nest, void *mctx)
1288 slepc 42
 
43
+  svd    - singular value solver context obtained from SVDCreate()
44
.  its    - iteration number
45
.  nconv  - number of converged singular triplets
46
.  sigma  - singular values
47
.  errest - relative error estimates for each singular triplet
48
.  nest   - number of error estimates
1331 slepc 49
-  mctx   - optional monitoring context, as set by SVDMonitorSet()
1288 slepc 50
 
51
   Options Database Keys:
2054 eromero 52
+    -svd_monitor          - print only the first error estimate
53
.    -svd_monitor_all      - print error estimates at each iteration
54
.    -svd_monitor_conv     - print the singular value approximations only when
1897 jroman 55
      convergence has been reached
2054 eromero 56
.    -svd_monitor_draw     - sets line graph monitor for the first unconverged
57
      approximate singular value
58
.    -svd_monitor_draw_all - sets line graph monitor for all unconverged
59
      approximate singular value
60
-    -svd_monitor_cancel   - cancels all monitors that have been hardwired into
1331 slepc 61
      a code by calls to SVDMonitorSet(), but does not cancel those set via
1288 slepc 62
      the options database.
63
 
64
   Notes:  
65
   Several different monitoring routines may be set by calling
1331 slepc 66
   SVDMonitorSet() multiple times; all will be called in the
1288 slepc 67
   order in which they were set.
68
 
69
   Level: intermediate
70
 
2134 eromero 71
.seealso: SVDMonitorFirst(), SVDMonitorAll(), SVDMonitorLG(), SVDMonitorLGAll(), SVDMonitorCancel()
1288 slepc 72
@*/
1504 slepc 73
PetscErrorCode SVDMonitorSet(SVD svd,PetscErrorCode (*monitor)(SVD,PetscInt,PetscInt,PetscReal*,PetscReal*,PetscInt,void*),
1288 slepc 74
                             void *mctx,PetscErrorCode (*monitordestroy)(void*))
75
{
76
  PetscFunctionBegin;
2213 jroman 77
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1288 slepc 78
  if (svd->numbermonitors >= MAXSVDMONITORS) {
2214 jroman 79
    SETERRQ(((PetscObject)svd)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many SVD monitors set");
1288 slepc 80
  }
81
  svd->monitor[svd->numbermonitors]           = monitor;
82
  svd->monitorcontext[svd->numbermonitors]    = (void*)mctx;
83
  svd->monitordestroy[svd->numbermonitors++]  = monitordestroy;
84
  PetscFunctionReturn(0);
85
}
86
 
87
#undef __FUNCT__  
1331 slepc 88
#define __FUNCT__ "SVDMonitorCancel"
1288 slepc 89
/*@
1331 slepc 90
   SVDMonitorCancel - Clears all monitors for an SVD object.
1288 slepc 91
 
92
   Collective on SVD
93
 
94
   Input Parameters:
95
.  svd - singular value solver context obtained from SVDCreate()
96
 
97
   Options Database Key:
1331 slepc 98
.    -svd_monitor_cancel - Cancels all monitors that have been hardwired
99
      into a code by calls to SVDMonitorSet(),
1288 slepc 100
      but does not cancel those set via the options database.
101
 
102
   Level: intermediate
103
 
2134 eromero 104
.seealso: SVDMonitorSet()
1288 slepc 105
@*/
1331 slepc 106
PetscErrorCode SVDMonitorCancel(SVD svd)
1288 slepc 107
{
108
  PetscErrorCode ierr;
109
  PetscInt       i;
110
 
111
  PetscFunctionBegin;
2213 jroman 112
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1288 slepc 113
  for (i=0; i<svd->numbermonitors; i++) {
114
    if (svd->monitordestroy[i]) {
115
      ierr = (*svd->monitordestroy[i])(svd->monitorcontext[i]);CHKERRQ(ierr);
116
    }
117
  }
118
  svd->numbermonitors = 0;
119
  PetscFunctionReturn(0);
120
}
121
 
122
#undef __FUNCT__  
123
#define __FUNCT__ "SVDGetMonitorContext"
124
/*@C
125
   SVDGetMonitorContext - Gets the monitor context, as set by
1331 slepc 126
   SVDMonitorSet() for the FIRST monitor only.
1288 slepc 127
 
128
   Not Collective
129
 
130
   Input Parameter:
131
.  svd - singular value solver context obtained from SVDCreate()
132
 
133
   Output Parameter:
134
.  ctx - monitor context
135
 
136
   Level: intermediate
137
 
2134 eromero 138
.seealso: SVDMonitorSet()
1288 slepc 139
@*/
140
PetscErrorCode SVDGetMonitorContext(SVD svd, void **ctx)
141
{
142
  PetscFunctionBegin;
2213 jroman 143
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1288 slepc 144
  *ctx =      (svd->monitorcontext[0]);
145
  PetscFunctionReturn(0);
146
}
147
 
148
#undef __FUNCT__  
2054 eromero 149
#define __FUNCT__ "SVDMonitorAll"
1288 slepc 150
/*@C
2054 eromero 151
   SVDMonitorAll - Print the current approximate values and
1288 slepc 152
   error estimates at each iteration of the singular value solver.
153
 
154
   Collective on SVD
155
 
156
   Input Parameters:
157
+  svd    - singular value solver context
158
.  its    - iteration number
159
.  nconv  - number of converged singular triplets so far
160
.  sigma  - singular values
161
.  errest - error estimates
162
.  nest   - number of error estimates to display
163
-  dummy  - unused monitor context
164
 
165
   Level: intermediate
166
 
1331 slepc 167
.seealso: SVDMonitorSet()
1288 slepc 168
@*/
2054 eromero 169
PetscErrorCode SVDMonitorAll(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *dummy)
1288 slepc 170
{
1532 slepc 171
  PetscErrorCode          ierr;
172
  PetscInt                i;
173
  PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
1288 slepc 174
 
175
  PetscFunctionBegin;
176
  if (its) {
1532 slepc 177
    if (!dummy) {ierr = PetscViewerASCIIMonitorCreate(((PetscObject)svd)->comm,"stdout",0,&viewer);CHKERRQ(ierr);}
178
    ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3d SVD nconv=%d Values (Errors)",its,nconv);CHKERRQ(ierr);
1288 slepc 179
    for (i=0;i<nest;i++) {
1532 slepc 180
      ierr = PetscViewerASCIIMonitorPrintf(viewer," %g (%10.8e)",sigma[i],errest[i]);CHKERRQ(ierr);
1288 slepc 181
    }
1532 slepc 182
    ierr = PetscViewerASCIIMonitorPrintf(viewer,"\n");CHKERRQ(ierr);
183
    if (!dummy) {ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);}
1288 slepc 184
  }
185
  PetscFunctionReturn(0);
186
}
187
 
188
#undef __FUNCT__  
1721 antodo 189
#define __FUNCT__ "SVDMonitorFirst"
190
/*@C
191
   SVDMonitorFirst - Print the first unconverged approximate values and
192
   error estimates at each iteration of the singular value solver.
193
 
194
   Collective on SVD
195
 
196
   Input Parameters:
197
+  svd    - singular value solver context
198
.  its    - iteration number
199
.  nconv  - number of converged singular triplets so far
200
.  sigma  - singular values
201
.  errest - error estimates
202
.  nest   - number of error estimates to display
203
-  dummy  - unused monitor context
204
 
205
   Level: intermediate
206
 
207
.seealso: SVDMonitorSet()
208
@*/
209
PetscErrorCode SVDMonitorFirst(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *dummy)
210
{
211
  PetscErrorCode          ierr;
212
  PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
213
 
214
  PetscFunctionBegin;
215
  if (its && nconv<nest) {
216
    if (!dummy) {ierr = PetscViewerASCIIMonitorCreate(((PetscObject)svd)->comm,"stdout",0,&viewer);CHKERRQ(ierr);}
217
    ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3d SVD nconv=%d first unconverged value (error)",its,nconv);CHKERRQ(ierr);
218
    ierr = PetscViewerASCIIMonitorPrintf(viewer," %g (%10.8e)\n",sigma[nconv],errest[nconv]);CHKERRQ(ierr);
219
    if (!dummy) {ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);}
220
  }
221
  PetscFunctionReturn(0);
222
}
223
 
224
#undef __FUNCT__  
225
#define __FUNCT__ "SVDMonitorConverged"
226
/*@C
227
   SVDMonitorConverged - Print the approximate values and error estimates as they converge.
228
 
229
   Collective on SVD
230
 
231
   Input Parameters:
232
+  svd    - singular value solver context
233
.  its    - iteration number
234
.  nconv  - number of converged singular triplets so far
235
.  sigma  - singular values
236
.  errest - error estimates
237
.  nest   - number of error estimates to display
238
-  dummy  - unused monitor context
239
 
240
   Level: intermediate
241
 
242
.seealso: SVDMonitorSet()
243
@*/
244
PetscErrorCode SVDMonitorConverged(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *dummy)
245
{
1951 jroman 246
  PetscErrorCode  ierr;
247
  PetscInt        i;
248
  SVDMONITOR_CONV *ctx = (SVDMONITOR_CONV*) dummy;
1721 antodo 249
 
250
  PetscFunctionBegin;
251
  if (!its) {
1951 jroman 252
    ctx->oldnconv = 0;
1721 antodo 253
  } else {
1951 jroman 254
    for (i=ctx->oldnconv;i<nconv;i++) {
255
      ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3d SVD converged value (error) #%d",its,i);CHKERRQ(ierr);
256
      ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer," %g (%10.8e)\n",sigma[i],errest[i]);CHKERRQ(ierr);
1721 antodo 257
    }
1951 jroman 258
    ctx->oldnconv = nconv;
1721 antodo 259
  }
260
  PetscFunctionReturn(0);
261
}
262
 
1951 jroman 263
PetscErrorCode SVDMonitorDestroy_Converged(SVDMONITOR_CONV *ctx)
264
{
265
  PetscErrorCode  ierr;
266
  PetscFunctionBegin;
267
  ierr = PetscViewerASCIIMonitorDestroy(ctx->viewer);CHKERRQ(ierr);
268
  ierr = PetscFree(ctx);CHKERRQ(ierr);
269
  PetscFunctionReturn(0);
270
}
271
 
1721 antodo 272
#undef __FUNCT__  
1331 slepc 273
#define __FUNCT__ "SVDMonitorLG"
1504 slepc 274
PetscErrorCode SVDMonitorLG(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *monctx)
1288 slepc 275
{
276
  PetscViewer    viewer = (PetscViewer) monctx;
277
  PetscDraw      draw;
278
  PetscDrawLG    lg;
279
  PetscErrorCode ierr;
2054 eromero 280
  PetscReal      x,y,p;
281
  PetscDraw      draw1;
282
  PetscDrawLG    lg1;
283
 
284
  PetscFunctionBegin;
285
 
286
  if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)svd)->comm); }
287
 
288
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
289
  ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
290
  ierr = PetscViewerDrawGetDraw(viewer,1,&draw1);CHKERRQ(ierr);
291
  ierr = PetscViewerDrawGetDrawLG(viewer,1,&lg1);CHKERRQ(ierr);
292
 
293
  if (!its) {
294
    ierr = PetscDrawSetTitle(draw,"Error estimates");CHKERRQ(ierr);
295
    ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
296
    ierr = PetscDrawLGSetDimension(lg,1);CHKERRQ(ierr);
297
    ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);
298
    ierr = PetscDrawLGSetLimits(lg,0,1.0,log10(svd->tol)-2,0.0);CHKERRQ(ierr);
299
 
300
    ierr = PetscDrawSetTitle(draw1,"Approximate singular values");CHKERRQ(ierr);
301
    ierr = PetscDrawSetDoubleBuffer(draw1);CHKERRQ(ierr);
302
    ierr = PetscDrawLGSetDimension(lg1,1);CHKERRQ(ierr);
303
    ierr = PetscDrawLGReset(lg1);CHKERRQ(ierr);
304
    ierr = PetscDrawLGSetLimits(lg1,0,1.0,1.e20,-1.e20);CHKERRQ(ierr);
305
  }
306
 
307
  x = (PetscReal) its;
308
  if (errest[nconv] > 0.0) y = log10(errest[nconv]); else y = 0.0;
309
  ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
310
 
311
  ierr = PetscDrawLGAddPoint(lg1,&x,svd->sigma);CHKERRQ(ierr);
312
  ierr = PetscDrawGetPause(draw1,&p);CHKERRQ(ierr);
313
  ierr = PetscDrawSetPause(draw1,0);CHKERRQ(ierr);
314
  ierr = PetscDrawLGDraw(lg1);CHKERRQ(ierr);
315
  ierr = PetscDrawSetPause(draw1,p);CHKERRQ(ierr);
316
 
317
  ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
318
  PetscFunctionReturn(0);
319
}
320
 
321
#undef __FUNCT__  
322
#define __FUNCT__ "SVDMonitorLGAll"
323
PetscErrorCode SVDMonitorLGAll(SVD svd,PetscInt its,PetscInt nconv,PetscReal *sigma,PetscReal *errest,PetscInt nest,void *monctx)
324
{
325
  PetscViewer    viewer = (PetscViewer) monctx;
326
  PetscDraw      draw;
327
  PetscDrawLG    lg;
328
  PetscErrorCode ierr;
1852 antodo 329
  PetscReal      *x,*y,p;
2011 jroman 330
  int            n = PetscMin(svd->nsv,255);
1504 slepc 331
  PetscInt       i;
1288 slepc 332
  PetscDraw      draw1;
333
  PetscDrawLG    lg1;
334
 
335
  PetscFunctionBegin;
336
 
1422 slepc 337
  if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)svd)->comm); }
1288 slepc 338
 
339
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
340
  ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
341
  ierr = PetscViewerDrawGetDraw(viewer,1,&draw1);CHKERRQ(ierr);
342
  ierr = PetscViewerDrawGetDrawLG(viewer,1,&lg1);CHKERRQ(ierr);
343
 
344
  if (!its) {
345
    ierr = PetscDrawSetTitle(draw,"Error estimates");CHKERRQ(ierr);
346
    ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
347
    ierr = PetscDrawLGSetDimension(lg,n);CHKERRQ(ierr);
348
    ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);
349
    ierr = PetscDrawLGSetLimits(lg,0,1.0,log10(svd->tol)-2,0.0);CHKERRQ(ierr);
350
 
351
    ierr = PetscDrawSetTitle(draw1,"Approximate singular values");CHKERRQ(ierr);
352
    ierr = PetscDrawSetDoubleBuffer(draw1);CHKERRQ(ierr);
353
    ierr = PetscDrawLGSetDimension(lg1,n);CHKERRQ(ierr);
354
    ierr = PetscDrawLGReset(lg1);CHKERRQ(ierr);
355
    ierr = PetscDrawLGSetLimits(lg1,0,1.0,1.e20,-1.e20);CHKERRQ(ierr);
356
  }
357
 
358
  ierr = PetscMalloc(sizeof(PetscReal)*n,&x);CHKERRQ(ierr);
359
  ierr = PetscMalloc(sizeof(PetscReal)*n,&y);CHKERRQ(ierr);
360
  for (i=0;i<n;i++) {
361
    x[i] = (PetscReal) its;
2054 eromero 362
    if (i < nest && errest[i] > 0.0) y[i] = log10(errest[i]);
363
    else y[i] = 0.0;
1288 slepc 364
  }
365
  ierr = PetscDrawLGAddPoint(lg,x,y);CHKERRQ(ierr);
366
 
367
  ierr = PetscDrawLGAddPoint(lg1,x,svd->sigma);CHKERRQ(ierr);
368
  ierr = PetscDrawGetPause(draw1,&p);CHKERRQ(ierr);
369
  ierr = PetscDrawSetPause(draw1,0);CHKERRQ(ierr);
370
  ierr = PetscDrawLGDraw(lg1);CHKERRQ(ierr);
371
  ierr = PetscDrawSetPause(draw1,p);CHKERRQ(ierr);
372
 
373
  ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
374
  ierr = PetscFree(x);CHKERRQ(ierr);
375
  ierr = PetscFree(y);CHKERRQ(ierr);
376
  PetscFunctionReturn(0);
377
}