1b22c5e46SPierre Jolivet static char help[] = "Test MatConvert() with a MATNEST with scaled and shifted MATTRANSPOSEVIRTUAL blocks.\n\n"; 2b22c5e46SPierre Jolivet 3b22c5e46SPierre Jolivet #include <petscmat.h> 4b22c5e46SPierre Jolivet 5b22c5e46SPierre Jolivet /* 6b22c5e46SPierre Jolivet This example builds the matrix 7b22c5e46SPierre Jolivet 8b22c5e46SPierre Jolivet H = [ R C 9b22c5e46SPierre Jolivet alpha C^H + beta I gamma R^T + delta I ], 10b22c5e46SPierre Jolivet 11b22c5e46SPierre Jolivet where R is Hermitian and C is complex symmetric. In particular, R and C have the 12b22c5e46SPierre Jolivet following Toeplitz structure: 13b22c5e46SPierre Jolivet 14b22c5e46SPierre Jolivet R = pentadiag{a,b,c,conj(b),conj(a)} 15b22c5e46SPierre Jolivet C = tridiag{b,d,b} 16b22c5e46SPierre Jolivet 17b22c5e46SPierre Jolivet where a,b,d are complex scalars, and c is real. 18b22c5e46SPierre Jolivet */ 19b22c5e46SPierre Jolivet 20b22c5e46SPierre Jolivet int main(int argc, char **argv) 21b22c5e46SPierre Jolivet { 22b22c5e46SPierre Jolivet Mat block[4], H, R, C, M; 23b22c5e46SPierre Jolivet PetscScalar a, b, c, d; 24b22c5e46SPierre Jolivet PetscInt n = 13, Istart, Iend, i; 25b22c5e46SPierre Jolivet PetscBool flg; 26b22c5e46SPierre Jolivet 27b22c5e46SPierre Jolivet PetscFunctionBeginUser; 28c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 29b22c5e46SPierre Jolivet 30b22c5e46SPierre Jolivet PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL)); 31b22c5e46SPierre Jolivet 32b22c5e46SPierre Jolivet a = PetscCMPLX(-0.1, 0.2); 33b22c5e46SPierre Jolivet b = PetscCMPLX(1.0, 0.5); 34b22c5e46SPierre Jolivet c = 4.5; 35b22c5e46SPierre Jolivet d = PetscCMPLX(2.0, 0.2); 36b22c5e46SPierre Jolivet 37b22c5e46SPierre Jolivet PetscCall(MatCreate(PETSC_COMM_WORLD, &R)); 38b22c5e46SPierre Jolivet PetscCall(MatSetSizes(R, PETSC_DECIDE, PETSC_DECIDE, n, n)); 39b22c5e46SPierre Jolivet PetscCall(MatSetFromOptions(R)); 40b22c5e46SPierre Jolivet 41b22c5e46SPierre Jolivet PetscCall(MatCreate(PETSC_COMM_WORLD, &C)); 42b22c5e46SPierre Jolivet PetscCall(MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, n, n)); 43b22c5e46SPierre Jolivet PetscCall(MatSetFromOptions(C)); 44b22c5e46SPierre Jolivet 45b22c5e46SPierre Jolivet PetscCall(MatGetOwnershipRange(R, &Istart, &Iend)); 46b22c5e46SPierre Jolivet for (i = Istart; i < Iend; i++) { 47b22c5e46SPierre Jolivet if (i > 1) PetscCall(MatSetValue(R, i, i - 2, a, INSERT_VALUES)); 48b22c5e46SPierre Jolivet if (i > 0) PetscCall(MatSetValue(R, i, i - 1, b, INSERT_VALUES)); 49b22c5e46SPierre Jolivet PetscCall(MatSetValue(R, i, i, c, INSERT_VALUES)); 50b22c5e46SPierre Jolivet if (i < n - 1) PetscCall(MatSetValue(R, i, i + 1, PetscConj(b), INSERT_VALUES)); 51b22c5e46SPierre Jolivet if (i < n - 2) PetscCall(MatSetValue(R, i, i + 2, PetscConj(a), INSERT_VALUES)); 52b22c5e46SPierre Jolivet } 53b22c5e46SPierre Jolivet 54b22c5e46SPierre Jolivet PetscCall(MatGetOwnershipRange(C, &Istart, &Iend)); 55b22c5e46SPierre Jolivet for (i = Istart; i < Iend; i++) { 56b22c5e46SPierre Jolivet if (i > 0) PetscCall(MatSetValue(C, i, i - 1, b, INSERT_VALUES)); 57b22c5e46SPierre Jolivet PetscCall(MatSetValue(C, i, i, d, INSERT_VALUES)); 58b22c5e46SPierre Jolivet if (i < n - 1) PetscCall(MatSetValue(C, i, i + 1, b, INSERT_VALUES)); 59b22c5e46SPierre Jolivet } 60b22c5e46SPierre Jolivet 61b22c5e46SPierre Jolivet PetscCall(MatAssemblyBegin(R, MAT_FINAL_ASSEMBLY)); 62b22c5e46SPierre Jolivet PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 63b22c5e46SPierre Jolivet PetscCall(MatAssemblyEnd(R, MAT_FINAL_ASSEMBLY)); 64b22c5e46SPierre Jolivet PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 65b22c5e46SPierre Jolivet 66b22c5e46SPierre Jolivet block[0] = R; 67b22c5e46SPierre Jolivet block[1] = C; 68b22c5e46SPierre Jolivet 69b22c5e46SPierre Jolivet PetscCall(MatCreateHermitianTranspose(C, &block[2])); 70b22c5e46SPierre Jolivet PetscCall(MatScale(block[2], PetscConj(b))); 71b22c5e46SPierre Jolivet PetscCall(MatShift(block[2], d)); 72b22c5e46SPierre Jolivet PetscCall(MatCreateTranspose(R, &block[3])); 73b22c5e46SPierre Jolivet PetscCall(MatScale(block[3], PetscConj(d))); 74b22c5e46SPierre Jolivet PetscCall(MatShift(block[3], b)); 75b22c5e46SPierre Jolivet PetscCall(MatCreateNest(PetscObjectComm((PetscObject)R), 2, NULL, 2, NULL, block, &H)); 76b22c5e46SPierre Jolivet PetscCall(MatDestroy(&block[2])); 77b22c5e46SPierre Jolivet PetscCall(MatDestroy(&block[3])); 78b22c5e46SPierre Jolivet 79b22c5e46SPierre Jolivet PetscCall(MatConvert(H, MATAIJ, MAT_INITIAL_MATRIX, &M)); 80b22c5e46SPierre Jolivet PetscCall(MatMultEqual(H, M, 20, &flg)); 81b22c5e46SPierre Jolivet PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "MatNest != MatAIJ"); 82b22c5e46SPierre Jolivet 83b22c5e46SPierre Jolivet PetscCall(MatDestroy(&R)); 84b22c5e46SPierre Jolivet PetscCall(MatDestroy(&C)); 85b22c5e46SPierre Jolivet PetscCall(MatDestroy(&H)); 86b22c5e46SPierre Jolivet PetscCall(MatDestroy(&M)); 87b22c5e46SPierre Jolivet PetscCall(PetscFinalize()); 88b22c5e46SPierre Jolivet return 0; 89b22c5e46SPierre Jolivet } 90b22c5e46SPierre Jolivet 91b22c5e46SPierre Jolivet /*TEST 92b22c5e46SPierre Jolivet 93b22c5e46SPierre Jolivet build: 94b22c5e46SPierre Jolivet requires: complex 95b22c5e46SPierre Jolivet 96b22c5e46SPierre Jolivet test: 97*3886731fSPierre Jolivet output_file: output/empty.out 98b22c5e46SPierre Jolivet nsize: {{1 4}} 99b22c5e46SPierre Jolivet 100b22c5e46SPierre Jolivet TEST*/ 101