static char help[] = "Tests MatTranspose(), MatNorm(), MatAXPY() and MatAYPX().\n\n"; #include static PetscErrorCode TransposeAXPY(Mat C,PetscScalar alpha,Mat mat,PetscErrorCode (*f)(Mat,Mat*)) { Mat D,E,F,G; MatType mtype; PetscFunctionBegin; PetscCall(MatGetType(mat,&mtype)); if (f == MatCreateTranspose) { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nMatAXPY: (C^T)^T = (C^T)^T + alpha * A, C=A, SAME_NONZERO_PATTERN\n")); } else { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nMatAXPY: (C^H)^H = (C^H)^H + alpha * A, C=A, SAME_NONZERO_PATTERN\n")); } PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,&C)); PetscCall(f(C,&D)); PetscCall(f(D,&E)); PetscCall(MatAXPY(E,alpha,mat,SAME_NONZERO_PATTERN)); PetscCall(MatConvert(E,mtype,MAT_INPLACE_MATRIX,&E)); PetscCall(MatView(E,PETSC_VIEWER_STDOUT_WORLD)); PetscCall(MatDestroy(&E)); PetscCall(MatDestroy(&D)); PetscCall(MatDestroy(&C)); if (f == MatCreateTranspose) { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: C = C + alpha * (A^T)^T, C=A, SAME_NONZERO_PATTERN\n")); } else { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: C = C + alpha * (A^H)^H, C=A, SAME_NONZERO_PATTERN\n")); } if (f == MatCreateTranspose) { PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&D)); } else { PetscCall(MatHermitianTranspose(mat,MAT_INITIAL_MATRIX,&D)); } PetscCall(f(D,&E)); PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,&C)); PetscCall(MatAXPY(C,alpha,E,SAME_NONZERO_PATTERN)); PetscCall(MatView(C,PETSC_VIEWER_STDOUT_WORLD)); PetscCall(MatDestroy(&E)); PetscCall(MatDestroy(&D)); PetscCall(MatDestroy(&C)); if (f == MatCreateTranspose) { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: (C^T)^T = (C^T)^T + alpha * (A^T)^T, C=A, SAME_NONZERO_PATTERN\n")); } else { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: (C^H)^H = (C^H)^H + alpha * (A^H)^H, C=A, SAME_NONZERO_PATTERN\n")); } PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,&C)); PetscCall(f(C,&D)); PetscCall(f(D,&E)); PetscCall(f(mat,&F)); PetscCall(f(F,&G)); PetscCall(MatAXPY(E,alpha,G,SAME_NONZERO_PATTERN)); PetscCall(MatConvert(E,mtype,MAT_INPLACE_MATRIX,&E)); PetscCall(MatView(E,PETSC_VIEWER_STDOUT_WORLD)); PetscCall(MatDestroy(&G)); PetscCall(MatDestroy(&F)); PetscCall(MatDestroy(&E)); PetscCall(MatDestroy(&D)); PetscCall(MatDestroy(&C)); /* Call f on a matrix that does not implement the transposition */ PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: Now without the transposition operation\n")); PetscCall(MatConvert(mat,MATSHELL,MAT_INITIAL_MATRIX,&C)); PetscCall(f(C,&D)); PetscCall(f(D,&E)); /* XXX cannot use MAT_INPLACE_MATRIX, it leaks mat */ PetscCall(MatConvert(E,mtype,MAT_INITIAL_MATRIX,&F)); PetscCall(MatAXPY(F,alpha,mat,SAME_NONZERO_PATTERN)); PetscCall(MatView(F,PETSC_VIEWER_STDOUT_WORLD)); PetscCall(MatDestroy(&F)); PetscCall(MatDestroy(&E)); PetscCall(MatDestroy(&D)); PetscCall(MatDestroy(&C)); PetscFunctionReturn(0); } int main(int argc,char **argv) { Mat mat,tmat = 0; PetscInt m = 7,n,i,j,rstart,rend,rect = 0; PetscMPIInt size,rank; PetscBool flg; PetscScalar v, alpha; PetscReal normf,normi,norm1; PetscCall(PetscInitialize(&argc,&argv,(char*)0,help)); PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_COMMON)); PetscCall(PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL)); PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); n = m; PetscCall(PetscOptionsHasName(NULL,NULL,"-rectA",&flg)); if (flg) {n += 2; rect = 1;} PetscCall(PetscOptionsHasName(NULL,NULL,"-rectB",&flg)); if (flg) {n -= 2; rect = 1;} /* ------- Assemble matrix --------- */ PetscCall(MatCreate(PETSC_COMM_WORLD,&mat)); PetscCall(MatSetSizes(mat,PETSC_DECIDE,PETSC_DECIDE,m,n)); PetscCall(MatSetFromOptions(mat)); PetscCall(MatSetUp(mat)); PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); for (i=rstart; i