Actual source code: ex15.c

  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain

  6:    This file is part of SLEPc.
  7:       
  8:    SLEPc is free software: you can redistribute it and/or modify it under  the
  9:    terms of version 3 of the GNU Lesser General Public License as published by
 10:    the Free Software Foundation.

 12:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY 
 13:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS 
 14:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for 
 15:    more details.

 17:    You  should have received a copy of the GNU Lesser General  Public  License
 18:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
 19:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 20: */

 22: static char help[] = "Singular value decomposition of the Lauchli matrix.\n"
 23:   "The command line options are:\n"
 24:   "  -n <n>, where <n> = matrix dimension.\n"
 25:   "  -mu <mu>, where <mu> = subdiagonal value.\n\n";

 27:  #include slepcsvd.h

 31: int main( int argc, char **argv )
 32: {
 33:   Mat                  A;               /* operator matrix */
 34:   Vec            u,v;             /* left and right singular vectors */
 35:   SVD                  svd;             /* singular value problem solver context */
 36:   const SVDType  type;
 37:   PetscReal            error, tol, sigma, mu=PETSC_SQRT_MACHINE_EPSILON;
 39:   PetscInt       n=100, i, j, Istart, Iend, nsv, maxit, its, nconv;

 41:   SlepcInitialize(&argc,&argv,(char*)0,help);

 43:   PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);
 44:   PetscOptionsGetReal(PETSC_NULL,"-mu",&mu,PETSC_NULL);
 45:   PetscPrintf(PETSC_COMM_WORLD,"\nLauchli singular value decomposition, (%d x %d) mu=%g\n\n",n+1,n,mu);

 47:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 48:                           Build the Lauchli matrix
 49:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

 51:   MatCreate(PETSC_COMM_WORLD,&A);
 52:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n+1,n);
 53:   MatSetFromOptions(A);

 55:   MatGetOwnershipRange(A,&Istart,&Iend);
 56:   for (i=Istart;i<Iend;i++) {
 57:     if (i == 0) {
 58:       for (j=0;j<n;j++) {
 59:         MatSetValue(A,0,j,1.0,INSERT_VALUES);
 60:       }
 61:     } else {
 62:       MatSetValue(A,i,i-1,mu,INSERT_VALUES);
 63:     }
 64:   }
 65: 
 66:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
 67:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
 68:   MatGetVecs(A,&v,&u);

 70:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 71:           Create the singular value solver and set various options
 72:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

 74:   /* 
 75:      Create singular value solver context
 76:   */
 77:   SVDCreate(PETSC_COMM_WORLD,&svd);

 79:   /* 
 80:      Set operator
 81:   */
 82:   SVDSetOperator(svd,A);
 83: 
 84:   /*
 85:      Use thick-restart Lanczos as default solver
 86:   */
 87:   SVDSetType(svd,SVDTRLANCZOS);

 89:   /*
 90:      Set solver parameters at runtime
 91:   */
 92:   SVDSetFromOptions(svd);

 94:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 95:                       Solve the singular value system
 96:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

 98:   SVDSolve(svd);
 99:   SVDGetIterationNumber(svd, &its);
100:   PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %d\n",its);

102:   /*
103:      Optional: Get some information from the solver and display it
104:   */
105:   SVDGetType(svd,&type);
106:   PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);
107:   SVDGetDimensions(svd,&nsv,PETSC_NULL,PETSC_NULL);
108:   PetscPrintf(PETSC_COMM_WORLD," Number of requested singular values: %d\n",nsv);
109:   SVDGetTolerances(svd,&tol,&maxit);
110:   PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%d\n",tol,maxit);

112:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
113:                     Display solution and clean up
114:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

116:   /* 
117:      Get number of converged singular triplets
118:   */
119:   SVDGetConverged(svd,&nconv);
120:   PetscPrintf(PETSC_COMM_WORLD," Number of converged approximate singular triplets: %d\n\n",nconv);

122:   if (nconv>0) {
123:     /*
124:        Display singular values and relative errors
125:     */
126:     PetscPrintf(PETSC_COMM_WORLD,
127:          "          sigma           residual norm\n"
128:          "  --------------------- ------------------\n" );
129:     for( i=0; i<nconv; i++ ) {
130:       /* 
131:          Get converged singular triplets: i-th singular value is stored in sigma
132:       */
133:       SVDGetSingularTriplet(svd,i,&sigma,u,v);

135:       /*
136:          Compute the error associated to each singular triplet 
137:       */
138:       SVDComputeRelativeError(svd,i,&error);

140:       PetscPrintf(PETSC_COMM_WORLD,"       % 6f      ",sigma);
141:       PetscPrintf(PETSC_COMM_WORLD," % 12g\n",error);
142:     }
143:     PetscPrintf(PETSC_COMM_WORLD,"\n" );
144:   }
145: 
146:   /* 
147:      Free work space
148:   */
149:   SVDDestroy(svd);
150:   MatDestroy(A);
151:   VecDestroy(u);
152:   VecDestroy(v);
153:   SlepcFinalize();
154:   return 0;
155: }