Actual source code: svdview.c
slepc-3.17.0 2022-03-31
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, 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>
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: EPSView()
43: @*/
44: PetscErrorCode SVDView(SVD svd,PetscViewer viewer)
45: {
46: const char *type=NULL;
47: PetscBool isascii,isshell;
50: if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)svd),&viewer);
54: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
55: if (isascii) {
56: PetscObjectPrintClassNamePrefixType((PetscObject)svd,viewer);
57: if (svd->ops->view) {
58: PetscViewerASCIIPushTab(viewer);
59: (*svd->ops->view)(svd,viewer);
60: PetscViewerASCIIPopTab(viewer);
61: }
62: if (svd->problem_type) {
63: switch (svd->problem_type) {
64: case SVD_STANDARD: type = "(standard) singular value problem"; break;
65: case SVD_GENERALIZED: type = "generalized singular value problem"; break;
66: }
67: } else type = "not yet set";
68: PetscViewerASCIIPrintf(viewer," problem type: %s\n",type);
69: PetscViewerASCIIPrintf(viewer," transpose mode: %s\n",svd->impltrans?"implicit":"explicit");
70: if (svd->which == SVD_LARGEST) PetscViewerASCIIPrintf(viewer," selected portion of the spectrum: largest\n");
71: else PetscViewerASCIIPrintf(viewer," selected portion of the spectrum: smallest\n");
72: PetscViewerASCIIPrintf(viewer," number of singular values (nsv): %" PetscInt_FMT "\n",svd->nsv);
73: PetscViewerASCIIPrintf(viewer," number of column vectors (ncv): %" PetscInt_FMT "\n",svd->ncv);
74: PetscViewerASCIIPrintf(viewer," maximum dimension of projected problem (mpd): %" PetscInt_FMT "\n",svd->mpd);
75: PetscViewerASCIIPrintf(viewer," maximum number of iterations: %" PetscInt_FMT "\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_NORM:
85: PetscViewerASCIIPrintf(viewer,"relative to the matrix norms\n");
86: PetscViewerASCIIPrintf(viewer," computed matrix norms: norm(A)=%g",(double)svd->nrma);
87: if (svd->isgeneralized) PetscViewerASCIIPrintf(viewer,", norm(B)=%g",(double)svd->nrmb);
88: PetscViewerASCIIPrintf(viewer,"\n");
89: break;
90: case SVD_CONV_MAXIT:
91: PetscViewerASCIIPrintf(viewer,"maximum number of iterations\n");break;
92: case SVD_CONV_USER:
93: PetscViewerASCIIPrintf(viewer,"user-defined\n");break;
94: }
95: PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
96: if (svd->nini) PetscViewerASCIIPrintf(viewer," dimension of user-provided initial space: %" PetscInt_FMT "\n",PetscAbs(svd->nini));
97: if (svd->ninil) PetscViewerASCIIPrintf(viewer," dimension of user-provided initial left space: %" PetscInt_FMT "\n",PetscAbs(svd->ninil));
98: } else {
99: if (svd->ops->view) (*svd->ops->view)(svd,viewer);
100: }
101: PetscObjectTypeCompareAny((PetscObject)svd,&isshell,SVDCROSS,SVDCYCLIC,SVDSCALAPACK,SVDELEMENTAL,SVDPRIMME,"");
102: if (!isshell) {
103: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
104: if (!svd->V) SVDGetBV(svd,&svd->V,NULL);
105: BVView(svd->V,viewer);
106: if (!svd->ds) SVDGetDS(svd,&svd->ds);
107: DSView(svd->ds,viewer);
108: PetscViewerPopFormat(viewer);
109: }
110: PetscFunctionReturn(0);
111: }
113: /*@C
114: SVDViewFromOptions - View from options
116: Collective on SVD
118: Input Parameters:
119: + svd - the singular value solver context
120: . obj - optional object
121: - name - command line option
123: Level: intermediate
125: .seealso: SVDView(), SVDCreate()
126: @*/
127: PetscErrorCode SVDViewFromOptions(SVD svd,PetscObject obj,const char name[])
128: {
130: PetscObjectViewFromOptions((PetscObject)svd,obj,name);
131: PetscFunctionReturn(0);
132: }
134: /*@C
135: SVDConvergedReasonView - Displays the reason an SVD solve converged or diverged.
137: Collective on svd
139: Input Parameters:
140: + svd - the singular value solver context
141: - viewer - the viewer to display the reason
143: Options Database Keys:
144: . -svd_converged_reason - print reason for convergence, and number of iterations
146: Note:
147: To change the format of the output call PetscViewerPushFormat(viewer,format) before
148: this call. Use PETSC_VIEWER_DEFAULT for the default, use PETSC_VIEWER_FAILED to only
149: display a reason if it fails. The latter can be set in the command line with
150: -svd_converged_reason ::failed
152: Level: intermediate
154: .seealso: SVDSetTolerances(), SVDGetIterationNumber(), SVDConvergedReasonViewFromOptions()
155: @*/
156: PetscErrorCode SVDConvergedReasonView(SVD svd,PetscViewer viewer)
157: {
158: PetscBool isAscii;
159: PetscViewerFormat format;
161: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
162: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
163: if (isAscii) {
164: PetscViewerGetFormat(viewer,&format);
165: PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel);
166: if (svd->reason > 0 && format != PETSC_VIEWER_FAILED) PetscViewerASCIIPrintf(viewer,"%s SVD solve converged (%" PetscInt_FMT " singular triplet%s) due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)svd)->prefix?((PetscObject)svd)->prefix:"",svd->nconv,(svd->nconv>1)?"s":"",SVDConvergedReasons[svd->reason],svd->its);
167: else if (svd->reason <= 0) PetscViewerASCIIPrintf(viewer,"%s SVD solve did not converge due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)svd)->prefix?((PetscObject)svd)->prefix:"",SVDConvergedReasons[svd->reason],svd->its);
168: PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel);
169: }
170: PetscFunctionReturn(0);
171: }
173: /*@
174: SVDConvergedReasonViewFromOptions - Processes command line options to determine if/how
175: the SVD converged reason is to be viewed.
177: Collective on svd
179: Input Parameter:
180: . svd - the singular value solver context
182: Level: developer
184: .seealso: SVDConvergedReasonView()
185: @*/
186: PetscErrorCode SVDConvergedReasonViewFromOptions(SVD svd)
187: {
188: PetscViewer viewer;
189: PetscBool flg;
190: static PetscBool incall = PETSC_FALSE;
191: PetscViewerFormat format;
193: if (incall) PetscFunctionReturn(0);
194: incall = PETSC_TRUE;
195: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_converged_reason",&viewer,&format,&flg);
196: if (flg) {
197: PetscViewerPushFormat(viewer,format);
198: SVDConvergedReasonView(svd,viewer);
199: PetscViewerPopFormat(viewer);
200: PetscViewerDestroy(&viewer);
201: }
202: incall = PETSC_FALSE;
203: PetscFunctionReturn(0);
204: }
206: static PetscErrorCode SVDErrorView_ASCII(SVD svd,SVDErrorType etype,PetscViewer viewer)
207: {
208: PetscReal error,sigma;
209: PetscInt i,j;
211: if (svd->nconv<svd->nsv) {
212: PetscViewerASCIIPrintf(viewer," Problem: less than %" PetscInt_FMT " singular values converged\n\n",svd->nsv);
213: PetscFunctionReturn(0);
214: }
215: for (i=0;i<svd->nsv;i++) {
216: SVDComputeError(svd,i,etype,&error);
217: if (error>=5.0*svd->tol) {
218: PetscViewerASCIIPrintf(viewer," Problem: some of the first %" PetscInt_FMT " relative errors are higher than the tolerance\n\n",svd->nsv);
219: PetscFunctionReturn(0);
220: }
221: }
222: PetscViewerASCIIPrintf(viewer," All requested singular values computed up to the required tolerance:");
223: for (i=0;i<=(svd->nsv-1)/8;i++) {
224: PetscViewerASCIIPrintf(viewer,"\n ");
225: for (j=0;j<PetscMin(8,svd->nsv-8*i);j++) {
226: SVDGetSingularTriplet(svd,8*i+j,&sigma,NULL,NULL);
227: PetscViewerASCIIPrintf(viewer,"%.5f",(double)sigma);
228: if (8*i+j+1<svd->nsv) PetscViewerASCIIPrintf(viewer,", ");
229: }
230: }
231: PetscViewerASCIIPrintf(viewer,"\n\n");
232: PetscFunctionReturn(0);
233: }
235: static PetscErrorCode SVDErrorView_DETAIL(SVD svd,SVDErrorType etype,PetscViewer viewer)
236: {
237: PetscReal error,sigma;
238: PetscInt i;
239: char ex[30],sep[]=" ---------------------- --------------------\n";
241: if (!svd->nconv) PetscFunctionReturn(0);
242: switch (etype) {
243: case SVD_ERROR_ABSOLUTE:
244: PetscSNPrintf(ex,sizeof(ex)," absolute error");
245: break;
246: case SVD_ERROR_RELATIVE:
247: PetscSNPrintf(ex,sizeof(ex)," relative error");
248: break;
249: case SVD_ERROR_NORM:
250: if (svd->isgeneralized) PetscSNPrintf(ex,sizeof(ex)," ||r||/||[A;B]||");
251: else PetscSNPrintf(ex,sizeof(ex)," ||r||/||A||");
252: break;
253: }
254: PetscViewerASCIIPrintf(viewer,"%s sigma %s\n%s",sep,ex,sep);
255: for (i=0;i<svd->nconv;i++) {
256: SVDGetSingularTriplet(svd,i,&sigma,NULL,NULL);
257: SVDComputeError(svd,i,etype,&error);
258: PetscViewerASCIIPrintf(viewer," % 6f %12g\n",(double)sigma,(double)error);
259: }
260: PetscViewerASCIIPrintf(viewer,"%s",sep);
261: PetscFunctionReturn(0);
262: }
264: static PetscErrorCode SVDErrorView_MATLAB(SVD svd,SVDErrorType etype,PetscViewer viewer)
265: {
266: PetscReal error;
267: PetscInt i;
268: const char *name;
270: PetscObjectGetName((PetscObject)svd,&name);
271: PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name);
272: for (i=0;i<svd->nconv;i++) {
273: SVDComputeError(svd,i,etype,&error);
274: PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)error);
275: }
276: PetscViewerASCIIPrintf(viewer,"];\n");
277: PetscFunctionReturn(0);
278: }
280: /*@C
281: SVDErrorView - Displays the errors associated with the computed solution
282: (as well as the singular values).
284: Collective on svd
286: Input Parameters:
287: + svd - the singular value solver context
288: . etype - error type
289: - viewer - optional visualization context
291: Options Database Keys:
292: + -svd_error_absolute - print absolute errors of each singular triplet
293: . -svd_error_relative - print relative errors of each singular triplet
294: - -svd_error_norm - print errors relative to the matrix norms of each singular triplet
296: Notes:
297: By default, this function checks the error of all singular triplets and prints
298: the singular values if all of them are below the requested tolerance.
299: If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
300: singular values and corresponding errors is printed.
302: Level: intermediate
304: .seealso: SVDSolve(), SVDValuesView(), SVDVectorsView()
305: @*/
306: PetscErrorCode SVDErrorView(SVD svd,SVDErrorType etype,PetscViewer viewer)
307: {
308: PetscBool isascii;
309: PetscViewerFormat format;
312: if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)svd),&viewer);
315: SVDCheckSolved(svd,1);
316: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
317: if (!isascii) PetscFunctionReturn(0);
319: PetscViewerGetFormat(viewer,&format);
320: switch (format) {
321: case PETSC_VIEWER_DEFAULT:
322: case PETSC_VIEWER_ASCII_INFO:
323: SVDErrorView_ASCII(svd,etype,viewer);
324: break;
325: case PETSC_VIEWER_ASCII_INFO_DETAIL:
326: SVDErrorView_DETAIL(svd,etype,viewer);
327: break;
328: case PETSC_VIEWER_ASCII_MATLAB:
329: SVDErrorView_MATLAB(svd,etype,viewer);
330: break;
331: default:
332: PetscInfo(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
333: }
334: PetscFunctionReturn(0);
335: }
337: /*@
338: SVDErrorViewFromOptions - Processes command line options to determine if/how
339: the errors of the computed solution are to be viewed.
341: Collective on svd
343: Input Parameter:
344: . svd - the singular value solver context
346: Level: developer
348: .seealso: SVDErrorView()
349: @*/
350: PetscErrorCode SVDErrorViewFromOptions(SVD svd)
351: {
352: PetscViewer viewer;
353: PetscBool flg;
354: static PetscBool incall = PETSC_FALSE;
355: PetscViewerFormat format;
357: if (incall) PetscFunctionReturn(0);
358: incall = PETSC_TRUE;
359: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_error_absolute",&viewer,&format,&flg);
360: if (flg) {
361: PetscViewerPushFormat(viewer,format);
362: SVDErrorView(svd,SVD_ERROR_ABSOLUTE,viewer);
363: PetscViewerPopFormat(viewer);
364: PetscViewerDestroy(&viewer);
365: }
366: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_error_relative",&viewer,&format,&flg);
367: if (flg) {
368: PetscViewerPushFormat(viewer,format);
369: SVDErrorView(svd,SVD_ERROR_RELATIVE,viewer);
370: PetscViewerPopFormat(viewer);
371: PetscViewerDestroy(&viewer);
372: }
373: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_error_norm",&viewer,&format,&flg);
374: if (flg) {
375: PetscViewerPushFormat(viewer,format);
376: SVDErrorView(svd,SVD_ERROR_NORM,viewer);
377: PetscViewerPopFormat(viewer);
378: PetscViewerDestroy(&viewer);
379: }
380: incall = PETSC_FALSE;
381: PetscFunctionReturn(0);
382: }
384: static PetscErrorCode SVDValuesView_DRAW(SVD svd,PetscViewer viewer)
385: {
386: PetscDraw draw;
387: PetscDrawSP drawsp;
388: PetscReal re,im=0.0;
389: PetscInt i;
391: if (!svd->nconv) PetscFunctionReturn(0);
392: PetscViewerDrawGetDraw(viewer,0,&draw);
393: PetscDrawSetTitle(draw,"Computed singular values");
394: PetscDrawSPCreate(draw,1,&drawsp);
395: for (i=0;i<svd->nconv;i++) {
396: re = svd->sigma[svd->perm[i]];
397: PetscDrawSPAddPoint(drawsp,&re,&im);
398: }
399: PetscDrawSPDraw(drawsp,PETSC_TRUE);
400: PetscDrawSPSave(drawsp);
401: PetscDrawSPDestroy(&drawsp);
402: PetscFunctionReturn(0);
403: }
405: static PetscErrorCode SVDValuesView_BINARY(SVD svd,PetscViewer viewer)
406: {
407: PetscInt i,k;
408: PetscReal *sv;
410: PetscMalloc1(svd->nconv,&sv);
411: for (i=0;i<svd->nconv;i++) {
412: k = svd->perm[i];
413: sv[i] = svd->sigma[k];
414: }
415: PetscViewerBinaryWrite(viewer,sv,svd->nconv,PETSC_REAL);
416: PetscFree(sv);
417: PetscFunctionReturn(0);
418: }
420: #if defined(PETSC_HAVE_HDF5)
421: static PetscErrorCode SVDValuesView_HDF5(SVD svd,PetscViewer viewer)
422: {
423: PetscInt i,k,n,N;
424: PetscMPIInt rank;
425: Vec v;
426: char vname[30];
427: const char *ename;
429: MPI_Comm_rank(PetscObjectComm((PetscObject)svd),&rank);
430: N = svd->nconv;
431: n = rank? 0: N;
432: /* create a vector containing the singular values */
433: VecCreateMPI(PetscObjectComm((PetscObject)svd),n,N,&v);
434: PetscObjectGetName((PetscObject)svd,&ename);
435: PetscSNPrintf(vname,sizeof(vname),"sigma_%s",ename);
436: PetscObjectSetName((PetscObject)v,vname);
437: if (!rank) {
438: for (i=0;i<svd->nconv;i++) {
439: k = svd->perm[i];
440: VecSetValue(v,i,svd->sigma[k],INSERT_VALUES);
441: }
442: }
443: VecAssemblyBegin(v);
444: VecAssemblyEnd(v);
445: VecView(v,viewer);
446: VecDestroy(&v);
447: PetscFunctionReturn(0);
448: }
449: #endif
451: static PetscErrorCode SVDValuesView_ASCII(SVD svd,PetscViewer viewer)
452: {
453: PetscInt i;
455: PetscViewerASCIIPrintf(viewer,"Singular values = \n");
456: for (i=0;i<svd->nconv;i++) PetscViewerASCIIPrintf(viewer," %.5f\n",(double)svd->sigma[svd->perm[i]]);
457: PetscViewerASCIIPrintf(viewer,"\n");
458: PetscFunctionReturn(0);
459: }
461: static PetscErrorCode SVDValuesView_MATLAB(SVD svd,PetscViewer viewer)
462: {
463: PetscInt i;
464: const char *name;
466: PetscObjectGetName((PetscObject)svd,&name);
467: PetscViewerASCIIPrintf(viewer,"Sigma_%s = [\n",name);
468: for (i=0;i<svd->nconv;i++) PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)svd->sigma[svd->perm[i]]);
469: PetscViewerASCIIPrintf(viewer,"];\n");
470: PetscFunctionReturn(0);
471: }
473: /*@C
474: SVDValuesView - Displays the computed singular values in a viewer.
476: Collective on svd
478: Input Parameters:
479: + svd - the singular value solver context
480: - viewer - the viewer
482: Options Database Key:
483: . -svd_view_values - print computed singular values
485: Level: intermediate
487: .seealso: SVDSolve(), SVDVectorsView(), SVDErrorView()
488: @*/
489: PetscErrorCode SVDValuesView(SVD svd,PetscViewer viewer)
490: {
491: PetscBool isascii,isdraw,isbinary;
492: PetscViewerFormat format;
493: #if defined(PETSC_HAVE_HDF5)
494: PetscBool ishdf5;
495: #endif
498: if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)svd),&viewer);
501: SVDCheckSolved(svd,1);
502: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
503: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
504: #if defined(PETSC_HAVE_HDF5)
505: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
506: #endif
507: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
508: if (isdraw) SVDValuesView_DRAW(svd,viewer);
509: else if (isbinary) SVDValuesView_BINARY(svd,viewer);
510: #if defined(PETSC_HAVE_HDF5)
511: else if (ishdf5) SVDValuesView_HDF5(svd,viewer);
512: #endif
513: else if (isascii) {
514: PetscViewerGetFormat(viewer,&format);
515: switch (format) {
516: case PETSC_VIEWER_DEFAULT:
517: case PETSC_VIEWER_ASCII_INFO:
518: case PETSC_VIEWER_ASCII_INFO_DETAIL:
519: SVDValuesView_ASCII(svd,viewer);
520: break;
521: case PETSC_VIEWER_ASCII_MATLAB:
522: SVDValuesView_MATLAB(svd,viewer);
523: break;
524: default:
525: PetscInfo(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
526: }
527: }
528: PetscFunctionReturn(0);
529: }
531: /*@
532: SVDValuesViewFromOptions - Processes command line options to determine if/how
533: the computed singular values are to be viewed.
535: Collective on svd
537: Input Parameter:
538: . svd - the singular value solver context
540: Level: developer
542: .seealso: SVDValuesView()
543: @*/
544: PetscErrorCode SVDValuesViewFromOptions(SVD svd)
545: {
546: PetscViewer viewer;
547: PetscBool flg;
548: static PetscBool incall = PETSC_FALSE;
549: PetscViewerFormat format;
551: if (incall) PetscFunctionReturn(0);
552: incall = PETSC_TRUE;
553: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_view_values",&viewer,&format,&flg);
554: if (flg) {
555: PetscViewerPushFormat(viewer,format);
556: SVDValuesView(svd,viewer);
557: PetscViewerPopFormat(viewer);
558: PetscViewerDestroy(&viewer);
559: }
560: incall = PETSC_FALSE;
561: PetscFunctionReturn(0);
562: }
564: /*@C
565: SVDVectorsView - Outputs computed singular vectors to a viewer.
567: Collective on svd
569: Input Parameters:
570: + svd - the singular value solver context
571: - viewer - the viewer
573: Options Database Key:
574: . -svd_view_vectors - output singular vectors
576: Note:
577: Right and left singular vectors are interleaved, that is, the vectors are
578: output in the following order V0, U0, V1, U1, V2, U2, ...
580: Level: intermediate
582: .seealso: SVDSolve(), SVDValuesView(), SVDErrorView()
583: @*/
584: PetscErrorCode SVDVectorsView(SVD svd,PetscViewer viewer)
585: {
586: PetscInt i,k;
587: Vec x;
588: char vname[30];
589: const char *ename;
592: if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)svd),&viewer);
595: SVDCheckSolved(svd,1);
596: if (svd->nconv) {
597: PetscObjectGetName((PetscObject)svd,&ename);
598: SVDComputeVectors(svd);
599: for (i=0;i<svd->nconv;i++) {
600: k = svd->perm[i];
601: PetscSNPrintf(vname,sizeof(vname),"V%" PetscInt_FMT "_%s",i,ename);
602: BVGetColumn(svd->V,k,&x);
603: PetscObjectSetName((PetscObject)x,vname);
604: VecView(x,viewer);
605: BVRestoreColumn(svd->V,k,&x);
606: PetscSNPrintf(vname,sizeof(vname),"U%" PetscInt_FMT "_%s",i,ename);
607: BVGetColumn(svd->U,k,&x);
608: PetscObjectSetName((PetscObject)x,vname);
609: VecView(x,viewer);
610: BVRestoreColumn(svd->U,k,&x);
611: }
612: }
613: PetscFunctionReturn(0);
614: }
616: /*@
617: SVDVectorsViewFromOptions - Processes command line options to determine if/how
618: the computed singular vectors are to be viewed.
620: Collective on svd
622: Input Parameter:
623: . svd - the singular value solver context
625: Level: developer
627: .seealso: SVDVectorsView()
628: @*/
629: PetscErrorCode SVDVectorsViewFromOptions(SVD svd)
630: {
631: PetscViewer viewer;
632: PetscBool flg = PETSC_FALSE;
633: static PetscBool incall = PETSC_FALSE;
634: PetscViewerFormat format;
636: if (incall) PetscFunctionReturn(0);
637: incall = PETSC_TRUE;
638: PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_view_vectors",&viewer,&format,&flg);
639: if (flg) {
640: PetscViewerPushFormat(viewer,format);
641: SVDVectorsView(svd,viewer);
642: PetscViewerPopFormat(viewer);
643: PetscViewerDestroy(&viewer);
644: }
645: incall = PETSC_FALSE;
646: PetscFunctionReturn(0);
647: }