LCOV - code coverage report
Current view: top level - svd/tutorials - ex52.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 79 84 94.0 %
Date: 2024-11-21 00:34:55 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : 
      11             : static char help[] = "Partial hyperbolic singular value decomposition (HSVD) from a file.\n"
      12             :   "The command line options are:\n"
      13             :   "  -file <filename>, PETSc binary file containing matrix A.\n"
      14             :   "  -p <p>, where <p> = number of -1's in signature.\n"
      15             :   "  -transpose, to transpose the matrix before doing the computation.\n\n";
      16             : 
      17             : #include <slepcsvd.h>
      18             : 
      19          23 : int main(int argc,char **argv)
      20             : {
      21          23 :   Mat            A,Omega;         /* operator matrix, signature matrix */
      22          23 :   SVD            svd;             /* singular value problem solver context */
      23          23 :   Mat            At;
      24          23 :   Vec            u,v,vomega,*U,*V;
      25          23 :   MatType        Atype;
      26          23 :   PetscReal      tol,lev1=0.0,lev2=0.0;
      27          23 :   PetscInt       M,N,p=0,i,Istart,Iend,nconv,nsv;
      28          23 :   char           filename[PETSC_MAX_PATH_LEN];
      29          23 :   PetscViewer    viewer;
      30          23 :   PetscBool      flg,terse,skiporth=PETSC_FALSE,transpose=PETSC_FALSE;
      31             : 
      32          23 :   PetscFunctionBeginUser;
      33          23 :   PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
      34             : 
      35             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      36             :         Load matrix that defines the hyperbolic singular value problem
      37             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      38             : 
      39          23 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nHyperbolic singular value problem stored in file.\n\n"));
      40          23 :   PetscCall(PetscOptionsGetString(NULL,NULL,"-file",filename,sizeof(filename),&flg));
      41          23 :   PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Must indicate a file name for matrix A with the -file option");
      42             : 
      43             : #if defined(PETSC_USE_COMPLEX)
      44             :   PetscCall(PetscPrintf(PETSC_COMM_WORLD," Reading COMPLEX matrix from a binary file...\n"));
      45             : #else
      46          23 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD," Reading REAL matrix from a binary file...\n"));
      47             : #endif
      48          23 :   PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_READ,&viewer));
      49          23 :   PetscCall(MatCreate(PETSC_COMM_WORLD,&A));
      50          23 :   PetscCall(MatSetFromOptions(A));
      51          23 :   PetscCall(MatLoad(A,viewer));
      52          23 :   PetscCall(PetscViewerDestroy(&viewer));
      53             : 
      54             :   /* transpose the matrix if requested */
      55          23 :   PetscCall(PetscOptionsGetBool(NULL,NULL,"-transpose",&transpose,NULL));
      56          23 :   if (transpose) {
      57          10 :     PetscCall(MatHermitianTranspose(A,MAT_INITIAL_MATRIX,&At));
      58          10 :     PetscCall(MatDestroy(&A));
      59          10 :     A = At;
      60             :   }
      61             : 
      62             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      63             :                           Create the signature
      64             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      65             : 
      66          23 :   PetscCall(MatGetSize(A,&M,&N));
      67          23 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-p",&p,&flg));
      68          23 :   PetscCheck(p>=0,PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Parameter p cannot be negative");
      69          23 :   PetscCheck(p<M,PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Parameter p cannot be larger than the number of rows of A");
      70          23 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\n Matrix dimensions: %" PetscInt_FMT "x%" PetscInt_FMT,M,N));
      71          23 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,", using signature Omega=blkdiag(-I_%" PetscInt_FMT ",I_%" PetscInt_FMT ")\n\n",p,M-p));
      72             : 
      73          23 :   PetscCall(MatCreateVecs(A,NULL,&vomega));
      74          23 :   PetscCall(VecSet(vomega,1.0));
      75          23 :   PetscCall(VecGetOwnershipRange(vomega,&Istart,&Iend));
      76       13320 :   for (i=Istart;i<Iend;i++) {
      77       13297 :     if (i<p) PetscCall(VecSetValue(vomega,i,-1.0,INSERT_VALUES));
      78             :   }
      79          23 :   PetscCall(VecAssemblyBegin(vomega));
      80          23 :   PetscCall(VecAssemblyEnd(vomega));
      81             : 
      82          23 :   PetscCall(MatGetType(A,&Atype));
      83          23 :   PetscCall(MatCreate(PETSC_COMM_WORLD,&Omega));
      84          23 :   PetscCall(MatSetSizes(Omega,PETSC_DECIDE,PETSC_DECIDE,M,M));
      85          23 :   PetscCall(MatSetType(Omega,Atype));
      86          23 :   PetscCall(MatDiagonalSet(Omega,vomega,INSERT_VALUES));
      87             : 
      88             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      89             :           Create the singular value solver and set various options
      90             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      91             : 
      92          23 :   PetscCall(SVDCreate(PETSC_COMM_WORLD,&svd));
      93             : 
      94          23 :   PetscCall(SVDSetOperators(svd,A,NULL));
      95          23 :   PetscCall(SVDSetSignature(svd,vomega));
      96          23 :   PetscCall(SVDSetProblemType(svd,SVD_HYPERBOLIC));
      97             : 
      98          23 :   PetscCall(SVDSetFromOptions(svd));
      99             : 
     100          23 :   PetscCall(SVDIsHyperbolic(svd,&flg));
     101          23 :   PetscCheck(flg,PetscObjectComm((PetscObject)(svd)),PETSC_ERR_COR,"Problem should be hyperbolic");
     102             : 
     103             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     104             :                  Solve the problem, display solution
     105             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     106             : 
     107          23 :   PetscCall(MatCreateVecs(A,&v,&u));
     108          23 :   PetscCall(VecSet(u,1.0));
     109          23 :   PetscCall(VecSet(v,1.0));
     110          23 :   PetscCall(SVDSolve(svd));
     111             : 
     112             :   /* show detailed info unless -terse option is given by user */
     113          23 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-terse",&terse));
     114          23 :   if (terse) PetscCall(SVDErrorView(svd,SVD_ERROR_NORM,NULL));
     115             :   else {
     116           0 :     PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO_DETAIL));
     117           0 :     PetscCall(SVDConvergedReasonView(svd,PETSC_VIEWER_STDOUT_WORLD));
     118           0 :     PetscCall(SVDErrorView(svd,SVD_ERROR_NORM,PETSC_VIEWER_STDOUT_WORLD));
     119           0 :     PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD));
     120             :   }
     121             : 
     122             :   /* check orthogonality */
     123          23 :   PetscCall(PetscOptionsGetBool(NULL,NULL,"-skiporth",&skiporth,NULL));
     124          23 :   PetscCall(SVDGetConverged(svd,&nconv));
     125          23 :   PetscCall(SVDGetDimensions(svd,&nsv,NULL,NULL));
     126          23 :   nconv = PetscMin(nconv,nsv);
     127          23 :   if (nconv>0 && !skiporth) {
     128          23 :     PetscCall(SVDGetTolerances(svd,&tol,NULL));
     129          23 :     PetscCall(VecDuplicateVecs(u,nconv,&U));
     130          23 :     PetscCall(VecDuplicateVecs(v,nconv,&V));
     131         653 :     for (i=0;i<nconv;i++) PetscCall(SVDGetSingularTriplet(svd,i,NULL,U[i],V[i]));
     132          23 :     PetscCall(VecCheckOrthonormality(U,nconv,NULL,nconv,Omega,NULL,&lev1));
     133          23 :     PetscCall(VecCheckOrthonormality(V,nconv,NULL,nconv,NULL,NULL,&lev2));
     134          23 :     if (lev1+lev2<20*tol) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Level of orthogonality below the tolerance\n"));
     135           0 :     else PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Level of orthogonality: %g (U) %g (V)\n",(double)lev1,(double)lev2));
     136          23 :     PetscCall(VecDestroyVecs(nconv,&U));
     137          23 :     PetscCall(VecDestroyVecs(nconv,&V));
     138             :   }
     139          23 :   PetscCall(VecDestroy(&u));
     140          23 :   PetscCall(VecDestroy(&v));
     141             : 
     142             :   /* free work space */
     143          23 :   PetscCall(SVDDestroy(&svd));
     144          23 :   PetscCall(MatDestroy(&A));
     145          23 :   PetscCall(MatDestroy(&Omega));
     146          23 :   PetscCall(VecDestroy(&vomega));
     147          23 :   PetscCall(SlepcFinalize());
     148             :   return 0;
     149             : }
     150             : 
     151             : /*TEST
     152             : 
     153             :    testset:
     154             :       args: -file ${DATAFILESPATH}/matrices/real/illc1033.petsc -svd_nsv 62 -p 40 -terse
     155             :       requires: double !complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
     156             :       filter: grep -v Reading
     157             :       output_file: output/ex52_1.out
     158             :       test:
     159             :          args: -svd_type cross -svd_cross_explicitmatrix {{0 1}} -svd_implicittranspose {{0 1}}
     160             :          suffix: 1_cross
     161             :       test:
     162             :          args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}} -svd_ncv 300
     163             :          suffix: 1_cyclic
     164             :       test:
     165             :          args: -svd_type trlanczos -svd_trlanczos_explicitmatrix {{0 1}}
     166             :          suffix: 1_trlanczos
     167             :       test:
     168             :          args: -svd_type lapack
     169             :          suffix: 1_lapack
     170             : 
     171             :    testset:
     172             :       args: -file ${DATAFILESPATH}/matrices/real/illc1033.petsc -transpose -svd_nsv 6 -p 130 -terse
     173             :       requires: double !complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
     174             :       filter: grep -v Reading
     175             :       output_file: output/ex52_2.out
     176             :       test:
     177             :          args: -svd_type cross -svd_cross_explicitmatrix {{0 1}} -svd_implicittranspose {{0 1}} -svd_ncv 100
     178             :          suffix: 2_cross
     179             :       test:
     180             :          args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}} -svd_ncv 25
     181             :          suffix: 2_cyclic
     182             :       test:
     183             :          args: -svd_type trlanczos -svd_trlanczos_explicitmatrix {{0 1}} -svd_implicittranspose {{0 1}}
     184             :          suffix: 2_trlanczos
     185             : 
     186             :    testset:
     187             :       args: -file ${DATAFILESPATH}/matrices/complex/illc1033.petsc -svd_nsv 62 -p 40 -terse
     188             :       requires: double complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
     189             :       filter: grep -v Reading
     190             :       output_file: output/ex52_1.out
     191             :       test:
     192             :          args: -svd_type cross -svd_cross_explicitmatrix {{0 1}}
     193             :          suffix: 3_cross
     194             :       test:
     195             :          args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}} -svd_cyclic_bv_definite_tol 1e-13 -svd_cyclic_st_ksp_type gcr -svd_cyclic_st_pc_type jacobi -svd_ncv 250
     196             :          suffix: 3_cyclic
     197             :       test:
     198             :          args: -svd_type trlanczos -svd_trlanczos_explicitmatrix {{0 1}} -bv_definite_tol 1e-13
     199             :          suffix: 3_trlanczos
     200             :       test:
     201             :          args: -svd_type lapack
     202             :          suffix: 3_lapack
     203             : 
     204             :    testset:
     205             :       args: -file ${DATAFILESPATH}/matrices/complex/illc1033.petsc -transpose -svd_nsv 6 -p 130 -terse
     206             :       requires: double complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
     207             :       filter: grep -v Reading
     208             :       output_file: output/ex52_2.out
     209             :       test:
     210             :          args: -svd_type cross -svd_cross_explicitmatrix {{0 1}} -svd_ncv 100 -svd_cross_bv_definite_tol 1e-14
     211             :          suffix: 4_cross
     212             :       test:
     213             :          args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}} -svd_ncv 26
     214             :          suffix: 4_cyclic
     215             :       test:
     216             :          args: -svd_type trlanczos -svd_trlanczos_explicitmatrix {{0 1}}
     217             :          suffix: 4_trlanczos
     218             : 
     219             :    testset:
     220             :       args: -file ${SLEPC_DIR}/share/slepc/datafiles/matrices/rdb200.petsc -svd_smallest -svd_nsv 3 -p 1 -terse
     221             :       requires: double !complex !defined(PETSC_USE_64BIT_INDICES)
     222             :       filter: grep -v Reading
     223             :       output_file: output/ex52_5.out
     224             :       test:
     225             :          args: -svd_type cross -svd_max_it 1000 -svd_cross_bv_definite_tol 1e-14
     226             :          suffix: 5_cross
     227             :       test:
     228             :          args: -svd_type cyclic -svd_max_it 4000 -svd_ncv 32 -svd_cyclic_st_ksp_type preonly -svd_cyclic_st_pc_type jacobi -svd_cyclic_bv_definite_tol 1e-14
     229             :          suffix: 5_cyclic
     230             :       test:
     231             :          args: -svd_type trlanczos -svd_max_it 4000 -svd_ncv 28 -bv_definite_tol 1e-14
     232             :          suffix: 5_trlanczos
     233             :       test:
     234             :          args: -svd_type lapack
     235             :          suffix: 5_lapack
     236             : 
     237             : TEST*/

Generated by: LCOV version 1.14