Date: 2016-03-29T14:58:35+00:00

Actual source code: svdview.c
slepc-3.6.3 2016-03-29
Report Typos and Errors

      1: /*
      2:    The SVD routines related to various viewers.

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

      8:    This file is part of SLEPc.

     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 <slepc/private/svdimpl.h>      /*I "slepcsvd.h" I*/
     25: #include <petscdraw.h>

     29: /*@C
     30:    SVDView - Prints the SVD data structure.

     32:    Collective on SVD

     34:    Input Parameters:
     35: +  svd - the singular value solver context
     36: -  viewer - optional visualization context

     38:    Options Database Key:
     39: .  -svd_view -  Calls SVDView() at end of SVDSolve()

     41:    Note:
     42:    The available visualization contexts include
     43: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
     44: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
     45:          output where only the first processor opens
     46:          the file.  All other processors send their
     47:          data to the first processor to print.

     49:    The user can open an alternative visualization context with
     50:    PetscViewerASCIIOpen() - output to a specified file.

     52:    Level: beginner

     54: .seealso: STView(), PetscViewerASCIIOpen()
     55: @*/
     56: PetscErrorCode SVDView(SVD svd,PetscViewer viewer)
     57: {
     59:   PetscBool      isascii,isshell;

     63:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));

     67:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
     68:   if (isascii) {
     69:     PetscObjectPrintClassNamePrefixType((PetscObject)svd,viewer);
     70:     if (svd->ops->view) {
     71:       PetscViewerASCIIPushTab(viewer);
     72:       (*svd->ops->view)(svd,viewer);
     73:       PetscViewerASCIIPopTab(viewer);
     74:     }
     75:     PetscViewerASCIIPrintf(viewer,"  transpose mode: %s\n",svd->impltrans?"implicit":"explicit");
     76:     if (svd->which == SVD_LARGEST) {
     77:       PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: largest\n");
     78:     } else {
     79:       PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: smallest\n");
     80:     }
     81:     PetscViewerASCIIPrintf(viewer,"  number of singular values (nsv): %D\n",svd->nsv);
     82:     PetscViewerASCIIPrintf(viewer,"  number of column vectors (ncv): %D\n",svd->ncv);
     83:     PetscViewerASCIIPrintf(viewer,"  maximum dimension of projected problem (mpd): %D\n",svd->mpd);
     84:     PetscViewerASCIIPrintf(viewer,"  maximum number of iterations: %D\n",svd->max_it);
     85:     PetscViewerASCIIPrintf(viewer,"  tolerance: %g\n",(double)svd->tol);
     86:     if (svd->nini) {
     87:       PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial space: %D\n",PetscAbs(svd->nini));
     88:     }
     89:     if (svd->ninil) {
     90:       PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial left space: %D\n",PetscAbs(svd->ninil));
     91:     }
     92:   } else {
     93:     if (svd->ops->view) {
     94:       (*svd->ops->view)(svd,viewer);
     95:     }
     96:   }
     97:   PetscObjectTypeCompareAny((PetscObject)svd,&isshell,SVDCROSS,SVDCYCLIC,"");
     98:   if (!isshell) {
     99:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
    100:     if (!svd->V) { SVDGetBV(svd,&svd->V,NULL); }
    101:     BVView(svd->V,viewer);
    102:     if (!svd->ds) { SVDGetDS(svd,&svd->ds); }
    103:     DSView(svd->ds,viewer);
    104:     PetscViewerPopFormat(viewer);
    105:   }
    106:   return(0);
    107: }

    111: /*@C
    112:    SVDReasonView - Displays the reason an SVD solve converged or diverged.

    114:    Collective on SVD

    116:    Parameter:
    117: +  svd - the singular value solver context
    118: -  viewer - the viewer to display the reason

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

    123:    Level: intermediate

    125: .seealso: SVDSetTolerances(), SVDGetIterationNumber()
    126: @*/
    127: PetscErrorCode SVDReasonView(SVD svd,PetscViewer viewer)
    128: {
    130:   PetscBool      isAscii;

    133:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
    134:   if (isAscii) {
    135:     PetscViewerASCIIAddTab(viewer,((PetscObject)svd)->tablevel);
    136:     if (svd->reason > 0) {
    137:       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);
    138:     } else {
    139:       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);
    140:     }
    141:     PetscViewerASCIISubtractTab(viewer,((PetscObject)svd)->tablevel);
    142:   }
    143:   return(0);
    144: }

    148: /*@
    149:    SVDReasonViewFromOptions - Processes command line options to determine if/how
    150:    the SVD converged reason is to be viewed.

    152:    Collective on SVD

    154:    Input Parameters:
    155: .  svd - the singular value solver context

    157:    Level: developer
    158: @*/
    159: PetscErrorCode SVDReasonViewFromOptions(SVD svd)
    160: {
    161:   PetscErrorCode    ierr;
    162:   PetscViewer       viewer;
    163:   PetscBool         flg;
    164:   static PetscBool  incall = PETSC_FALSE;
    165:   PetscViewerFormat format;

    168:   if (incall) return(0);
    169:   incall = PETSC_TRUE;
    170:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_converged_reason",&viewer,&format,&flg);
    171:   if (flg) {
    172:     PetscViewerPushFormat(viewer,format);
    173:     SVDReasonView(svd,viewer);
    174:     PetscViewerPopFormat(viewer);
    175:     PetscViewerDestroy(&viewer);
    176:   }
    177:   incall = PETSC_FALSE;
    178:   return(0);
    179: }

    183: static PetscErrorCode SVDErrorView_ASCII(SVD svd,SVDErrorType etype,PetscViewer viewer)
    184: {
    185:   PetscBool      errok;
    186:   PetscReal      error,sigma;
    187:   PetscInt       i,j;

    191:   if (svd->nconv<svd->nsv) {
    192:     PetscViewerASCIIPrintf(viewer," Problem: less than %D singular values converged\n\n",svd->nsv);
    193:     return(0);
    194:   }
    195:   errok = PETSC_TRUE;
    196:   for (i=0;i<svd->nsv;i++) {
    197:     SVDComputeError(svd,i,etype,&error);
    198:     errok = (errok && error<5.0*svd->tol)? PETSC_TRUE: PETSC_FALSE;
    199:   }
    200:   if (!errok) {
    201:     PetscViewerASCIIPrintf(viewer," Problem: some of the first %D relative errors are higher than the tolerance\n\n",svd->nsv);
    202:     return(0);
    203:   }
    204:   PetscViewerASCIIPrintf(viewer," All requested singular values computed up to the required tolerance:");
    205:   for (i=0;i<=(svd->nsv-1)/8;i++) {
    206:     PetscViewerASCIIPrintf(viewer,"\n     ");
    207:     for (j=0;j<PetscMin(8,svd->nsv-8*i);j++) {
    208:       SVDGetSingularTriplet(svd,8*i+j,&sigma,NULL,NULL);
    209:       PetscViewerASCIIPrintf(viewer,"%.5f",(double)sigma);
    210:       if (8*i+j+1<svd->nsv) { PetscViewerASCIIPrintf(viewer,", "); }
    211:     }
    212:   }
    213:   PetscViewerASCIIPrintf(viewer,"\n\n");
    214:   return(0);
    215: }

    219: static PetscErrorCode SVDErrorView_DETAIL(SVD svd,SVDErrorType etype,PetscViewer viewer)
    220: {
    222:   PetscReal      error,sigma;
    223:   PetscInt       i;
    224: #define EXLEN 30
    225:   char           ex[EXLEN],sep[]=" ---------------------- --------------------\n";

    228:   if (!svd->nconv) return(0);
    229:   switch (etype) {
    230:     case SVD_ERROR_ABSOLUTE:
    231:       PetscSNPrintf(ex,EXLEN," absolute error");
    232:       break;
    233:     case SVD_ERROR_RELATIVE:
    234:       PetscSNPrintf(ex,EXLEN," relative error");
    235:       break;
    236:   }
    237:   PetscViewerASCIIPrintf(viewer,"%s          sigma           %s\n%s",sep,ex,sep);
    238:   for (i=0;i<svd->nconv;i++) {
    239:     SVDGetSingularTriplet(svd,i,&sigma,NULL,NULL);
    240:     SVDComputeError(svd,i,etype,&error);
    241:     PetscViewerASCIIPrintf(viewer,"       % 6f          %12g\n",(double)sigma,(double)error);
    242:   }
    243:   PetscViewerASCIIPrintf(viewer,sep);
    244:   return(0);
    245: }

    249: static PetscErrorCode SVDErrorView_MATLAB(SVD svd,SVDErrorType etype,PetscViewer viewer)
    250: {
    252:   PetscReal      error;
    253:   PetscInt       i;
    254:   const char     *name;

    257:   PetscObjectGetName((PetscObject)svd,&name);
    258:   PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name);
    259:   for (i=0;i<svd->nconv;i++) {
    260:     SVDComputeError(svd,i,etype,&error);
    261:     PetscViewerASCIIPrintf(viewer,"%18.16e\n",error);
    262:   }
    263:   PetscViewerASCIIPrintf(viewer,"];\n");
    264:   return(0);
    265: }

    269: /*@C
    270:    SVDErrorView - Displays the errors associated with the computed solution
    271:    (as well as the singular values).

    273:    Collective on SVD

    275:    Input Parameters:
    276: +  svd    - the singular value solver context
    277: .  etype  - error type
    278: -  viewer - optional visualization context

    280:    Options Database Key:
    281: +  -svd_error_absolute - print absolute errors of each singular triplet
    282: -  -svd_error_relative - print relative errors of each singular triplet

    284:    Notes:
    285:    By default, this function checks the error of all singular triplets and prints
    286:    the singular values if all of them are below the requested tolerance.
    287:    If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
    288:    singular values and corresponding errors is printed.

    290:    Level: intermediate

    292: .seealso: SVDSolve(), SVDValuesView(), SVDVectorsView()
    293: @*/
    294: PetscErrorCode SVDErrorView(SVD svd,SVDErrorType etype,PetscViewer viewer)
    295: {
    296:   PetscBool         isascii;
    297:   PetscViewerFormat format;
    298:   PetscErrorCode    ierr;

    302:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
    305:   SVDCheckSolved(svd,1);
    306:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    307:   if (!isascii) return(0);

    309:   PetscViewerGetFormat(viewer,&format);
    310:   switch (format) {
    311:     case PETSC_VIEWER_DEFAULT:
    312:     case PETSC_VIEWER_ASCII_INFO:
    313:       SVDErrorView_ASCII(svd,etype,viewer);
    314:       break;
    315:     case PETSC_VIEWER_ASCII_INFO_DETAIL:
    316:       SVDErrorView_DETAIL(svd,etype,viewer);
    317:       break;
    318:     case PETSC_VIEWER_ASCII_MATLAB:
    319:       SVDErrorView_MATLAB(svd,etype,viewer);
    320:       break;
    321:     default:
    322:       PetscInfo1(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
    323:   }
    324:   return(0);
    325: }

    329: /*@
    330:    SVDErrorViewFromOptions - Processes command line options to determine if/how
    331:    the errors of the computed solution are to be viewed.

    333:    Collective on SVD

    335:    Input Parameters:
    336: .  svd - the singular value solver context

    338:    Level: developer
    339: @*/
    340: PetscErrorCode SVDErrorViewFromOptions(SVD svd)
    341: {
    342:   PetscErrorCode    ierr;
    343:   PetscViewer       viewer;
    344:   PetscBool         flg;
    345:   static PetscBool  incall = PETSC_FALSE;
    346:   PetscViewerFormat format;

    349:   if (incall) return(0);
    350:   incall = PETSC_TRUE;
    351:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_error_absolute",&viewer,&format,&flg);
    352:   if (flg) {
    353:     PetscViewerPushFormat(viewer,format);
    354:     SVDErrorView(svd,SVD_ERROR_ABSOLUTE,viewer);
    355:     PetscViewerPopFormat(viewer);
    356:     PetscViewerDestroy(&viewer);
    357:   }
    358:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_error_relative",&viewer,&format,&flg);
    359:   if (flg) {
    360:     PetscViewerPushFormat(viewer,format);
    361:     SVDErrorView(svd,SVD_ERROR_RELATIVE,viewer);
    362:     PetscViewerPopFormat(viewer);
    363:     PetscViewerDestroy(&viewer);
    364:   }
    365:   incall = PETSC_FALSE;
    366:   return(0);
    367: }

    371: static PetscErrorCode SVDValuesView_DRAW(SVD svd,PetscViewer viewer)
    372: {
    374:   PetscDraw      draw;
    375:   PetscDrawSP    drawsp;
    376:   PetscReal      re,im=0.0;
    377:   PetscInt       i;

    380:   if (!svd->nconv) return(0);
    381:   PetscViewerDrawOpen(PETSC_COMM_SELF,0,"Computed singular values",PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
    382:   PetscViewerDrawGetDraw(viewer,0,&draw);
    383:   PetscDrawSPCreate(draw,1,&drawsp);
    384:   for (i=0;i<svd->nconv;i++) {
    385:     re = svd->sigma[svd->perm[i]];
    386:     PetscDrawSPAddPoint(drawsp,&re,&im);
    387:   }
    388:   PetscDrawSPDraw(drawsp,PETSC_TRUE);
    389:   PetscDrawSPDestroy(&drawsp);
    390:   PetscViewerDestroy(&viewer);
    391:   return(0);
    392: }

    396: static PetscErrorCode SVDValuesView_ASCII(SVD svd,PetscViewer viewer)
    397: {
    398:   PetscInt       i;

    402:   PetscViewerASCIIPrintf(viewer,"Singular values = \n");
    403:   for (i=0;i<svd->nconv;i++) {
    404:     PetscViewerASCIIPrintf(viewer,"   %.5f\n",(double)svd->sigma[svd->perm[i]]);
    405:   }
    406:   PetscViewerASCIIPrintf(viewer,"\n");
    407:   return(0);
    408: }

    412: static PetscErrorCode SVDValuesView_MATLAB(SVD svd,PetscViewer viewer)
    413: {
    415:   PetscInt       i;
    416:   const char     *name;

    419:   PetscObjectGetName((PetscObject)svd,&name);
    420:   PetscViewerASCIIPrintf(viewer,"Sigma_%s = [\n",name);
    421:   for (i=0;i<svd->nconv;i++) {
    422:     PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)svd->sigma[svd->perm[i]]);
    423:   }
    424:   PetscViewerASCIIPrintf(viewer,"];\n");
    425:   return(0);
    426: }

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

    433:    Collective on SVD

    435:    Input Parameters:
    436: +  svd    - the singular value solver context
    437: -  viewer - the viewer

    439:    Options Database Key:
    440: .  -svd_view_values - print computed singular values

    442:    Level: intermediate

    444: .seealso: SVDSolve(), SVDVectorsView(), SVDErrorView()
    445: @*/
    446: PetscErrorCode SVDValuesView(SVD svd,PetscViewer viewer)
    447: {
    448:   PetscBool         isascii,isdraw;
    449:   PetscViewerFormat format;
    450:   PetscErrorCode    ierr;

    454:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
    457:   SVDCheckSolved(svd,1);
    458:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    459:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    460:   if (isdraw) {
    461:     SVDValuesView_DRAW(svd,viewer);
    462:   } else if (isascii) {
    463:     PetscViewerGetFormat(viewer,&format);
    464:     switch (format) {
    465:       case PETSC_VIEWER_DEFAULT:
    466:       case PETSC_VIEWER_ASCII_INFO:
    467:       case PETSC_VIEWER_ASCII_INFO_DETAIL:
    468:         SVDValuesView_ASCII(svd,viewer);
    469:         break;
    470:       case PETSC_VIEWER_ASCII_MATLAB:
    471:         SVDValuesView_MATLAB(svd,viewer);
    472:         break;
    473:       default:
    474:         PetscInfo1(svd,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
    475:     }
    476:   }
    477:   return(0);
    478: }

    482: /*@
    483:    SVDValuesViewFromOptions - Processes command line options to determine if/how
    484:    the computed singular values are to be viewed.

    486:    Collective on SVD

    488:    Input Parameters:
    489: .  svd - the singular value solver context

    491:    Level: developer
    492: @*/
    493: PetscErrorCode SVDValuesViewFromOptions(SVD svd)
    494: {
    495:   PetscErrorCode    ierr;
    496:   PetscViewer       viewer;
    497:   PetscBool         flg;
    498:   static PetscBool  incall = PETSC_FALSE;
    499:   PetscViewerFormat format;

    502:   if (incall) return(0);
    503:   incall = PETSC_TRUE;
    504:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_view_values",&viewer,&format,&flg);
    505:   if (flg) {
    506:     PetscViewerPushFormat(viewer,format);
    507:     SVDValuesView(svd,viewer);
    508:     PetscViewerPopFormat(viewer);
    509:     PetscViewerDestroy(&viewer);
    510:   }
    511:   incall = PETSC_FALSE;
    512:   return(0);
    513: }

    517: /*@C
    518:    SVDVectorsView - Outputs computed singular vectors to a viewer.

    520:    Collective on SVD

    522:    Parameter:
    523: +  svd    - the singular value solver context
    524: -  viewer - the viewer

    526:    Options Database Keys:
    527: .  -svd_view_vectors - output singular vectors

    529:    Level: intermediate

    531: .seealso: SVDSolve(), SVDValuesView(), SVDErrorView()
    532: @*/
    533: PetscErrorCode SVDVectorsView(SVD svd,PetscViewer viewer)
    534: {
    536:   PetscInt       i,k;
    537:   Vec            x;
    538: #define NMLEN 30
    539:   char           vname[NMLEN];
    540:   const char     *ename;

    544:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)svd));
    547:   SVDCheckSolved(svd,1);
    548:   if (svd->nconv) {
    549:     PetscObjectGetName((PetscObject)svd,&ename);
    550:     SVDComputeVectors(svd);
    551:     for (i=0;i<svd->nconv;i++) {
    552:       k = svd->perm[i];
    553:       PetscSNPrintf(vname,NMLEN,"V%d_%s",i,ename);
    554:       BVGetColumn(svd->V,k,&x);
    555:       PetscObjectSetName((PetscObject)x,vname);
    556:       VecView(x,viewer);
    557:       BVRestoreColumn(svd->V,k,&x);
    558:       PetscSNPrintf(vname,NMLEN,"U%d_%s",i,ename);
    559:       BVGetColumn(svd->U,k,&x);
    560:       PetscObjectSetName((PetscObject)x,vname);
    561:       VecView(x,viewer);
    562:       BVRestoreColumn(svd->U,k,&x);
    563:     }
    564:   }
    565:   return(0);
    566: }

    570: /*@
    571:    SVDVectorsViewFromOptions - Processes command line options to determine if/how
    572:    the computed singular vectors are to be viewed.

    574:    Collective on SVD

    576:    Input Parameters:
    577: .  svd - the singular value solver context

    579:    Level: developer
    580: @*/
    581: PetscErrorCode SVDVectorsViewFromOptions(SVD svd)
    582: {
    583:   PetscErrorCode    ierr;
    584:   PetscViewer       viewer;
    585:   PetscBool         flg = PETSC_FALSE;
    586:   static PetscBool  incall = PETSC_FALSE;
    587:   PetscViewerFormat format;

    590:   if (incall) return(0);
    591:   incall = PETSC_TRUE;
    592:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)svd),((PetscObject)svd)->prefix,"-svd_view_vectors",&viewer,&format,&flg);
    593:   if (flg) {
    594:     PetscViewerPushFormat(viewer,format);
    595:     SVDVectorsView(svd,viewer);
    596:     PetscViewerPopFormat(viewer);
    597:     PetscViewerDestroy(&viewer);
    598:   }
    599:   incall = PETSC_FALSE;
    600:   return(0);
    601: }