Actual source code: ex93.c
petsc-3.4.5 2014-06-29
1: static char help[] = "Test MatMatMult() and MatPtAP() for AIJ matrices.\n\n";
3: #include <petscmat.h>
5: extern PetscErrorCode testPTAPRectangular(void);
9: int main(int argc,char **argv)
10: {
11: Mat A,B,C,D;
12: PetscScalar a[] ={1.,1.,0.,0.,1.,1.,0.,0.,1.};
13: PetscInt ij[]={0,1,2};
14: PetscScalar none=-1.;
16: PetscReal fill=4;
17: PetscReal norm;
18: PetscMPIInt size,rank;
20: PetscInitialize(&argc,&argv,(char*)0,help);
21: MPI_Comm_size(PETSC_COMM_WORLD,&size);
22: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
24: MatCreate(PETSC_COMM_WORLD,&A);
25: MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,3,3);
26: MatSetType(A,MATAIJ);
27: MatSetUp(A);
28: MatSetOption(A,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);
29: if (!rank) {
30: MatSetValues(A,3,ij,3,ij,a,ADD_VALUES);
31: }
32: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
33: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
34: MatSetOptionsPrefix(A,"A_");
35: MatView(A,PETSC_VIEWER_STDOUT_WORLD);
36: PetscPrintf(PETSC_COMM_WORLD,"\n");
38: /* Test MatMatMult() */
39: MatTranspose(A,MAT_INITIAL_MATRIX,&B); /* B = A^T */
40: MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C); /* C = B*A */
41: MatMatMultNumeric(B,A,C); /* recompute C=B*A */
42: MatMatMult(B,A,MAT_REUSE_MATRIX,fill,&C); /* recompute C=B*A */
43: MatSetOptionsPrefix(C,"C_");
44: MatView(C,PETSC_VIEWER_STDOUT_WORLD);
45: if (!rank) {PetscPrintf(PETSC_COMM_SELF,"\n");}
47: MatMatMultSymbolic(C,A,fill,&D);
48: MatMatMultNumeric(C,A,D); /* D = C*A = (A^T*A)*A */
49: MatSetOptionsPrefix(D,"D_");
50: MatView(D,PETSC_VIEWER_STDOUT_WORLD);
51: if (!rank) {PetscPrintf(PETSC_COMM_SELF,"\n");}
53: /* Repeat the numeric product to test reuse of the previous symbolic product */
54: MatMatMultNumeric(C,A,D);
55: MatView(D,PETSC_VIEWER_STDOUT_WORLD);
56: if (!rank) {PetscPrintf(PETSC_COMM_SELF,"\n");}
58: MatDestroy(&B);
59: MatDestroy(&C);
61: /* Test PtAP routine. */
62: MatDuplicate(A,MAT_COPY_VALUES,&B); /* B = A */
63: MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C); /* C = B^T*A*B */
64: MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN);
65: MatNorm(D,NORM_FROBENIUS,&norm);
66: if (norm > 1.e-15 && !rank) {
67: PetscPrintf(PETSC_COMM_SELF,"Error in MatPtAP: %g\n",norm);
68: }
69: MatDestroy(&C);
70: MatDestroy(&D);
72: /* Repeat PtAP to test symbolic/numeric separation for reuse of the symbolic product */
73: MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C);
74: MatSetOptionsPrefix(C,"C=BtAB_");
75: MatView(C,PETSC_VIEWER_STDOUT_WORLD);
76: PetscPrintf(PETSC_COMM_WORLD,"\n");
78: MatPtAPSymbolic(A,B,fill,&D);
79: MatPtAPNumeric(A,B,D);
80: MatSetOptionsPrefix(D,"D=BtAB_");
81: MatView(D,PETSC_VIEWER_STDOUT_WORLD);
82: PetscPrintf(PETSC_COMM_WORLD,"\n");
84: /* Repeat numeric product to test reuse of the previous symbolic product */
85: MatPtAPNumeric(A,B,D);
86: MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN);
87: MatNorm(D,NORM_FROBENIUS,&norm);
88: if (norm > 1.e-15) {
89: PetscPrintf(PETSC_COMM_WORLD,"Error in symbolic/numeric MatPtAP: %g\n",norm);
90: }
91: MatDestroy(&B);
92: MatDestroy(&C);
93: MatDestroy(&D);
95: if (size == 1) {
96: /* A test contributed by Tobias Neckel <neckel@in.tum.de> */
97: testPTAPRectangular();
99: /* test MatMatTransposeMult(): A*B^T */
100: MatMatTransposeMult(A,A,MAT_INITIAL_MATRIX,fill,&D); /* D = A*A^T */
101: MatSetOptionsPrefix(D,"D=A*A^T_");
102: MatView(D,PETSC_VIEWER_STDOUT_WORLD);
103: PetscPrintf(PETSC_COMM_WORLD,"\n");
105: MatTranspose(A,MAT_INITIAL_MATRIX,&B); /* B = A^T */
106: MatMatMult(A,B,MAT_INITIAL_MATRIX,fill,&C); /* C=A*B */
107: MatSetOptionsPrefix(C,"D=A*B=A*A^T_");
108: MatView(C,PETSC_VIEWER_STDOUT_WORLD);
109: PetscPrintf(PETSC_COMM_WORLD,"\n");
110: }
112: MatDestroy(&A);
113: MatDestroy(&B);
114: MatDestroy(&C);
115: MatDestroy(&D);
116: PetscFinalize();
117: return(0);
118: }
120: /* a test contributed by Tobias Neckel <neckel@in.tum.de>, 02 Jul 2008 */
121: #define PETSc_CHKERRQ CHKERRQ
124: PetscErrorCode testPTAPRectangular(void)
125: {
127: const int rows = 3;
128: const int cols = 5;
129: PetscErrorCode _ierr;
130: int i;
131: Mat A;
132: Mat P;
133: Mat C;
136: /* set up A */
137: _MatCreateSeqAIJ(PETSC_COMM_WORLD, rows, rows,1, NULL, &A);
138: PETSc_CHKERRQ(_ierr);
139: for (i=0; i<rows; i++) {
140: _MatSetValue(A, i, i, 1.0, INSERT_VALUES);
141: PETSc_CHKERRQ(_ierr);
142: }
143: _MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
144: PETSc_CHKERRQ(_ierr);
145: _MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
146: PETSc_CHKERRQ(_ierr);
148: /* set up P */
149: _MatCreateSeqAIJ(PETSC_COMM_WORLD, rows, cols,5, NULL, &P);
150: PETSc_CHKERRQ(_ierr);
151: _MatSetValue(P, 0, 0, 1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
152: _MatSetValue(P, 0, 1, 2.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
153: _MatSetValue(P, 0, 2, 0.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
155: _MatSetValue(P, 0, 3, -1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
157: _MatSetValue(P, 1, 0, 0.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
158: _MatSetValue(P, 1, 1, -1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
159: _MatSetValue(P, 1, 2, 1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
161: _MatSetValue(P, 2, 0, 3.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
162: _MatSetValue(P, 2, 1, 0.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
163: _MatSetValue(P, 2, 2, -3.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr);
165: _MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
166: PETSc_CHKERRQ(_ierr);
167: _MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
168: PETSc_CHKERRQ(_ierr);
170: /* compute C */
171: _MatPtAP(A, P, MAT_INITIAL_MATRIX, 1.0, &C);
172: PETSc_CHKERRQ(_ierr);
174: _MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
175: PETSc_CHKERRQ(_ierr);
176: _MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);
177: PETSc_CHKERRQ(_ierr);
179: /* compare results */
180: /*
181: printf("C:\n");
182: _MatView(C,PETSC_VIEWER_STDOUT_WORLD);PETSc_CHKERRQ(_ierr);
184: blitz::Array<double,2> actualC(cols, cols);
185: actualC = 0.0;
186: for (int i=0; i<cols; i++) {
187: for (int j=0; j<cols; j++) {
188: _MatGetValues(C, 1, &i, 1, &j, &actualC(i,j));
189: PETSc_CHKERRQ(_ierr); ;
190: }
191: }
192: blitz::Array<double,2> expectedC(cols, cols);
193: expectedC = 0.0;
195: expectedC(0,0) = 10.0;
196: expectedC(0,1) = 2.0;
197: expectedC(0,2) = -9.0;
198: expectedC(0,3) = -1.0;
199: expectedC(1,0) = 2.0;
200: expectedC(1,1) = 5.0;
201: expectedC(1,2) = -1.0;
202: expectedC(1,3) = -2.0;
203: expectedC(2,0) = -9.0;
204: expectedC(2,1) = -1.0;
205: expectedC(2,2) = 10.0;
206: expectedC(2,3) = 0.0;
207: expectedC(3,0) = -1.0;
208: expectedC(3,1) = -2.0;
209: expectedC(3,2) = 0.0;
210: expectedC(3,3) = 1.0;
212: int check = areBlitzArrays2NumericallyEqual(actualC,expectedC);
213: validateEqualsWithParams3(check, -1 , "testPTAPRectangular()", check, actualC(check), expectedC(check));
214: */
216: _MatDestroy(&A);
217: PETSc_CHKERRQ(_ierr);
218: _MatDestroy(&P);
219: PETSc_CHKERRQ(_ierr);
220: _MatDestroy(&C);
221: PETSc_CHKERRQ(_ierr);
222: return(0);
223: }