Actual source code: svdview.c
slepc-3.10.1 2018-10-23
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2018, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7: SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9: */
10: /*
11: The SVD routines related to various viewers
12: */
14: #include <slepc/private/svdimpl.h> /*I "slepcsvd.h" I*/
15: #include <petscdraw.h>
17: /*@C
18: SVDView - Prints the SVD data structure.
20: Collective on SVD
22: Input Parameters:
23: + svd - the singular value solver context
24: - viewer - optional visualization context
26: Options Database Key:
27: . -svd_view - Calls SVDView() at end of SVDSolve()
29: Note:
30: The available visualization contexts include
31: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
32: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
33: output where only the first processor opens
34: the file. All other processors send their
35: data to the first processor to print.
37: The user can open an alternative visualization context with
38: PetscViewerASCIIOpen() - output to a specified file.
40: Level: beginner
42: .seealso: STView(), PetscViewerASCIIOpen()
43: @*/
44: PetscErrorCode SVDView(SVD svd,PetscViewer viewer)
45: {
47: PetscBool isascii,isshell;
48: PetscInt tabs;
52: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
56: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
57: if (isascii) {
58: PetscViewerASCIIGetTab(viewer,&tabs);
59: PetscViewerASCIISetTab(viewer,((PetscObject)svd)->tablevel);
60: PetscObjectPrintClassNamePrefixType((PetscObject)svd,viewer);
61: if (svd->ops->view) {
62: PetscViewerASCIIPushTab(viewer);
63: (*svd->ops->view)(svd,viewer);
64: PetscViewerASCIIPopTab(viewer);
65: }
66: PetscViewerASCIIPrintf(viewer," transpose mode: %s\n",svd->impltrans?"implicit":"explicit");
67: if (svd->which == SVD_LARGEST) {
68: PetscViewerASCIIPrintf(viewer," selected portion of the spectrum: largest\n");
69: } else {
70: PetscViewerASCIIPrintf(viewer," selected portion of the spectrum: smallest\n");
71: }
72: PetscViewerASCIIPrintf(viewer," number of singular values (nsv): %D\n",svd->nsv);
73: PetscViewerASCIIPrintf(viewer," number of column vectors (ncv): %D\n",svd->ncv);
74: PetscViewerASCIIPrintf(viewer," maximum dimension of projected problem (mpd): %D\n",svd->mpd);
75: PetscViewerASCIIPrintf(viewer," maximum number of iterations: %D\n",svd->max_it);
76: PetscViewerASCIIPrintf(viewer," tolerance: %g\n",(double)svd->tol);
77: PetscViewerASCIIPrintf(viewer," convergence test: ");
78: PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);
79: switch (svd->conv) {
80: case SVD_CONV_ABS:
81: PetscViewerASCIIPrintf(viewer,"absolute\n");break;
82: case SVD_CONV_REL:
83: PetscViewerASCIIPrintf(viewer,"relative to the singular value\n");break;
84: case SVD_CONV_USER:
85: PetscViewerASCIIPrintf(viewer,"user-defined\n");break;
86: }
87: PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
88: if (svd->nini) {
89: PetscViewerASCIIPrintf(viewer," dimension of user-provided initial space: %D\n",PetscAbs(svd->nini));
90: }
91: if (svd->ninil) {
92: PetscViewerASCIIPrintf(viewer," dimension of user-provided initial left space: %D\n",PetscAbs(svd->ninil));
93: }
94: PetscViewerASCIISetTab(viewer,tabs);
95: } else {
96: if (svd->ops->view) {
97: (*svd->ops->view)(svd,viewer);
98: }
99: }
100: PetscObjectTypeCompareAny((PetscObject)svd,&isshell,SVDCROSS,SVDCYCLIC,SVDPRIMME,"");
101: if (!isshell) {
102: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
103: if (!svd->V) { SVDGetBV(svd,&svd->V,NULL); }
104: BVView(svd->V,viewer);
105: if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
106: DSView(svd->ds,viewer);
107: PetscViewerPopFormat(viewer);
108: }
109: return(0);
110: }
112: /*@C
113: SVDReasonView - Displays the reason an SVD solve converged or diverged.
115: Collective on SVD
117: Parameter:
118: + svd - the singular value solver context
119: - viewer - the viewer to display the reason
121: Options Database Keys:
122: . -svd_converged_reason - print reason for convergence, and number of iterations
124: Level: intermediate
126: .seealso: SVDSetTolerances(), SVDGetIterationNumber()
127: @*/
128: PetscErrorCode SVDReasonView(SVD svd,PetscViewer viewer)
129: {
131: PetscBool isAscii;
134: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
135: if (isAscii) {
136: PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel);
137: if (svd->reason > 0) {
138: PetscViewerASCIIPrintf(viewer,"%s SVD solve converged (%D singular triplet%s) due to %s; iterations %D\n",((PetscObject)svd)->prefix?((PetscObject)svd)->prefix:"",svd->nconv,(svd->nconv>1)?"s":"",SVDConvergedReasons[svd->reason],svd->its);
139: } else {
140: PetscViewerASCIIPrintf(viewer,"%s SVD solve did not converge due to %s; iterations %D\n",((PetscObject)svd)->prefix?((PetscObject)svd)->prefix:"",SVDConvergedReasons[svd->reason],svd->its);
141: }
142: PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel);
143: }
144: return(0);
145: }
147: /*@
148: SVDReasonViewFromOptions - Processes command line options to determine if/how
149: the SVD converged reason is to be viewed.
151: Collective on SVD
153: Input Parameters:
154: . svd - the singular value solver context
156: Level: developer
157: @*/
158: PetscErrorCode SVDReasonViewFromOptions(SVD svd)
159: {
160: PetscErrorCode ierr;
161: PetscViewer viewer;
162: PetscBool flg;
163: static PetscBool incall = PETSC_FALSE;
164: PetscViewerFormat format;
167: if (incall) return(0);
168: incall = PETSC_TRUE;
169: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_converged_reason",&viewer,&format,&flg);
170: if (flg) {
171: PetscViewerPushFormat(viewer,format);
172: SVDReasonView(svd,viewer);
173: PetscViewerPopFormat(viewer);
174: PetscViewerDestroy(&viewer);
175: }
176: incall = PETSC_FALSE;
177: return(0);
178: }
180: static PetscErrorCode SVDErrorView_ASCII(SVD svd,SVDErrorType etype,PetscViewer viewer)
181: {
182: PetscReal error,sigma;
183: PetscInt i,j;
187: if (svd->nconv<svd->nsv) {
188: PetscViewerASCIIPrintf(viewer," Problem: less than %D singular values converged\n\n",svd->nsv);
189: return(0);
190: }
191: for (i=0;i<svd->nsv;i++) {
192: SVDComputeError(svd,i,etype,&error);
193: if (error>=5.0*svd->tol) {
194: PetscViewerASCIIPrintf(viewer," Problem: some of the first %D relative errors are higher than the tolerance\n\n",svd->nsv);
195: return(0);
196: }
197: }
198: PetscViewerASCIIPrintf(viewer," All requested singular values computed up to the required tolerance:");
199: for (i=0;i<=(svd->nsv-1)/8;i++) {
200: PetscViewerASCIIPrintf(viewer,"\n ");
201: for (j=0;j<PetscMin(8,svd->nsv-8*i);j++) {
202: SVDGetSingularTriplet(svd,8*i+j,&sigma,NULL,NULL);
203: PetscViewerASCIIPrintf(viewer,"%.5f",(double)sigma);
204: if (8*i+j+1<svd->nsv) { PetscViewerASCIIPrintf(viewer,", "); }
205: }
206: }
207: PetscViewerASCIIPrintf(viewer,"\n\n");
208: return(0);
209: }
211: static PetscErrorCode SVDErrorView_DETAIL(SVD svd,SVDErrorType etype,PetscViewer viewer)
212: {
214: PetscReal error,sigma;
215: PetscInt i;
216: #define EXLEN 30
217: char ex[EXLEN],sep[]=" ---------------------- --------------------\n";
220: if (!svd->nconv) return(0);
221: switch (etype) {
222: case SVD_ERROR_ABSOLUTE:
223: PetscSNPrintf(ex,EXLEN," absolute error");
224: break;
225: case SVD_ERROR_RELATIVE:
226: PetscSNPrintf(ex,EXLEN," relative error");
227: break;
228: }
229: PetscViewerASCIIPrintf(viewer,"%s sigma %s\n%s",sep,ex,sep);
230: for (i=0;i<svd->nconv;i++) {
231: SVDGetSingularTriplet(svd,i,&sigma,NULL,NULL);
232: SVDComputeError(svd,i,etype,&error);
233: PetscViewerASCIIPrintf(viewer," % 6f %12g\n",(double)sigma,(double)error);
234: }
235: PetscViewerASCIIPrintf(viewer,sep);
236: return(0);
237: }
239: static PetscErrorCode SVDErrorView_MATLAB(SVD svd,SVDErrorType etype,PetscViewer viewer)
240: {
242: PetscReal error;
243: PetscInt i;
244: const char *name;
247: PetscObjectGetName((PetscObject)svd,&name);
248: PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name);
249: for (i=0;i<svd->nconv;i++) {
250: SVDComputeError(svd,i,etype,&error);
251: PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)error);
252: }
253: PetscViewerASCIIPrintf(viewer,"];\n");
254: return(0);
255: }
257: /*@C
258: SVDErrorView - Displays the errors associated with the computed solution
259: (as well as the singular values).
261: Collective on SVD
263: Input Parameters:
264: + svd - the singular value solver context
265: . etype - error type
266: - viewer - optional visualization context
268: Options Database Key:
269: + -svd_error_absolute - print absolute errors of each singular triplet
270: - -svd_error_relative - print relative errors of each singular triplet
272: Notes:
273: By default, this function checks the error of all singular triplets and prints
274: the singular values if all of them are below the requested tolerance.
275: If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
276: singular values and corresponding errors is printed.
278: Level: intermediate
280: .seealso: SVDSolve(), SVDValuesView(), SVDVectorsView()
281: @*/
282: PetscErrorCode SVDErrorView(SVD svd,SVDErrorType etype,PetscViewer viewer)
283: {
284: PetscBool isascii;
285: PetscViewerFormat format;
286: PetscErrorCode ierr;
290: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
293: SVDCheckSolved(svd,1);
294: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
295: if (!isascii) return(0);
297: PetscViewerGetFormat(viewer,&format);
298: switch (format) {
299: case PETSC_VIEWER_DEFAULT:
300: case PETSC_VIEWER_ASCII_INFO:
301: SVDErrorView_ASCII(svd,etype,viewer);
302: break;
303: case PETSC_VIEWER_ASCII_INFO_DETAIL:
304: SVDErrorView_DETAIL(svd,etype,viewer);
305: break;
306: case PETSC_VIEWER_ASCII_MATLAB:
307: SVDErrorView_MATLAB(svd,etype,viewer);
308: break;
309: default:
310: PetscInfo1(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
311: }
312: return(0);
313: }
315: /*@
316: SVDErrorViewFromOptions - Processes command line options to determine if/how
317: the errors of the computed solution are to be viewed.
319: Collective on SVD
321: Input Parameters:
322: . svd - the singular value solver context
324: Level: developer
325: @*/
326: PetscErrorCode SVDErrorViewFromOptions(SVD svd)
327: {
328: PetscErrorCode ierr;
329: PetscViewer viewer;
330: PetscBool flg;
331: static PetscBool incall = PETSC_FALSE;
332: PetscViewerFormat format;
335: if (incall) return(0);
336: incall = PETSC_TRUE;
337: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_error_absolute",&viewer,&format,&flg);
338: if (flg) {
339: PetscViewerPushFormat(viewer,format);
340: SVDErrorView(svd,SVD_ERROR_ABSOLUTE,viewer);
341: PetscViewerPopFormat(viewer);
342: PetscViewerDestroy(&viewer);
343: }
344: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_error_relative",&viewer,&format,&flg);
345: if (flg) {
346: PetscViewerPushFormat(viewer,format);
347: SVDErrorView(svd,SVD_ERROR_RELATIVE,viewer);
348: PetscViewerPopFormat(viewer);
349: PetscViewerDestroy(&viewer);
350: }
351: incall = PETSC_FALSE;
352: return(0);
353: }
355: static PetscErrorCode SVDValuesView_DRAW(SVD svd,PetscViewer viewer)
356: {
358: PetscDraw draw;
359: PetscDrawSP drawsp;
360: PetscReal re,im=0.0;
361: PetscInt i;
364: if (!svd->nconv) return(0);
365: PetscViewerDrawGetDraw(viewer,0,&draw);
366: PetscDrawSetTitle(draw,"Computed singular values");
367: PetscDrawSPCreate(draw,1,&drawsp);
368: for (i=0;i<svd->nconv;i++) {
369: re = svd->sigma[svd->perm[i]];
370: PetscDrawSPAddPoint(drawsp,&re,&im);
371: }
372: PetscDrawSPDraw(drawsp,PETSC_TRUE);
373: PetscDrawSPSave(drawsp);
374: PetscDrawSPDestroy(&drawsp);
375: return(0);
376: }
378: static PetscErrorCode SVDValuesView_ASCII(SVD svd,PetscViewer viewer)
379: {
380: PetscInt i;
384: PetscViewerASCIIPrintf(viewer,"Singular values = \n");
385: for (i=0;i<svd->nconv;i++) {
386: PetscViewerASCIIPrintf(viewer," %.5f\n",(double)svd->sigma[svd->perm[i]]);
387: }
388: PetscViewerASCIIPrintf(viewer,"\n");
389: return(0);
390: }
392: static PetscErrorCode SVDValuesView_MATLAB(SVD svd,PetscViewer viewer)
393: {
395: PetscInt i;
396: const char *name;
399: PetscObjectGetName((PetscObject)svd,&name);
400: PetscViewerASCIIPrintf(viewer,"Sigma_%s = [\n",name);
401: for (i=0;i<svd->nconv;i++) {
402: PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)svd->sigma[svd->perm[i]]);
403: }
404: PetscViewerASCIIPrintf(viewer,"];\n");
405: return(0);
406: }
408: /*@C
409: SVDValuesView - Displays the computed singular values in a viewer.
411: Collective on SVD
413: Input Parameters:
414: + svd - the singular value solver context
415: - viewer - the viewer
417: Options Database Key:
418: . -svd_view_values - print computed singular values
420: Level: intermediate
422: .seealso: SVDSolve(), SVDVectorsView(), SVDErrorView()
423: @*/
424: PetscErrorCode SVDValuesView(SVD svd,PetscViewer viewer)
425: {
426: PetscBool isascii,isdraw;
427: PetscViewerFormat format;
428: PetscErrorCode ierr;
432: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
435: SVDCheckSolved(svd,1);
436: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
437: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
438: if (isdraw) {
439: SVDValuesView_DRAW(svd,viewer);
440: } else if (isascii) {
441: PetscViewerGetFormat(viewer,&format);
442: switch (format) {
443: case PETSC_VIEWER_DEFAULT:
444: case PETSC_VIEWER_ASCII_INFO:
445: case PETSC_VIEWER_ASCII_INFO_DETAIL:
446: SVDValuesView_ASCII(svd,viewer);
447: break;
448: case PETSC_VIEWER_ASCII_MATLAB:
449: SVDValuesView_MATLAB(svd,viewer);
450: break;
451: default:
452: PetscInfo1(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
453: }
454: }
455: return(0);
456: }
458: /*@
459: SVDValuesViewFromOptions - Processes command line options to determine if/how
460: the computed singular values are to be viewed.
462: Collective on SVD
464: Input Parameters:
465: . svd - the singular value solver context
467: Level: developer
468: @*/
469: PetscErrorCode SVDValuesViewFromOptions(SVD svd)
470: {
471: PetscErrorCode ierr;
472: PetscViewer viewer;
473: PetscBool flg;
474: static PetscBool incall = PETSC_FALSE;
475: PetscViewerFormat format;
478: if (incall) return(0);
479: incall = PETSC_TRUE;
480: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_view_values",&viewer,&format,&flg);
481: if (flg) {
482: PetscViewerPushFormat(viewer,format);
483: SVDValuesView(svd,viewer);
484: PetscViewerPopFormat(viewer);
485: PetscViewerDestroy(&viewer);
486: }
487: incall = PETSC_FALSE;
488: return(0);
489: }
491: /*@C
492: SVDVectorsView - Outputs computed singular vectors to a viewer.
494: Collective on SVD
496: Parameter:
497: + svd - the singular value solver context
498: - viewer - the viewer
500: Options Database Keys:
501: . -svd_view_vectors - output singular vectors
503: Level: intermediate
505: .seealso: SVDSolve(), SVDValuesView(), SVDErrorView()
506: @*/
507: PetscErrorCode SVDVectorsView(SVD svd,PetscViewer viewer)
508: {
510: PetscInt i,k;
511: Vec x;
512: #define NMLEN 30
513: char vname[NMLEN];
514: const char *ename;
518: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
521: SVDCheckSolved(svd,1);
522: if (svd->nconv) {
523: PetscObjectGetName((PetscObject)svd,&ename);
524: SVDComputeVectors(svd);
525: for (i=0;i<svd->nconv;i++) {
526: k = svd->perm[i];
527: PetscSNPrintf(vname,NMLEN,"V%d_%s",(int)i,ename);
528: BVGetColumn(svd->V,k,&x);
529: PetscObjectSetName((PetscObject)x,vname);
530: VecView(x,viewer);
531: BVRestoreColumn(svd->V,k,&x);
532: PetscSNPrintf(vname,NMLEN,"U%d_%s",(int)i,ename);
533: BVGetColumn(svd->U,k,&x);
534: PetscObjectSetName((PetscObject)x,vname);
535: VecView(x,viewer);
536: BVRestoreColumn(svd->U,k,&x);
537: }
538: }
539: return(0);
540: }
542: /*@
543: SVDVectorsViewFromOptions - Processes command line options to determine if/how
544: the computed singular vectors are to be viewed.
546: Collective on SVD
548: Input Parameters:
549: . svd - the singular value solver context
551: Level: developer
552: @*/
553: PetscErrorCode SVDVectorsViewFromOptions(SVD svd)
554: {
555: PetscErrorCode ierr;
556: PetscViewer viewer;
557: PetscBool flg = PETSC_FALSE;
558: static PetscBool incall = PETSC_FALSE;
559: PetscViewerFormat format;
562: if (incall) return(0);
563: incall = PETSC_TRUE;
564: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_view_vectors",&viewer,&format,&flg);
565: if (flg) {
566: PetscViewerPushFormat(viewer,format);
567: SVDVectorsView(svd,viewer);
568: PetscViewerPopFormat(viewer);
569: PetscViewerDestroy(&viewer);
570: }
571: incall = PETSC_FALSE;
572: return(0);
573: }