xref: /petsc/src/mat/tutorials/ex2.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
16aad120cSJose E. Roman static char help[] = "testing SeqDense matrices with an LDA (leading dimension of the user-allocated array) larger than M.\n";
2c4762a1bSJed Brown /*
3c4762a1bSJed Brown  * Example code testing SeqDense matrices with an LDA (leading dimension
46aad120cSJose E. Roman  * of the user-allocated array) larger than M.
5c4762a1bSJed Brown  * This example tests the functionality of MatSetValues(), MatMult(),
6c4762a1bSJed Brown  * and MatMultTranspose().
7c4762a1bSJed Brown  */
8c4762a1bSJed Brown 
9c4762a1bSJed Brown #include <petscmat.h>
10c4762a1bSJed Brown 
119371c9d4SSatish Balay int main(int argc, char **argv) {
12c4762a1bSJed Brown   Mat          A, A11, A12, A21, A22;
13c4762a1bSJed Brown   Vec          X, X1, X2, Y, Z, Z1, Z2;
14c4762a1bSJed Brown   PetscScalar *a, *b, *x, *y, *z, v, one = 1;
15c4762a1bSJed Brown   PetscReal    nrm;
16c4762a1bSJed Brown   PetscInt     size = 8, size1 = 6, size2 = 2, i, j;
17c4762a1bSJed Brown   PetscRandom  rnd;
18c4762a1bSJed Brown 
19327415f7SBarry Smith   PetscFunctionBeginUser;
209566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, 0, help));
219566063dSJacob Faibussowitsch   PetscCall(PetscRandomCreate(PETSC_COMM_SELF, &rnd));
22c4762a1bSJed Brown 
23c4762a1bSJed Brown   /*
24c4762a1bSJed Brown    * Create matrix and three vectors: these are all normal
25c4762a1bSJed Brown    */
269566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size * size, &a));
279566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size * size, &b));
28c4762a1bSJed Brown   for (i = 0; i < size; i++) {
29c4762a1bSJed Brown     for (j = 0; j < size; j++) {
309566063dSJacob Faibussowitsch       PetscCall(PetscRandomGetValue(rnd, &a[i + j * size]));
31c4762a1bSJed Brown       b[i + j * size] = a[i + j * size];
32c4762a1bSJed Brown     }
33c4762a1bSJed Brown   }
349566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_SELF, &A));
359566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A, size, size, size, size));
369566063dSJacob Faibussowitsch   PetscCall(MatSetType(A, MATSEQDENSE));
379566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(A, a));
389566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
399566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
40c4762a1bSJed Brown 
419566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size, &x));
429371c9d4SSatish Balay   for (i = 0; i < size; i++) { x[i] = one; }
439566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, size, x, &X));
449566063dSJacob Faibussowitsch   PetscCall(VecAssemblyBegin(X));
459566063dSJacob Faibussowitsch   PetscCall(VecAssemblyEnd(X));
46c4762a1bSJed Brown 
479566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size, &y));
489566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, size, y, &Y));
499566063dSJacob Faibussowitsch   PetscCall(VecAssemblyBegin(Y));
509566063dSJacob Faibussowitsch   PetscCall(VecAssemblyEnd(Y));
51c4762a1bSJed Brown 
529566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size, &z));
539566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, size, z, &Z));
549566063dSJacob Faibussowitsch   PetscCall(VecAssemblyBegin(Z));
559566063dSJacob Faibussowitsch   PetscCall(VecAssemblyEnd(Z));
56c4762a1bSJed Brown 
57c4762a1bSJed Brown   /*
58c4762a1bSJed Brown    * Now create submatrices and subvectors
59c4762a1bSJed Brown    */
609566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_SELF, &A11));
619566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A11, size1, size1, size1, size1));
629566063dSJacob Faibussowitsch   PetscCall(MatSetType(A11, MATSEQDENSE));
639566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(A11, b));
649566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(A11, size));
659566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A11, MAT_FINAL_ASSEMBLY));
669566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A11, MAT_FINAL_ASSEMBLY));
67c4762a1bSJed Brown 
689566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_SELF, &A12));
699566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A12, size1, size2, size1, size2));
709566063dSJacob Faibussowitsch   PetscCall(MatSetType(A12, MATSEQDENSE));
719566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(A12, b + size1 * size));
729566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(A12, size));
739566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A12, MAT_FINAL_ASSEMBLY));
749566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A12, MAT_FINAL_ASSEMBLY));
75c4762a1bSJed Brown 
769566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_SELF, &A21));
779566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A21, size2, size1, size2, size1));
789566063dSJacob Faibussowitsch   PetscCall(MatSetType(A21, MATSEQDENSE));
799566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(A21, b + size1));
809566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(A21, size));
819566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A21, MAT_FINAL_ASSEMBLY));
829566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A21, MAT_FINAL_ASSEMBLY));
83c4762a1bSJed Brown 
849566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_SELF, &A22));
859566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A22, size2, size2, size2, size2));
869566063dSJacob Faibussowitsch   PetscCall(MatSetType(A22, MATSEQDENSE));
879566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(A22, b + size1 * size + size1));
889566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(A22, size));
899566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A22, MAT_FINAL_ASSEMBLY));
909566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A22, MAT_FINAL_ASSEMBLY));
91c4762a1bSJed Brown 
929566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, size1, x, &X1));
939566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, size2, x + size1, &X2));
949566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, size1, z, &Z1));
959566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, size2, z + size1, &Z2));
96c4762a1bSJed Brown 
97c4762a1bSJed Brown   /*
98c4762a1bSJed Brown    * Now multiple matrix times input in two ways;
99c4762a1bSJed Brown    * compare the results
100c4762a1bSJed Brown    */
1019566063dSJacob Faibussowitsch   PetscCall(MatMult(A, X, Y));
1029566063dSJacob Faibussowitsch   PetscCall(MatMult(A11, X1, Z1));
1039566063dSJacob Faibussowitsch   PetscCall(MatMultAdd(A12, X2, Z1, Z1));
1049566063dSJacob Faibussowitsch   PetscCall(MatMult(A22, X2, Z2));
1059566063dSJacob Faibussowitsch   PetscCall(MatMultAdd(A21, X1, Z2, Z2));
1069566063dSJacob Faibussowitsch   PetscCall(VecAXPY(Z, -1.0, Y));
1079566063dSJacob Faibussowitsch   PetscCall(VecNorm(Z, NORM_2, &nrm));
108*48a46eb9SPierre Jolivet   if (nrm > 100.0 * PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test1; error norm=%g\n", (double)nrm));
109c4762a1bSJed Brown 
110c4762a1bSJed Brown   /*
111c4762a1bSJed Brown    * Next test: change both matrices
112c4762a1bSJed Brown    */
1139566063dSJacob Faibussowitsch   PetscCall(PetscRandomGetValue(rnd, &v));
114c4762a1bSJed Brown   i = 1;
115c4762a1bSJed Brown   j = size - 2;
1169566063dSJacob Faibussowitsch   PetscCall(MatSetValues(A, 1, &i, 1, &j, &v, INSERT_VALUES));
117c4762a1bSJed Brown   j -= size1;
1189566063dSJacob Faibussowitsch   PetscCall(MatSetValues(A12, 1, &i, 1, &j, &v, INSERT_VALUES));
1199566063dSJacob Faibussowitsch   PetscCall(PetscRandomGetValue(rnd, &v));
120c4762a1bSJed Brown   i = j = size1 + 1;
1219566063dSJacob Faibussowitsch   PetscCall(MatSetValues(A, 1, &i, 1, &j, &v, INSERT_VALUES));
122c4762a1bSJed Brown   i = j = 1;
1239566063dSJacob Faibussowitsch   PetscCall(MatSetValues(A22, 1, &i, 1, &j, &v, INSERT_VALUES));
1249566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
1259566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
1269566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A12, MAT_FINAL_ASSEMBLY));
1279566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A12, MAT_FINAL_ASSEMBLY));
1289566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A22, MAT_FINAL_ASSEMBLY));
1299566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A22, MAT_FINAL_ASSEMBLY));
130c4762a1bSJed Brown 
1319566063dSJacob Faibussowitsch   PetscCall(MatMult(A, X, Y));
1329566063dSJacob Faibussowitsch   PetscCall(MatMult(A11, X1, Z1));
1339566063dSJacob Faibussowitsch   PetscCall(MatMultAdd(A12, X2, Z1, Z1));
1349566063dSJacob Faibussowitsch   PetscCall(MatMult(A22, X2, Z2));
1359566063dSJacob Faibussowitsch   PetscCall(MatMultAdd(A21, X1, Z2, Z2));
1369566063dSJacob Faibussowitsch   PetscCall(VecAXPY(Z, -1.0, Y));
1379566063dSJacob Faibussowitsch   PetscCall(VecNorm(Z, NORM_2, &nrm));
138*48a46eb9SPierre Jolivet   if (nrm > 100.0 * PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test2; error norm=%g\n", (double)nrm));
139c4762a1bSJed Brown 
140c4762a1bSJed Brown   /*
141c4762a1bSJed Brown    * Transpose product
142c4762a1bSJed Brown    */
1439566063dSJacob Faibussowitsch   PetscCall(MatMultTranspose(A, X, Y));
1449566063dSJacob Faibussowitsch   PetscCall(MatMultTranspose(A11, X1, Z1));
1459566063dSJacob Faibussowitsch   PetscCall(MatMultTransposeAdd(A21, X2, Z1, Z1));
1469566063dSJacob Faibussowitsch   PetscCall(MatMultTranspose(A22, X2, Z2));
1479566063dSJacob Faibussowitsch   PetscCall(MatMultTransposeAdd(A12, X1, Z2, Z2));
1489566063dSJacob Faibussowitsch   PetscCall(VecAXPY(Z, -1.0, Y));
1499566063dSJacob Faibussowitsch   PetscCall(VecNorm(Z, NORM_2, &nrm));
150*48a46eb9SPierre Jolivet   if (nrm > 100.0 * PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test3; error norm=%g\n", (double)nrm));
1519566063dSJacob Faibussowitsch   PetscCall(PetscFree(a));
1529566063dSJacob Faibussowitsch   PetscCall(PetscFree(b));
1539566063dSJacob Faibussowitsch   PetscCall(PetscFree(x));
1549566063dSJacob Faibussowitsch   PetscCall(PetscFree(y));
1559566063dSJacob Faibussowitsch   PetscCall(PetscFree(z));
1569566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A));
1579566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A11));
1589566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A12));
1599566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A21));
1609566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A22));
161c4762a1bSJed Brown 
1629566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&X));
1639566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Y));
1649566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Z));
165c4762a1bSJed Brown 
1669566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&X1));
1679566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&X2));
1689566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Z1));
1699566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Z2));
1709566063dSJacob Faibussowitsch   PetscCall(PetscRandomDestroy(&rnd));
1719566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
172b122ec5aSJacob Faibussowitsch   return 0;
173c4762a1bSJed Brown }
174c4762a1bSJed Brown 
175c4762a1bSJed Brown /*TEST
176c4762a1bSJed Brown 
177c4762a1bSJed Brown    test:
178c4762a1bSJed Brown 
179c4762a1bSJed Brown TEST*/
180