LCOV - code coverage report
Current view: top level - sys/classes/ds/tests - test22.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 116 121 95.9 %
Date: 2024-12-18 00:51:33 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[] = "Test DSGSVD with compact storage.\n\n";
      12             : 
      13             : #include <slepcds.h>
      14             : 
      15           3 : int main(int argc,char **argv)
      16             : {
      17           3 :   DS             ds;
      18           3 :   Mat            X;
      19           3 :   Vec            x0;
      20           3 :   SlepcSC        sc;
      21           3 :   PetscReal      *T,*D,sigma,rnorm,aux,cond;
      22           3 :   PetscScalar    *U,*V,*w,d;
      23           3 :   PetscInt       i,n=10,l=0,k=0,ld;
      24           3 :   PetscViewer    viewer;
      25           3 :   PetscBool      verbose,test_dsview,extrarow;
      26             : 
      27           3 :   PetscFunctionBeginUser;
      28           3 :   PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
      29           3 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
      30           3 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Solve a Dense System of type GSVD with compact storage - dimension %" PetscInt_FMT "x%" PetscInt_FMT ".\n",n,n));
      31           3 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-l",&l,NULL));
      32           3 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-k",&k,NULL));
      33           3 :   PetscCheck(l<=n && k<=n && l<=k,PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Wrong value of dimensions");
      34           3 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-verbose",&verbose));
      35           3 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-test_dsview",&test_dsview));
      36           3 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-extrarow",&extrarow));
      37             : 
      38             :   /* Create DS object */
      39           3 :   PetscCall(DSCreate(PETSC_COMM_WORLD,&ds));
      40           3 :   PetscCall(DSSetType(ds,DSGSVD));
      41           3 :   PetscCall(DSSetFromOptions(ds));
      42           3 :   ld = n+2;  /* test leading dimension larger than n */
      43           3 :   PetscCall(DSAllocate(ds,ld));
      44           3 :   PetscCall(DSSetDimensions(ds,n,l,k));
      45           3 :   PetscCall(DSGSVDSetDimensions(ds,n,PETSC_DECIDE));
      46           3 :   PetscCall(DSSetCompact(ds,PETSC_TRUE));
      47           3 :   PetscCall(DSSetExtraRow(ds,extrarow));
      48             : 
      49             :   /* Set up viewer */
      50           3 :   PetscCall(PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer));
      51           3 :   PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL));
      52           3 :   PetscCall(DSView(ds,viewer));
      53           3 :   PetscCall(PetscViewerPopFormat(viewer));
      54             : 
      55           3 :   if (test_dsview) {
      56             :     /* Fill A and B with dummy values to test DSView */
      57           1 :     PetscCall(DSGetArrayReal(ds,DS_MAT_T,&T));
      58           1 :     PetscCall(DSGetArrayReal(ds,DS_MAT_D,&D));
      59          11 :     for (i=0;i<n;i++) { T[i] = i+1; D[i] = -i-1; }
      60          10 :     for (i=0;i<n-1;i++) { T[i+ld] = -1.0; T[i+2*ld] = 1.0; }
      61           1 :     PetscCall(DSRestoreArrayReal(ds,DS_MAT_T,&T));
      62           1 :     PetscCall(DSRestoreArrayReal(ds,DS_MAT_D,&D));
      63           1 :     PetscCall(DSView(ds,viewer));
      64             :   }
      65             : 
      66             :   /* Fill A and B with upper arrow-bidiagonal matrices
      67             :      verifying that [A;B] has orthonormal columns */
      68           3 :   PetscCall(DSGetArrayReal(ds,DS_MAT_T,&T));
      69           3 :   PetscCall(DSGetArrayReal(ds,DS_MAT_D,&D));
      70          33 :   for (i=0;i<n;i++) T[i] = (PetscReal)(i+1)/(n+1); /* diagonal of matrix A */
      71          11 :   for (i=0;i<k;i++) D[i] = PetscSqrtReal(1.0-T[i]*T[i]);
      72           9 :   for (i=l;i<k;i++) {
      73           6 :     T[i+ld] = PetscSqrtReal((1.0-T[k]*T[k])/(1.0+T[i]*T[i]/(D[i]*D[i])))*0.5*(1.0/k); /* upper diagonal of matrix A */
      74           6 :     T[i+2*ld] = -T[i+ld]*T[i]/D[i]; /* upper diagonal of matrix B */
      75             :   }
      76           3 :   aux = 1.0-T[k]*T[k];
      77           9 :   for (i=l;i<k;i++) aux -= T[i+ld]*T[i+ld]+T[i+2*ld]*T[i+2*ld];
      78           3 :   D[k] = PetscSqrtReal(aux);
      79          22 :   for (i=k;i<n-1;i++) {
      80          19 :     T[i+ld] = PetscSqrtReal((1.0-T[i+1]*T[i+1])/(1.0+T[i]*T[i]/(D[i]*D[i])))*0.5; /* upper diagonal of matrix A */
      81          19 :     T[i+2*ld] = -T[i+ld]*T[i]/D[i]; /* upper diagonal of matrix B */
      82          19 :     D[i+1] = PetscSqrtReal(1.0-T[i+1]*T[i+1]-T[ld+i]*T[ld+i]-T[2*ld+i]*T[2*ld+i]); /* diagonal of matrix B */
      83             :   }
      84           3 :   if (extrarow) { T[n-1+ld]=-1.0; T[n-1+2*ld]=1.0; }
      85             :   /* Fill locked eigenvalues */
      86           3 :   PetscCall(PetscMalloc1(n,&w));
      87           5 :   for (i=0;i<l;i++) w[i] = T[i]/D[i];
      88           3 :   PetscCall(DSRestoreArrayReal(ds,DS_MAT_T,&T));
      89           3 :   PetscCall(DSRestoreArrayReal(ds,DS_MAT_D,&D));
      90           3 :   if (l==0 && k==0) PetscCall(DSSetState(ds,DS_STATE_INTERMEDIATE));
      91           2 :   else PetscCall(DSSetState(ds,DS_STATE_RAW));
      92           3 :   if (verbose) {
      93           0 :     PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB));
      94           0 :     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Initial - - - - - - - - -\n"));
      95           0 :     PetscCall(DSView(ds,viewer));
      96             :   }
      97             : 
      98             :   /* Condition number */
      99           3 :   PetscCall(DSCond(ds,&cond));
     100           3 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Condition number = %.3f\n",(double)cond));
     101             : 
     102             :   /* Solve */
     103           3 :   PetscCall(DSGetSlepcSC(ds,&sc));
     104           3 :   sc->comparison    = SlepcCompareLargestReal;
     105           3 :   sc->comparisonctx = NULL;
     106           3 :   sc->map           = NULL;
     107           3 :   sc->mapobj        = NULL;
     108           3 :   PetscCall(DSSolve(ds,w,NULL));
     109           3 :   PetscCall(DSSort(ds,w,NULL,NULL,NULL,NULL));
     110           3 :   if (extrarow) PetscCall(DSUpdateExtraRow(ds));
     111           3 :   PetscCall(DSSynchronize(ds,w,NULL));
     112           3 :   if (verbose) {
     113           0 :     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"After solve - - - - - - - - -\n"));
     114           0 :     PetscCall(DSView(ds,viewer));
     115             :   }
     116             : 
     117             :   /* Print singular values */
     118           3 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Computed singular values =\n"));
     119          33 :   for (i=0;i<n;i++) {
     120          30 :     sigma = PetscRealPart(w[i]);
     121          30 :     PetscCall(PetscViewerASCIIPrintf(viewer,"  %.5f\n",(double)sigma));
     122             :   }
     123             : 
     124           3 :   if (extrarow) {
     125             :     /* Check that extra row is correct */
     126           1 :     PetscCall(DSGetArrayReal(ds,DS_MAT_T,&T));
     127           1 :     PetscCall(DSGetArray(ds,DS_MAT_U,&U));
     128           1 :     PetscCall(DSGetArray(ds,DS_MAT_V,&V));
     129             :     d = 0.0;
     130          11 :     for (i=0;i<n;i++) d += T[i+ld]+U[n-1+i*ld];
     131           1 :     if (PetscAbsScalar(d)>10*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: there is a mismatch in A's extra row of %g\n",(double)PetscAbsScalar(d)));
     132           1 :     d = 0.0;
     133          11 :     for (i=0;i<n;i++) d += T[i+2*ld]-V[n-1+i*ld];
     134           1 :     if (PetscAbsScalar(d)>10*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: there is a mismatch in B's extra row of %g\n",(double)PetscAbsScalar(d)));
     135           1 :     PetscCall(DSRestoreArrayReal(ds,DS_MAT_T,&T));
     136           1 :     PetscCall(DSRestoreArray(ds,DS_MAT_U,&U));
     137           1 :     PetscCall(DSRestoreArray(ds,DS_MAT_V,&V));
     138             :   }
     139             : 
     140             :   /* Singular vectors */
     141           3 :   PetscCall(DSVectors(ds,DS_MAT_X,NULL,NULL));  /* all singular vectors */
     142           3 :   PetscCall(DSGetMat(ds,DS_MAT_X,&X));
     143           3 :   PetscCall(MatCreateVecs(X,NULL,&x0));
     144           3 :   PetscCall(MatGetColumnVector(X,x0,0));
     145           3 :   PetscCall(VecNorm(x0,NORM_2,&rnorm));
     146           3 :   PetscCall(DSRestoreMat(ds,DS_MAT_X,&X));
     147           3 :   PetscCall(VecDestroy(&x0));
     148           3 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Norm of 1st X vector = %.3f\n",(double)rnorm));
     149             : 
     150           3 :   PetscCall(DSGetMat(ds,DS_MAT_U,&X));
     151           3 :   PetscCall(MatCreateVecs(X,NULL,&x0));
     152           3 :   PetscCall(MatGetColumnVector(X,x0,0));
     153           3 :   PetscCall(VecNorm(x0,NORM_2,&rnorm));
     154           3 :   PetscCall(DSRestoreMat(ds,DS_MAT_U,&X));
     155           3 :   PetscCall(VecDestroy(&x0));
     156           3 :   if (PetscAbs(rnorm-1.0)>10*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: the 1st U vector has norm %g\n",(double)rnorm));
     157             : 
     158           3 :   PetscCall(DSGetMat(ds,DS_MAT_V,&X));
     159           3 :   PetscCall(MatCreateVecs(X,NULL,&x0));
     160           3 :   PetscCall(MatGetColumnVector(X,x0,0));
     161           3 :   PetscCall(VecNorm(x0,NORM_2,&rnorm));
     162           3 :   PetscCall(DSRestoreMat(ds,DS_MAT_V,&X));
     163           3 :   PetscCall(VecDestroy(&x0));
     164           3 :   if (PetscAbs(rnorm-1.0)>10*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: the 1st V vector has norm %g\n",(double)rnorm));
     165             : 
     166           3 :   PetscCall(PetscFree(w));
     167           3 :   PetscCall(DSDestroy(&ds));
     168           3 :   PetscCall(SlepcFinalize());
     169             :   return 0;
     170             : }
     171             : 
     172             : /*TEST
     173             : 
     174             :    testset:
     175             :       requires: double
     176             :       test:
     177             :          suffix: 1
     178             :          args: -test_dsview
     179             :       test:
     180             :          suffix: 2
     181             :          args: -l 1 -k 4
     182             :       test:
     183             :          suffix: 2_extrarow
     184             :          filter: sed -e "s/extrarow//"
     185             :          args: -l 1 -k 4 -extrarow
     186             :          output_file: output/test22_2.out
     187             : 
     188             : TEST*/

Generated by: LCOV version 1.14