Actual source code: ex15.c

  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-2011, Universitat 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;
 38:   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           relative error\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: }