Date: 2022-11-02T11:47:08+00:00

Actual source code: svdview.c
slepc-3.18.1 2022-11-02
Report Typos and Errors

      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:     PetscViewerASCIIPushTab(viewer);
     58:     PetscTryTypeMethod(svd,view,viewer);
     59:     PetscViewerASCIIPopTab(viewer);
     60:     if (svd->problem_type) {
     61:       switch (svd->problem_type) {
     62:         case SVD_STANDARD:    type = "(standard) singular value problem"; break;
     63:         case SVD_GENERALIZED: type = "generalized singular value problem"; break;
     64:         case SVD_HYPERBOLIC:  type = "hyperbolic singular value problem"; break;
     65:       }
     66:     } else type = "not yet set";
     67:     PetscViewerASCIIPrintf(viewer,"  problem type: %s\n",type);
     68:     PetscViewerASCIIPrintf(viewer,"  transpose mode: %s\n",svd->impltrans?"implicit":"explicit");
     69:     if (svd->which == SVD_LARGEST) PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: largest\n");
     70:     else PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: smallest\n");
     71:     PetscViewerASCIIPrintf(viewer,"  number of singular values (nsv): %" PetscInt_FMT "\n",svd->nsv);
     72:     PetscViewerASCIIPrintf(viewer,"  number of column vectors (ncv): %" PetscInt_FMT "\n",svd->ncv);
     73:     PetscViewerASCIIPrintf(viewer,"  maximum dimension of projected problem (mpd): %" PetscInt_FMT "\n",svd->mpd);
     74:     PetscViewerASCIIPrintf(viewer,"  maximum number of iterations: %" PetscInt_FMT "\n",svd->max_it);
     75:     PetscViewerASCIIPrintf(viewer,"  tolerance: %g\n",(double)svd->tol);
     76:     PetscViewerASCIIPrintf(viewer,"  convergence test: ");
     77:     PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);
     78:     switch (svd->conv) {
     79:     case SVD_CONV_ABS:
     80:       PetscViewerASCIIPrintf(viewer,"absolute\n");break;
     81:     case SVD_CONV_REL:
     82:       PetscViewerASCIIPrintf(viewer,"relative to the singular value\n");break;
     83:     case SVD_CONV_NORM:
     84:       PetscViewerASCIIPrintf(viewer,"relative to the matrix norms\n");
     85:       PetscViewerASCIIPrintf(viewer,"  computed matrix norms: norm(A)=%g",(double)svd->nrma);
     86:       if (svd->isgeneralized) PetscViewerASCIIPrintf(viewer,", norm(B)=%g",(double)svd->nrmb);
     87:       PetscViewerASCIIPrintf(viewer,"\n");
     88:       break;
     89:     case SVD_CONV_MAXIT:
     90:       PetscViewerASCIIPrintf(viewer,"maximum number of iterations\n");break;
     91:     case SVD_CONV_USER:
     92:       PetscViewerASCIIPrintf(viewer,"user-defined\n");break;
     93:     }
     94:     PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
     95:     if (svd->nini) PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial space: %" PetscInt_FMT "\n",PetscAbs(svd->nini));
     96:     if (svd->ninil) PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial left space: %" PetscInt_FMT "\n",PetscAbs(svd->ninil));
     97:   } else PetscTryTypeMethod(svd,view,viewer);
     98:   PetscObjectTypeCompareAny((PetscObject)svd,&isshell,SVDCROSS,SVDCYCLIC,SVDSCALAPACK,SVDELEMENTAL,SVDPRIMME,"");
     99:   if (!isshell) {
    100:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
    101:     if (!svd->V) SVDGetBV(svd,&svd->V,NULL);
    102:     BVView(svd->V,viewer);
    103:     if (!svd->ds) SVDGetDS(svd,&svd->ds);
    104:     DSView(svd->ds,viewer);
    105:     PetscViewerPopFormat(viewer);
    106:   }
    107:   return 0;
    108: }

    110: /*@C
    111:    SVDViewFromOptions - View from options

    113:    Collective on SVD

    115:    Input Parameters:
    116: +  svd  - the singular value solver context
    117: .  obj  - optional object
    118: -  name - command line option

    120:    Level: intermediate

    122: .seealso: SVDView(), SVDCreate()
    123: @*/
    124: PetscErrorCode SVDViewFromOptions(SVD svd,PetscObject obj,const char name[])
    125: {
    127:   PetscObjectViewFromOptions((PetscObject)svd,obj,name);
    128:   return 0;
    129: }

    131: /*@C
    132:    SVDConvergedReasonView - Displays the reason an SVD solve converged or diverged.

    134:    Collective on svd

    136:    Input Parameters:
    137: +  svd - the singular value solver context
    138: -  viewer - the viewer to display the reason

    140:    Options Database Keys:
    141: .  -svd_converged_reason - print reason for convergence, and number of iterations

    143:    Note:
    144:    To change the format of the output call PetscViewerPushFormat(viewer,format) before
    145:    this call. Use PETSC_VIEWER_DEFAULT for the default, use PETSC_VIEWER_FAILED to only
    146:    display a reason if it fails. The latter can be set in the command line with
    147:    -svd_converged_reason ::failed

    149:    Level: intermediate

    151: .seealso: SVDSetTolerances(), SVDGetIterationNumber(), SVDConvergedReasonViewFromOptions()
    152: @*/
    153: PetscErrorCode SVDConvergedReasonView(SVD svd,PetscViewer viewer)
    154: {
    155:   PetscBool         isAscii;
    156:   PetscViewerFormat format;

    158:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
    159:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
    160:   if (isAscii) {
    161:     PetscViewerGetFormat(viewer,&format);
    162:     PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel);
    163:     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);
    164:     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);
    165:     PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel);
    166:   }
    167:   return 0;
    168: }

    170: /*@
    171:    SVDConvergedReasonViewFromOptions - Processes command line options to determine if/how
    172:    the SVD converged reason is to be viewed.

    174:    Collective on svd

    176:    Input Parameter:
    177: .  svd - the singular value solver context

    179:    Level: developer

    181: .seealso: SVDConvergedReasonView()
    182: @*/
    183: PetscErrorCode SVDConvergedReasonViewFromOptions(SVD svd)
    184: {
    185:   PetscViewer       viewer;
    186:   PetscBool         flg;
    187:   static PetscBool  incall = PETSC_FALSE;
    188:   PetscViewerFormat format;

    190:   if (incall) return 0;
    191:   incall = PETSC_TRUE;
    192:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_converged_reason",&viewer,&format,&flg);
    193:   if (flg) {
    194:     PetscViewerPushFormat(viewer,format);
    195:     SVDConvergedReasonView(svd,viewer);
    196:     PetscViewerPopFormat(viewer);
    197:     PetscViewerDestroy(&viewer);
    198:   }
    199:   incall = PETSC_FALSE;
    200:   return 0;
    201: }

    203: static PetscErrorCode SVDErrorView_ASCII(SVD svd,SVDErrorType etype,PetscViewer viewer)
    204: {
    205:   PetscReal      error,sigma;
    206:   PetscInt       i,j;

    208:   if (svd->nconv<svd->nsv) {
    209:     PetscViewerASCIIPrintf(viewer," Problem: less than %" PetscInt_FMT " singular values converged\n\n",svd->nsv);
    210:     return 0;
    211:   }
    212:   for (i=0;i<svd->nsv;i++) {
    213:     SVDComputeError(svd,i,etype,&error);
    214:     if (error>=5.0*svd->tol) {
    215:       PetscViewerASCIIPrintf(viewer," Problem: some of the first %" PetscInt_FMT " relative errors are higher than the tolerance\n\n",svd->nsv);
    216:       return 0;
    217:     }
    218:   }
    219:   PetscViewerASCIIPrintf(viewer," All requested %ssingular values computed up to the required tolerance:",svd->isgeneralized?"generalized ":"");
    220:   for (i=0;i<=(svd->nsv-1)/8;i++) {
    221:     PetscViewerASCIIPrintf(viewer,"\n     ");
    222:     for (j=0;j<PetscMin(8,svd->nsv-8*i);j++) {
    223:       SVDGetSingularTriplet(svd,8*i+j,&sigma,NULL,NULL);
    224:       PetscViewerASCIIPrintf(viewer,"%.5f",(double)sigma);
    225:       if (8*i+j+1<svd->nsv) PetscViewerASCIIPrintf(viewer,", ");
    226:     }
    227:   }
    228:   PetscViewerASCIIPrintf(viewer,"\n\n");
    229:   return 0;
    230: }

    232: static PetscErrorCode SVDErrorView_DETAIL(SVD svd,SVDErrorType etype,PetscViewer viewer)
    233: {
    234:   PetscReal      error,sigma;
    235:   PetscInt       i;
    236:   char           ex[30],sep[]=" ---------------------- --------------------\n";

    238:   if (!svd->nconv) return 0;
    239:   switch (etype) {
    240:     case SVD_ERROR_ABSOLUTE:
    241:       PetscSNPrintf(ex,sizeof(ex)," absolute error");
    242:       break;
    243:     case SVD_ERROR_RELATIVE:
    244:       PetscSNPrintf(ex,sizeof(ex)," relative error");
    245:       break;
    246:     case SVD_ERROR_NORM:
    247:       if (svd->isgeneralized) PetscSNPrintf(ex,sizeof(ex)," ||r||/||[A;B]||");
    248:       else PetscSNPrintf(ex,sizeof(ex),"  ||r||/||A||");
    249:       break;
    250:   }
    251:   PetscViewerASCIIPrintf(viewer,"%s          sigma           %s\n%s",sep,ex,sep);
    252:   for (i=0;i<svd->nconv;i++) {
    253:     SVDGetSingularTriplet(svd,i,&sigma,NULL,NULL);
    254:     SVDComputeError(svd,i,etype,&error);
    255:     PetscViewerASCIIPrintf(viewer,"       % 6f          %12g\n",(double)sigma,(double)error);
    256:   }
    257:   PetscViewerASCIIPrintf(viewer,"%s",sep);
    258:   return 0;
    259: }

    261: static PetscErrorCode SVDErrorView_MATLAB(SVD svd,SVDErrorType etype,PetscViewer viewer)
    262: {
    263:   PetscReal      error;
    264:   PetscInt       i;
    265:   const char     *name;

    267:   PetscObjectGetName((PetscObject)svd,&name);
    268:   PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name);
    269:   for (i=0;i<svd->nconv;i++) {
    270:     SVDComputeError(svd,i,etype,&error);
    271:     PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)error);
    272:   }
    273:   PetscViewerASCIIPrintf(viewer,"];\n");
    274:   return 0;
    275: }

    277: /*@C
    278:    SVDErrorView - Displays the errors associated with the computed solution
    279:    (as well as the singular values).

    281:    Collective on svd

    283:    Input Parameters:
    284: +  svd    - the singular value solver context
    285: .  etype  - error type
    286: -  viewer - optional visualization context

    288:    Options Database Keys:
    289: +  -svd_error_absolute - print absolute errors of each singular triplet
    290: .  -svd_error_relative - print relative errors of each singular triplet
    291: -  -svd_error_norm     - print errors relative to the matrix norms of each singular triplet

    293:    Notes:
    294:    By default, this function checks the error of all singular triplets and prints
    295:    the singular values if all of them are below the requested tolerance.
    296:    If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
    297:    singular values and corresponding errors is printed.

    299:    Level: intermediate

    301: .seealso: SVDSolve(), SVDValuesView(), SVDVectorsView()
    302: @*/
    303: PetscErrorCode SVDErrorView(SVD svd,SVDErrorType etype,PetscViewer viewer)
    304: {
    305:   PetscBool         isascii;
    306:   PetscViewerFormat format;

    309:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)svd),&viewer);
    312:   SVDCheckSolved(svd,1);
    313:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    314:   if (!isascii) return 0;

    316:   PetscViewerGetFormat(viewer,&format);
    317:   switch (format) {
    318:     case PETSC_VIEWER_DEFAULT:
    319:     case PETSC_VIEWER_ASCII_INFO:
    320:       SVDErrorView_ASCII(svd,etype,viewer);
    321:       break;
    322:     case PETSC_VIEWER_ASCII_INFO_DETAIL:
    323:       SVDErrorView_DETAIL(svd,etype,viewer);
    324:       break;
    325:     case PETSC_VIEWER_ASCII_MATLAB:
    326:       SVDErrorView_MATLAB(svd,etype,viewer);
    327:       break;
    328:     default:
    329:       PetscInfo(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
    330:   }
    331:   return 0;
    332: }

    334: /*@
    335:    SVDErrorViewFromOptions - Processes command line options to determine if/how
    336:    the errors of the computed solution are to be viewed.

    338:    Collective on svd

    340:    Input Parameter:
    341: .  svd - the singular value solver context

    343:    Level: developer

    345: .seealso: SVDErrorView()
    346: @*/
    347: PetscErrorCode SVDErrorViewFromOptions(SVD svd)
    348: {
    349:   PetscViewer       viewer;
    350:   PetscBool         flg;
    351:   static PetscBool  incall = PETSC_FALSE;
    352:   PetscViewerFormat format;

    354:   if (incall) return 0;
    355:   incall = PETSC_TRUE;
    356:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_error_absolute",&viewer,&format,&flg);
    357:   if (flg) {
    358:     PetscViewerPushFormat(viewer,format);
    359:     SVDErrorView(svd,SVD_ERROR_ABSOLUTE,viewer);
    360:     PetscViewerPopFormat(viewer);
    361:     PetscViewerDestroy(&viewer);
    362:   }
    363:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_error_relative",&viewer,&format,&flg);
    364:   if (flg) {
    365:     PetscViewerPushFormat(viewer,format);
    366:     SVDErrorView(svd,SVD_ERROR_RELATIVE,viewer);
    367:     PetscViewerPopFormat(viewer);
    368:     PetscViewerDestroy(&viewer);
    369:   }
    370:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_error_norm",&viewer,&format,&flg);
    371:   if (flg) {
    372:     PetscViewerPushFormat(viewer,format);
    373:     SVDErrorView(svd,SVD_ERROR_NORM,viewer);
    374:     PetscViewerPopFormat(viewer);
    375:     PetscViewerDestroy(&viewer);
    376:   }
    377:   incall = PETSC_FALSE;
    378:   return 0;
    379: }

    381: static PetscErrorCode SVDValuesView_DRAW(SVD svd,PetscViewer viewer)
    382: {
    383:   PetscDraw      draw;
    384:   PetscDrawSP    drawsp;
    385:   PetscReal      re,im=0.0;
    386:   PetscInt       i;

    388:   if (!svd->nconv) return 0;
    389:   PetscViewerDrawGetDraw(viewer,0,&draw);
    390:   PetscDrawSetTitle(draw,"Computed singular values");
    391:   PetscDrawSPCreate(draw,1,&drawsp);
    392:   for (i=0;i<svd->nconv;i++) {
    393:     re = svd->sigma[svd->perm[i]];
    394:     PetscDrawSPAddPoint(drawsp,&re,&im);
    395:   }
    396:   PetscDrawSPDraw(drawsp,PETSC_TRUE);
    397:   PetscDrawSPSave(drawsp);
    398:   PetscDrawSPDestroy(&drawsp);
    399:   return 0;
    400: }

    402: static PetscErrorCode SVDValuesView_BINARY(SVD svd,PetscViewer viewer)
    403: {
    404:   PetscInt       i,k;
    405:   PetscReal      *sv;

    407:   PetscMalloc1(svd->nconv,&sv);
    408:   for (i=0;i<svd->nconv;i++) {
    409:     k = svd->perm[i];
    410:     sv[i] = svd->sigma[k];
    411:   }
    412:   PetscViewerBinaryWrite(viewer,sv,svd->nconv,PETSC_REAL);
    413:   PetscFree(sv);
    414:   return 0;
    415: }

    417: #if defined(PETSC_HAVE_HDF5)
    418: static PetscErrorCode SVDValuesView_HDF5(SVD svd,PetscViewer viewer)
    419: {
    420:   PetscInt       i,k,n,N;
    421:   PetscMPIInt    rank;
    422:   Vec            v;
    423:   char           vname[30];
    424:   const char     *ename;

    426:   MPI_Comm_rank(PetscObjectComm((PetscObject)svd),&rank);
    427:   N = svd->nconv;
    428:   n = rank? 0: N;
    429:   /* create a vector containing the singular values */
    430:   VecCreateMPI(PetscObjectComm((PetscObject)svd),n,N,&v);
    431:   PetscObjectGetName((PetscObject)svd,&ename);
    432:   PetscSNPrintf(vname,sizeof(vname),"sigma_%s",ename);
    433:   PetscObjectSetName((PetscObject)v,vname);
    434:   if (!rank) {
    435:     for (i=0;i<svd->nconv;i++) {
    436:       k = svd->perm[i];
    437:       VecSetValue(v,i,svd->sigma[k],INSERT_VALUES);
    438:     }
    439:   }
    440:   VecAssemblyBegin(v);
    441:   VecAssemblyEnd(v);
    442:   VecView(v,viewer);
    443:   VecDestroy(&v);
    444:   return 0;
    445: }
    446: #endif

    448: static PetscErrorCode SVDValuesView_ASCII(SVD svd,PetscViewer viewer)
    449: {
    450:   PetscInt       i;

    452:   PetscViewerASCIIPrintf(viewer,"Singular values = \n");
    453:   for (i=0;i<svd->nconv;i++) PetscViewerASCIIPrintf(viewer,"   %.5f\n",(double)svd->sigma[svd->perm[i]]);
    454:   PetscViewerASCIIPrintf(viewer,"\n");
    455:   return 0;
    456: }

    458: static PetscErrorCode SVDValuesView_MATLAB(SVD svd,PetscViewer viewer)
    459: {
    460:   PetscInt       i;
    461:   const char     *name;

    463:   PetscObjectGetName((PetscObject)svd,&name);
    464:   PetscViewerASCIIPrintf(viewer,"Sigma_%s = [\n",name);
    465:   for (i=0;i<svd->nconv;i++) PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)svd->sigma[svd->perm[i]]);
    466:   PetscViewerASCIIPrintf(viewer,"];\n");
    467:   return 0;
    468: }

    470: /*@C
    471:    SVDValuesView - Displays the computed singular values in a viewer.

    473:    Collective on svd

    475:    Input Parameters:
    476: +  svd    - the singular value solver context
    477: -  viewer - the viewer

    479:    Options Database Key:
    480: .  -svd_view_values - print computed singular values

    482:    Level: intermediate

    484: .seealso: SVDSolve(), SVDVectorsView(), SVDErrorView()
    485: @*/
    486: PetscErrorCode SVDValuesView(SVD svd,PetscViewer viewer)
    487: {
    488:   PetscBool         isascii,isdraw,isbinary;
    489:   PetscViewerFormat format;
    490: #if defined(PETSC_HAVE_HDF5)
    491:   PetscBool         ishdf5;
    492: #endif

    495:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)svd),&viewer);
    498:   SVDCheckSolved(svd,1);
    499:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    500:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
    501: #if defined(PETSC_HAVE_HDF5)
    502:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
    503: #endif
    504:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    505:   if (isdraw) SVDValuesView_DRAW(svd,viewer);
    506:   else if (isbinary) SVDValuesView_BINARY(svd,viewer);
    507: #if defined(PETSC_HAVE_HDF5)
    508:   else if (ishdf5) SVDValuesView_HDF5(svd,viewer);
    509: #endif
    510:   else if (isascii) {
    511:     PetscViewerGetFormat(viewer,&format);
    512:     switch (format) {
    513:       case PETSC_VIEWER_DEFAULT:
    514:       case PETSC_VIEWER_ASCII_INFO:
    515:       case PETSC_VIEWER_ASCII_INFO_DETAIL:
    516:         SVDValuesView_ASCII(svd,viewer);
    517:         break;
    518:       case PETSC_VIEWER_ASCII_MATLAB:
    519:         SVDValuesView_MATLAB(svd,viewer);
    520:         break;
    521:       default:
    522:         PetscInfo(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
    523:     }
    524:   }
    525:   return 0;
    526: }

    528: /*@
    529:    SVDValuesViewFromOptions - Processes command line options to determine if/how
    530:    the computed singular values are to be viewed.

    532:    Collective on svd

    534:    Input Parameter:
    535: .  svd - the singular value solver context

    537:    Level: developer

    539: .seealso: SVDValuesView()
    540: @*/
    541: PetscErrorCode SVDValuesViewFromOptions(SVD svd)
    542: {
    543:   PetscViewer       viewer;
    544:   PetscBool         flg;
    545:   static PetscBool  incall = PETSC_FALSE;
    546:   PetscViewerFormat format;

    548:   if (incall) return 0;
    549:   incall = PETSC_TRUE;
    550:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_view_values",&viewer,&format,&flg);
    551:   if (flg) {
    552:     PetscViewerPushFormat(viewer,format);
    553:     SVDValuesView(svd,viewer);
    554:     PetscViewerPopFormat(viewer);
    555:     PetscViewerDestroy(&viewer);
    556:   }
    557:   incall = PETSC_FALSE;
    558:   return 0;
    559: }

    561: /*@C
    562:    SVDVectorsView - Outputs computed singular vectors to a viewer.

    564:    Collective on svd

    566:    Input Parameters:
    567: +  svd    - the singular value solver context
    568: -  viewer - the viewer

    570:    Options Database Key:
    571: .  -svd_view_vectors - output singular vectors

    573:    Note:
    574:    Right and left singular vectors are interleaved, that is, the vectors are
    575:    output in the following order V0, U0, V1, U1, V2, U2, ...

    577:    Level: intermediate

    579: .seealso: SVDSolve(), SVDValuesView(), SVDErrorView()
    580: @*/
    581: PetscErrorCode SVDVectorsView(SVD svd,PetscViewer viewer)
    582: {
    583:   PetscInt       i,k;
    584:   Vec            x;
    585:   char           vname[30];
    586:   const char     *ename;

    589:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)svd),&viewer);
    592:   SVDCheckSolved(svd,1);
    593:   if (svd->nconv) {
    594:     PetscObjectGetName((PetscObject)svd,&ename);
    595:     SVDComputeVectors(svd);
    596:     for (i=0;i<svd->nconv;i++) {
    597:       k = svd->perm[i];
    598:       PetscSNPrintf(vname,sizeof(vname),"V%" PetscInt_FMT "_%s",i,ename);
    599:       BVGetColumn(svd->V,k,&x);
    600:       PetscObjectSetName((PetscObject)x,vname);
    601:       VecView(x,viewer);
    602:       BVRestoreColumn(svd->V,k,&x);
    603:       PetscSNPrintf(vname,sizeof(vname),"U%" PetscInt_FMT "_%s",i,ename);
    604:       BVGetColumn(svd->U,k,&x);
    605:       PetscObjectSetName((PetscObject)x,vname);
    606:       VecView(x,viewer);
    607:       BVRestoreColumn(svd->U,k,&x);
    608:     }
    609:   }
    610:   return 0;
    611: }

    613: /*@
    614:    SVDVectorsViewFromOptions - Processes command line options to determine if/how
    615:    the computed singular vectors are to be viewed.

    617:    Collective on svd

    619:    Input Parameter:
    620: .  svd - the singular value solver context

    622:    Level: developer

    624: .seealso: SVDVectorsView()
    625: @*/
    626: PetscErrorCode SVDVectorsViewFromOptions(SVD svd)
    627: {
    628:   PetscViewer       viewer;
    629:   PetscBool         flg = PETSC_FALSE;
    630:   static PetscBool  incall = PETSC_FALSE;
    631:   PetscViewerFormat format;

    633:   if (incall) return 0;
    634:   incall = PETSC_TRUE;
    635:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->options,((PetscObject)svd)->prefix,"-svd_view_vectors",&viewer,&format,&flg);
    636:   if (flg) {
    637:     PetscViewerPushFormat(viewer,format);
    638:     SVDVectorsView(svd,viewer);
    639:     PetscViewerPopFormat(viewer);
    640:     PetscViewerDestroy(&viewer);
    641:   }
    642:   incall = PETSC_FALSE;
    643:   return 0;
    644: }