Actual source code: ex52.c
slepc-3.18.3 2023-03-24
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7: SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9: */
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";
17: #include <slepcsvd.h>
19: int main(int argc,char **argv)
20: {
21: Mat A,Omega; /* operator matrix, signature matrix */
22: SVD svd; /* singular value problem solver context */
23: Mat At;
24: Vec u,v,vomega,*U,*V;
25: MatType Atype;
26: PetscReal tol,lev1=0.0,lev2=0.0;
27: PetscInt M,N,p=0,i,Istart,Iend,nconv;
28: char filename[PETSC_MAX_PATH_LEN];
29: PetscViewer viewer;
30: PetscBool flg,terse,skiporth=PETSC_FALSE,transpose=PETSC_FALSE;
33: SlepcInitialize(&argc,&argv,(char*)0,help);
35: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
36: Load matrix that defines the hyperbolic singular value problem
37: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
39: PetscPrintf(PETSC_COMM_WORLD,"\nHyperbolic singular value problem stored in file.\n\n");
40: PetscOptionsGetString(NULL,NULL,"-file",filename,sizeof(filename),&flg);
43: #if defined(PETSC_USE_COMPLEX)
44: PetscPrintf(PETSC_COMM_WORLD," Reading COMPLEX matrix from a binary file...\n");
45: #else
46: PetscPrintf(PETSC_COMM_WORLD," Reading REAL matrix from a binary file...\n");
47: #endif
48: PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_READ,&viewer);
49: MatCreate(PETSC_COMM_WORLD,&A);
50: MatSetFromOptions(A);
51: MatLoad(A,viewer);
52: PetscViewerDestroy(&viewer);
54: /* transpose the matrix if requested */
55: PetscOptionsGetBool(NULL,NULL,"-transpose",&transpose,NULL);
56: if (transpose) {
57: MatHermitianTranspose(A,MAT_INITIAL_MATRIX,&At);
58: MatDestroy(&A);
59: A = At;
60: }
62: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
63: Create the signature
64: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
66: MatGetSize(A,&M,&N);
67: PetscOptionsGetInt(NULL,NULL,"-p",&p,&flg);
70: PetscPrintf(PETSC_COMM_WORLD,"\n Matrix dimensions: %" PetscInt_FMT "x%" PetscInt_FMT,M,N);
71: PetscPrintf(PETSC_COMM_WORLD,", using signature Omega=blkdiag(-I_%" PetscInt_FMT ",I_%" PetscInt_FMT ")\n\n",p,M-p);
73: MatCreateVecs(A,NULL,&vomega);
74: VecSet(vomega,1.0);
75: VecGetOwnershipRange(vomega,&Istart,&Iend);
76: for (i=Istart;i<Iend;i++) {
77: if (i<p) VecSetValue(vomega,i,-1.0,INSERT_VALUES);
78: }
79: VecAssemblyBegin(vomega);
80: VecAssemblyEnd(vomega);
82: MatGetType(A,&Atype);
83: MatCreate(PETSC_COMM_WORLD,&Omega);
84: MatSetSizes(Omega,PETSC_DECIDE,PETSC_DECIDE,M,M);
85: MatSetType(Omega,Atype);
86: MatSetUp(Omega);
87: MatDiagonalSet(Omega,vomega,INSERT_VALUES);
89: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
90: Create the singular value solver and set various options
91: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
93: SVDCreate(PETSC_COMM_WORLD,&svd);
95: SVDSetOperators(svd,A,NULL);
96: SVDSetSignature(svd,vomega);
97: SVDSetProblemType(svd,SVD_HYPERBOLIC);
99: SVDSetFromOptions(svd);
101: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
102: Solve the problem, display solution
103: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
105: MatCreateVecs(A,&v,&u);
106: VecSet(u,1.0);
107: VecSet(v,1.0);
108: SVDSetInitialSpaces(svd,1,&v,1,&u);
109: SVDSolve(svd);
111: /* show detailed info unless -terse option is given by user */
112: PetscOptionsHasName(NULL,NULL,"-terse",&terse);
113: if (terse) SVDErrorView(svd,SVD_ERROR_NORM,NULL);
114: else {
115: PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO_DETAIL);
116: SVDConvergedReasonView(svd,PETSC_VIEWER_STDOUT_WORLD);
117: SVDErrorView(svd,SVD_ERROR_NORM,PETSC_VIEWER_STDOUT_WORLD);
118: PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);
119: }
121: /* check orthogonality */
122: PetscOptionsGetBool(NULL,NULL,"-skiporth",&skiporth,NULL);
123: SVDGetConverged(svd,&nconv);
124: if (nconv>0 && !skiporth) {
125: SVDGetTolerances(svd,&tol,NULL);
126: VecDuplicateVecs(u,nconv,&U);
127: VecDuplicateVecs(v,nconv,&V);
128: for (i=0;i<nconv;i++) SVDGetSingularTriplet(svd,i,NULL,U[i],V[i]);
129: VecCheckOrthonormality(U,nconv,NULL,nconv,Omega,NULL,&lev1);
130: VecCheckOrthonormality(V,nconv,NULL,nconv,NULL,NULL,&lev2);
131: if (lev1+lev2<20*tol) PetscPrintf(PETSC_COMM_WORLD,"Level of orthogonality below the tolerance\n");
132: else PetscPrintf(PETSC_COMM_WORLD,"Level of orthogonality: %g (U) %g (V)\n",(double)lev1,(double)lev2);
133: VecDestroyVecs(nconv,&U);
134: VecDestroyVecs(nconv,&V);
135: }
136: VecDestroy(&u);
137: VecDestroy(&v);
139: /* free work space */
140: SVDDestroy(&svd);
141: MatDestroy(&A);
142: MatDestroy(&Omega);
143: VecDestroy(&vomega);
144: SlepcFinalize();
145: return 0;
146: }
148: /*TEST
150: testset:
151: args: -file ${DATAFILESPATH}/matrices/real/illc1033.petsc -svd_nsv 62 -p 40 -terse
152: requires: double !complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
153: filter: grep -v Reading
154: output_file: output/ex52_1.out
155: test:
156: args: -svd_type cross -svd_cross_explicitmatrix {{0 1}} -svd_implicittranspose {{0 1}}
157: suffix: 1_cross
158: test:
159: args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}} -svd_ncv 300
160: suffix: 1_cyclic
162: testset:
163: args: -file ${DATAFILESPATH}/matrices/real/illc1033.petsc -transpose -svd_nsv 6 -p 130 -terse
164: requires: double !complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
165: filter: grep -v Reading
166: output_file: output/ex52_2.out
167: test:
168: args: -svd_type cross -svd_cross_explicitmatrix {{0 1}} -svd_implicittranspose {{0 1}} -svd_ncv 100
169: suffix: 2_cross
170: test:
171: args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}}
172: suffix: 2_cyclic
174: testset:
175: args: -file ${DATAFILESPATH}/matrices/complex/illc1033.petsc -svd_nsv 62 -p 40 -terse
176: requires: double complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
177: filter: grep -v Reading
178: output_file: output/ex52_1.out
179: test:
180: args: -svd_type cross -svd_cross_explicitmatrix {{0 1}}
181: suffix: 3_cross
182: test:
183: args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}}
184: suffix: 3_cyclic
186: testset:
187: args: -file ${DATAFILESPATH}/matrices/complex/illc1033.petsc -transpose -svd_nsv 6 -p 130 -terse
188: requires: double complex datafilespath !defined(PETSC_USE_64BIT_INDICES)
189: filter: grep -v Reading
190: output_file: output/ex52_2.out
191: test:
192: args: -svd_type cross -svd_cross_explicitmatrix {{0 1}} -svd_ncv 100
193: suffix: 4_cross
194: test:
195: args: -svd_type cyclic -svd_cyclic_explicitmatrix {{0 1}}
196: suffix: 4_cyclic
198: testset:
199: args: -file ${SLEPC_DIR}/share/slepc/datafiles/matrices/rdb200.petsc -svd_smallest -svd_nsv 3 -p 1 -terse
200: requires: double !complex !defined(PETSC_USE_64BIT_INDICES)
201: filter: grep -v Reading
202: output_file: output/ex52_5.out
203: test:
204: args: -svd_type cross -svd_max_it 1000
205: suffix: 5_cross
206: test:
207: args: -svd_type cyclic -svd_max_it 4000 -svd_cyclic_st_ksp_type preonly -svd_cyclic_st_pc_type jacobi
208: suffix: 5_cyclic
210: TEST*/