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 DSSVD.\n\n";
12 :
13 : #include <slepcds.h>
14 :
15 4 : int main(int argc,char **argv)
16 : {
17 4 : DS ds;
18 4 : SlepcSC sc;
19 4 : PetscReal sigma,rnorm,aux;
20 4 : PetscScalar *A,*U,*w,d;
21 4 : PetscInt i,j,k,n=15,m=10,m1,ld;
22 4 : PetscViewer viewer;
23 4 : PetscBool verbose,extrarow;
24 :
25 4 : PetscFunctionBeginUser;
26 4 : PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
27 4 : PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
28 4 : PetscCall(PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL));
29 4 : k = PetscMin(n,m);
30 4 : PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Solve a Dense System of type SVD - dimension %" PetscInt_FMT "x%" PetscInt_FMT ".\n",n,m));
31 4 : PetscCall(PetscOptionsHasName(NULL,NULL,"-verbose",&verbose));
32 4 : PetscCall(PetscOptionsHasName(NULL,NULL,"-extrarow",&extrarow));
33 :
34 : /* Create DS object */
35 4 : PetscCall(DSCreate(PETSC_COMM_WORLD,&ds));
36 4 : PetscCall(DSSetType(ds,DSSVD));
37 4 : PetscCall(DSSetFromOptions(ds));
38 4 : ld = PetscMax(n,m)+2; /* test leading dimension larger than n */
39 4 : PetscCall(DSAllocate(ds,ld));
40 4 : PetscCall(DSSetDimensions(ds,n,0,0));
41 4 : PetscCall(DSSVDSetDimensions(ds,m));
42 4 : PetscCall(DSSVDGetDimensions(ds,&m1));
43 4 : PetscCheck(m1==m,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Inconsistent dimension value");
44 4 : PetscCall(DSSetExtraRow(ds,extrarow));
45 :
46 : /* Set up viewer */
47 4 : PetscCall(PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer));
48 4 : PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL));
49 4 : PetscCall(DSView(ds,viewer));
50 4 : PetscCall(PetscViewerPopFormat(viewer));
51 :
52 : /* Fill with a rectangular Toeplitz matrix */
53 4 : PetscCall(DSGetArray(ds,DS_MAT_A,&A));
54 44 : for (i=0;i<k;i++) A[i+i*ld]=1.0;
55 12 : for (j=1;j<3;j++) {
56 76 : for (i=0;i<m-j;i++) { if ((i+j)<m) A[i+(i+j)*ld]=(PetscScalar)(j+1); }
57 : }
58 28 : for (j=1;j<n/2;j++) {
59 300 : for (i=0;i<n-j;i++) { if ((i+j)<n && i<m) A[(i+j)+i*ld]=-1.0; }
60 : }
61 4 : if (extrarow) { A[n-2+m*ld]=1.0; A[n-1+m*ld]=1.0; } /* really an extra column */
62 4 : PetscCall(DSRestoreArray(ds,DS_MAT_A,&A));
63 4 : PetscCall(DSSetState(ds,DS_STATE_RAW));
64 4 : if (verbose) {
65 0 : PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB));
66 0 : PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Initial - - - - - - - - -\n"));
67 : }
68 4 : PetscCall(DSView(ds,viewer));
69 :
70 : /* Solve */
71 4 : PetscCall(PetscMalloc1(k,&w));
72 4 : PetscCall(DSGetSlepcSC(ds,&sc));
73 4 : sc->comparison = SlepcCompareLargestReal;
74 4 : sc->comparisonctx = NULL;
75 4 : sc->map = NULL;
76 4 : sc->mapobj = NULL;
77 4 : PetscCall(DSSolve(ds,w,NULL));
78 4 : PetscCall(DSSort(ds,w,NULL,NULL,NULL,NULL));
79 4 : if (extrarow) PetscCall(DSUpdateExtraRow(ds));
80 4 : if (verbose) {
81 0 : PetscCall(PetscPrintf(PETSC_COMM_WORLD,"After solve - - - - - - - - -\n"));
82 0 : PetscCall(DSView(ds,viewer));
83 : }
84 :
85 : /* Print singular values */
86 4 : PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Computed singular values =\n"));
87 44 : for (i=0;i<k;i++) {
88 40 : sigma = PetscRealPart(w[i]);
89 40 : PetscCall(PetscViewerASCIIPrintf(viewer," %.5f\n",(double)sigma));
90 : }
91 :
92 4 : if (extrarow) {
93 : /* Check that extra column is correct */
94 2 : PetscCall(DSGetArray(ds,DS_MAT_A,&A));
95 2 : PetscCall(DSGetArray(ds,DS_MAT_U,&U));
96 : d = 0.0;
97 32 : for (i=0;i<n;i++) d += A[i+m*ld]-U[n-2+i*ld]-U[n-1+i*ld];
98 2 : if (PetscAbsScalar(d)>10*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: there is a mismatch in the extra row of %g\n",(double)PetscAbsScalar(d)));
99 2 : PetscCall(DSRestoreArray(ds,DS_MAT_A,&A));
100 2 : PetscCall(DSRestoreArray(ds,DS_MAT_U,&U));
101 : }
102 :
103 : /* Singular vectors */
104 4 : PetscCall(DSVectors(ds,DS_MAT_U,NULL,NULL)); /* all singular vectors */
105 4 : j = 0;
106 4 : rnorm = 0.0;
107 4 : PetscCall(DSGetArray(ds,DS_MAT_U,&U));
108 64 : for (i=0;i<n;i++) {
109 60 : aux = PetscAbsScalar(U[i+j*ld]);
110 60 : rnorm += aux*aux;
111 : }
112 4 : PetscCall(DSRestoreArray(ds,DS_MAT_U,&U));
113 4 : rnorm = PetscSqrtReal(rnorm);
114 4 : PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Norm of 1st U vector = %.3f\n",(double)rnorm));
115 :
116 4 : PetscCall(PetscFree(w));
117 4 : PetscCall(DSDestroy(&ds));
118 4 : PetscCall(SlepcFinalize());
119 : return 0;
120 : }
121 :
122 : /*TEST
123 :
124 : test:
125 : args: -ds_method {{0 1}}
126 : suffix: 1
127 : filter: grep -v "solving the problem"
128 : requires: !single
129 :
130 : test:
131 : suffix: 2
132 : args: -extrarow -ds_method {{0 1}}
133 : filter: grep -v "solving the problem"
134 : requires: !single
135 :
136 : TEST*/
|