Actual source code: test11.c
slepc-3.15.0 2021-03-31
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2021, 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[] = "Test BV block orthogonalization.\n\n";
13: #include <slepcbv.h>
15: /*
16: Compute the Frobenius norm ||A(l:k,l:k)-diag||_F
17: */
18: PetscErrorCode MyMatNorm(Mat A,PetscInt lda,PetscInt l,PetscInt k,PetscScalar diag,PetscReal *norm)
19: {
20: PetscErrorCode ierr;
21: PetscInt i,j;
22: const PetscScalar *pA;
23: PetscReal s,val;
26: MatDenseGetArrayRead(A,&pA);
27: s = 0.0;
28: for (i=l;i<k;i++) {
29: for (j=l;j<k;j++) {
30: val = (i==j)? PetscAbsScalar(pA[i+j*lda]-diag): PetscAbsScalar(pA[i+j*lda]);
31: s += val*val;
32: }
33: }
34: *norm = PetscSqrtReal(s);
35: MatDenseRestoreArrayRead(A,&pA);
36: return(0);
37: }
39: int main(int argc,char **argv)
40: {
42: BV X,Y,Z,cached;
43: Mat B=NULL,M,R=NULL;
44: Vec v,t;
45: PetscInt i,j,n=20,l=2,k=8,Istart,Iend;
46: PetscViewer view;
47: PetscBool withb,resid,rand,verbose;
48: PetscReal norm;
49: PetscScalar alpha;
51: SlepcInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
52: PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
53: PetscOptionsGetInt(NULL,NULL,"-l",&l,NULL);
54: PetscOptionsGetInt(NULL,NULL,"-k",&k,NULL);
55: PetscOptionsHasName(NULL,NULL,"-withb",&withb);
56: PetscOptionsHasName(NULL,NULL,"-resid",&resid);
57: PetscOptionsHasName(NULL,NULL,"-rand",&rand);
58: PetscOptionsHasName(NULL,NULL,"-verbose",&verbose);
59: PetscPrintf(PETSC_COMM_WORLD,"Test BV block orthogonalization (length %D, l=%D, k=%D)%s.\n",n,l,k,withb?" with non-standard inner product":"");
61: /* Create template vector */
62: VecCreate(PETSC_COMM_WORLD,&t);
63: VecSetSizes(t,PETSC_DECIDE,n);
64: VecSetFromOptions(t);
66: /* Create BV object X */
67: BVCreate(PETSC_COMM_WORLD,&X);
68: PetscObjectSetName((PetscObject)X,"X");
69: BVSetSizesFromVec(X,t,k);
70: BVSetFromOptions(X);
72: /* Set up viewer */
73: PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&view);
74: if (verbose) {
75: PetscViewerPushFormat(view,PETSC_VIEWER_ASCII_MATLAB);
76: }
78: /* Fill X entries */
79: if (rand) {
80: BVSetRandom(X);
81: } else {
82: for (j=0;j<k;j++) {
83: BVGetColumn(X,j,&v);
84: VecSet(v,0.0);
85: for (i=0;i<=n/2;i++) {
86: if (i+j<n) {
87: alpha = (3.0*i+j-2)/(2*(i+j+1));
88: VecSetValue(v,i+j,alpha,INSERT_VALUES);
89: }
90: }
91: VecAssemblyBegin(v);
92: VecAssemblyEnd(v);
93: BVRestoreColumn(X,j,&v);
94: }
95: }
96: if (verbose) {
97: BVView(X,view);
98: }
100: if (withb) {
101: /* Create inner product matrix */
102: MatCreate(PETSC_COMM_WORLD,&B);
103: MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,n,n);
104: MatSetFromOptions(B);
105: MatSetUp(B);
106: PetscObjectSetName((PetscObject)B,"B");
108: MatGetOwnershipRange(B,&Istart,&Iend);
109: for (i=Istart;i<Iend;i++) {
110: if (i>0) { MatSetValue(B,i,i-1,-1.0,INSERT_VALUES); }
111: if (i<n-1) { MatSetValue(B,i,i+1,-1.0,INSERT_VALUES); }
112: MatSetValue(B,i,i,2.0,INSERT_VALUES);
113: }
114: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
115: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
116: if (verbose) {
117: MatView(B,view);
118: }
119: BVSetMatrix(X,B,PETSC_FALSE);
120: }
122: /* Create copy on Y */
123: BVDuplicate(X,&Y);
124: PetscObjectSetName((PetscObject)Y,"Y");
125: BVCopy(X,Y);
126: MatCreateSeqDense(PETSC_COMM_SELF,k,k,NULL,&M);
128: if (resid) {
129: /* Create matrix R to store triangular factor */
130: MatCreateSeqDense(PETSC_COMM_SELF,k,k,NULL,&R);
131: PetscObjectSetName((PetscObject)R,"R");
132: }
134: if (l>0) {
135: /* First orthogonalize leading columns */
136: PetscPrintf(PETSC_COMM_WORLD,"Orthogonalizing leading columns\n");
137: BVSetActiveColumns(Y,0,l);
138: BVSetActiveColumns(X,0,l);
139: BVOrthogonalize(Y,R);
140: if (verbose) {
141: BVView(Y,view);
142: if (resid) { MatView(R,view); }
143: }
145: if (withb) {
146: /* Extract cached BV and check it is equal to B*X */
147: BVGetCachedBV(Y,&cached);
148: BVDuplicate(X,&Z);
149: BVSetMatrix(Z,NULL,PETSC_FALSE);
150: BVSetActiveColumns(Z,0,l);
151: BVCopy(X,Z);
152: BVMatMult(X,B,Z);
153: BVMult(Z,-1.0,1.0,cached,NULL);
154: BVNorm(Z,NORM_FROBENIUS,&norm);
155: if (norm<100*PETSC_MACHINE_EPSILON) {
156: PetscPrintf(PETSC_COMM_WORLD," Difference ||cached-BX|| < 100*eps\n");
157: } else {
158: PetscPrintf(PETSC_COMM_WORLD," Difference ||cached-BX||: %g\n",(double)norm);
159: }
160: BVDestroy(&Z);
161: }
163: /* Check orthogonality */
164: BVDot(Y,Y,M);
165: MyMatNorm(M,k,0,l,1.0,&norm);
166: if (norm<100*PETSC_MACHINE_EPSILON) {
167: PetscPrintf(PETSC_COMM_WORLD," Level of orthogonality of Q1 < 100*eps\n");
168: } else {
169: PetscPrintf(PETSC_COMM_WORLD," Level of orthogonality of Q1: %g\n",(double)norm);
170: }
172: if (resid) {
173: /* Check residual */
174: BVDuplicate(X,&Z);
175: BVSetMatrix(Z,NULL,PETSC_FALSE);
176: BVSetActiveColumns(Z,0,l);
177: BVCopy(X,Z);
178: BVMult(Z,-1.0,1.0,Y,R);
179: BVNorm(Z,NORM_FROBENIUS,&norm);
180: if (norm<100*PETSC_MACHINE_EPSILON) {
181: PetscPrintf(PETSC_COMM_WORLD," Residual ||X1-Q1*R11|| < 100*eps\n");
182: } else {
183: PetscPrintf(PETSC_COMM_WORLD," Residual ||X1-Q1*R11||: %g\n",(double)norm);
184: }
185: BVDestroy(&Z);
186: }
188: }
190: /* Now orthogonalize the rest of columns */
191: PetscPrintf(PETSC_COMM_WORLD,"Orthogonalizing active columns\n");
192: BVSetActiveColumns(Y,l,k);
193: BVSetActiveColumns(X,l,k);
194: BVOrthogonalize(Y,R);
195: if (verbose) {
196: BVView(Y,view);
197: if (resid) { MatView(R,view); }
198: }
200: if (l>0) {
201: /* Check orthogonality */
202: BVDot(Y,Y,M);
203: MyMatNorm(M,k,l,k,1.0,&norm);
204: if (norm<100*PETSC_MACHINE_EPSILON) {
205: PetscPrintf(PETSC_COMM_WORLD," Level of orthogonality of Q2 < 100*eps\n");
206: } else {
207: PetscPrintf(PETSC_COMM_WORLD," Level of orthogonality of Q2: %g\n",(double)norm);
208: }
209: }
211: /* Check the complete decomposition */
212: PetscPrintf(PETSC_COMM_WORLD,"Overall decomposition\n");
213: BVSetActiveColumns(Y,0,k);
214: BVSetActiveColumns(X,0,k);
216: /* Check orthogonality */
217: BVDot(Y,Y,M);
218: MyMatNorm(M,k,0,k,1.0,&norm);
219: if (norm<100*PETSC_MACHINE_EPSILON) {
220: PetscPrintf(PETSC_COMM_WORLD," Level of orthogonality of Q < 100*eps\n");
221: } else {
222: PetscPrintf(PETSC_COMM_WORLD," Level of orthogonality of Q: %g\n",(double)norm);
223: }
225: if (resid) {
226: /* Check residual */
227: BVMult(X,-1.0,1.0,Y,R);
228: BVSetMatrix(X,NULL,PETSC_FALSE);
229: BVNorm(X,NORM_FROBENIUS,&norm);
230: if (norm<100*PETSC_MACHINE_EPSILON) {
231: PetscPrintf(PETSC_COMM_WORLD," Residual ||X-Q*R|| < 100*eps\n");
232: } else {
233: PetscPrintf(PETSC_COMM_WORLD," Residual ||X-Q*R||: %g\n",(double)norm);
234: }
235: MatDestroy(&R);
236: }
238: if (B) { MatDestroy(&B); }
239: MatDestroy(&M);
240: BVDestroy(&X);
241: BVDestroy(&Y);
242: VecDestroy(&t);
243: SlepcFinalize();
244: return ierr;
245: }
247: /*TEST
249: testset:
250: args: -bv_orthog_block {{gs chol tsqr tsqrchol svqb}}
251: nsize: 2
252: output_file: output/test11_1.out
253: test:
254: suffix: 1
255: args: -bv_type {{vecs contiguous svec mat}shared output}
256: test:
257: suffix: 1_cuda
258: args: -bv_type svec -vec_type cuda
259: requires: cuda
261: testset:
262: args: -withb -bv_orthog_block {{gs chol svqb}}
263: nsize: 2
264: output_file: output/test11_4.out
265: test:
266: suffix: 4
267: args: -bv_type {{vecs contiguous svec mat}shared output}
268: test:
269: suffix: 4_cuda
270: args: -bv_type svec -vec_type cuda -mat_type aijcusparse
271: requires: cuda
273: testset:
274: args: -resid -bv_orthog_block {{gs chol tsqr tsqrchol svqb}}
275: nsize: 2
276: output_file: output/test11_6.out
277: test:
278: suffix: 6
279: args: -bv_type {{vecs contiguous svec mat}shared output}
280: test:
281: suffix: 6_cuda
282: args: -bv_type svec -vec_type cuda
283: requires: cuda
285: testset:
286: args: -resid -withb -bv_orthog_block {{gs chol svqb}}
287: nsize: 2
288: output_file: output/test11_9.out
289: test:
290: suffix: 9
291: args: -bv_type {{vecs contiguous svec mat}shared output}
292: test:
293: suffix: 9_cuda
294: args: -bv_type svec -vec_type cuda -mat_type aijcusparse
295: requires: cuda
297: testset:
298: args: -bv_orthog_block tsqr
299: nsize: 7
300: output_file: output/test11_1.out
301: test:
302: suffix: 11
303: args: -bv_type {{vecs contiguous svec mat}shared output}
304: requires: !valgrind
305: test:
306: suffix: 11_cuda
307: args: -bv_type svec -vec_type cuda
308: requires: cuda !valgrind
310: testset:
311: args: -resid -n 180 -l 0 -k 7 -bv_orthog_block tsqr
312: nsize: 9
313: output_file: output/test11_12.out
314: test:
315: suffix: 12
316: args: -bv_type {{vecs contiguous svec mat}shared output}
317: requires: !single !valgrind
318: test:
319: suffix: 12_cuda
320: args: -bv_type svec -vec_type cuda
321: requires: !single !valgrind cuda
323: TEST*/