185e3dda7SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 385e3dda7SBarry Smith 485e3dda7SBarry Smith typedef struct { 585e3dda7SBarry Smith Mat A; 685e3dda7SBarry Smith } Mat_Transpose; 785e3dda7SBarry Smith 885e3dda7SBarry Smith PetscErrorCode MatMult_Transpose(Mat N,Vec x,Vec y) 985e3dda7SBarry Smith { 1085e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 1185e3dda7SBarry Smith PetscErrorCode ierr; 1285e3dda7SBarry Smith 1385e3dda7SBarry Smith PetscFunctionBegin; 1485e3dda7SBarry Smith ierr = MatMultTranspose(Na->A,x,y);CHKERRQ(ierr); 1585e3dda7SBarry Smith PetscFunctionReturn(0); 1685e3dda7SBarry Smith } 1785e3dda7SBarry Smith 1885e3dda7SBarry Smith PetscErrorCode MatMultAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 1985e3dda7SBarry Smith { 2085e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 2185e3dda7SBarry Smith PetscErrorCode ierr; 2285e3dda7SBarry Smith 2385e3dda7SBarry Smith PetscFunctionBegin; 2485e3dda7SBarry Smith ierr = MatMultTransposeAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 2585e3dda7SBarry Smith PetscFunctionReturn(0); 2685e3dda7SBarry Smith } 2785e3dda7SBarry Smith 2847a9afc9SBarry Smith PetscErrorCode MatMultTranspose_Transpose(Mat N,Vec x,Vec y) 2947a9afc9SBarry Smith { 3047a9afc9SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 3147a9afc9SBarry Smith PetscErrorCode ierr; 3247a9afc9SBarry Smith 3347a9afc9SBarry Smith PetscFunctionBegin; 3447a9afc9SBarry Smith ierr = MatMult(Na->A,x,y);CHKERRQ(ierr); 3547a9afc9SBarry Smith PetscFunctionReturn(0); 3647a9afc9SBarry Smith } 3747a9afc9SBarry Smith 3847a9afc9SBarry Smith PetscErrorCode MatMultTransposeAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 3947a9afc9SBarry Smith { 4047a9afc9SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 4147a9afc9SBarry Smith PetscErrorCode ierr; 4247a9afc9SBarry Smith 4347a9afc9SBarry Smith PetscFunctionBegin; 4447a9afc9SBarry Smith ierr = MatMultAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 4547a9afc9SBarry Smith PetscFunctionReturn(0); 4647a9afc9SBarry Smith } 4747a9afc9SBarry Smith 4885e3dda7SBarry Smith PetscErrorCode MatDestroy_Transpose(Mat N) 4985e3dda7SBarry Smith { 5085e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 5185e3dda7SBarry Smith PetscErrorCode ierr; 5285e3dda7SBarry Smith 5385e3dda7SBarry Smith PetscFunctionBegin; 546bf464f9SBarry Smith ierr = MatDestroy(&Na->A);CHKERRQ(ierr); 558060fb66Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);CHKERRQ(ierr); 56bf0cc555SLisandro Dalcin ierr = PetscFree(N->data);CHKERRQ(ierr); 5785e3dda7SBarry Smith PetscFunctionReturn(0); 5885e3dda7SBarry Smith } 5985e3dda7SBarry Smith 60d0de2241SAndrew Spott PetscErrorCode MatDuplicate_Transpose(Mat N, MatDuplicateOption op, Mat* m) 61d0de2241SAndrew Spott { 62d0de2241SAndrew Spott Mat_Transpose *Na = (Mat_Transpose*)N->data; 63d0de2241SAndrew Spott PetscErrorCode ierr; 64d0de2241SAndrew Spott 65d0de2241SAndrew Spott PetscFunctionBegin; 66d0de2241SAndrew Spott if (op == MAT_COPY_VALUES) { 67d0de2241SAndrew Spott ierr = MatTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); 68d0de2241SAndrew Spott } else if (op == MAT_DO_NOT_COPY_VALUES) { 69d0de2241SAndrew Spott ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); 70c837ededSStefano Zampini ierr = MatTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr); 71fb41c00aSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); 72d0de2241SAndrew Spott PetscFunctionReturn(0); 73d0de2241SAndrew Spott } 74d0de2241SAndrew Spott 75d9b48344SStefano Zampini PetscErrorCode MatCreateVecs_Transpose(Mat A,Vec *r, Vec *l) 76d9b48344SStefano Zampini { 77d9b48344SStefano Zampini Mat_Transpose *Aa = (Mat_Transpose*)A->data; 78d9b48344SStefano Zampini PetscErrorCode ierr; 79d9b48344SStefano Zampini 80d9b48344SStefano Zampini PetscFunctionBegin; 81d9b48344SStefano Zampini ierr = MatCreateVecs(Aa->A,l,r);CHKERRQ(ierr); 82d9b48344SStefano Zampini PetscFunctionReturn(0); 83d9b48344SStefano Zampini } 84d9b48344SStefano Zampini 856171f1c8SPierre Jolivet PetscErrorCode MatAXPY_Transpose(Mat Y,PetscScalar a,Mat X,MatStructure str) 866171f1c8SPierre Jolivet { 876171f1c8SPierre Jolivet Mat_Transpose *Ya = (Mat_Transpose*)Y->data; 886171f1c8SPierre Jolivet Mat_Transpose *Xa = (Mat_Transpose*)X->data; 896171f1c8SPierre Jolivet Mat M = Ya->A; 906171f1c8SPierre Jolivet Mat N = Xa->A; 916171f1c8SPierre Jolivet PetscErrorCode ierr; 926171f1c8SPierre Jolivet 936171f1c8SPierre Jolivet PetscFunctionBegin; 946171f1c8SPierre Jolivet ierr = MatAXPY(M,a,N,str);CHKERRQ(ierr); 956171f1c8SPierre Jolivet PetscFunctionReturn(0); 966171f1c8SPierre Jolivet } 976171f1c8SPierre Jolivet 9852c5f739Sprj- PetscErrorCode MatHasOperation_Transpose(Mat mat,MatOperation op,PetscBool *has) 9952c5f739Sprj- { 10052c5f739Sprj- Mat_Transpose *X = (Mat_Transpose*)mat->data; 10152c5f739Sprj- PetscErrorCode ierr; 10252c5f739Sprj- PetscFunctionBegin; 10352c5f739Sprj- 10452c5f739Sprj- *has = PETSC_FALSE; 105*3c6db4c4SPierre Jolivet if (op == MATOP_MULT) { 106*3c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT_TRANSPOSE,has);CHKERRQ(ierr); 107*3c6db4c4SPierre Jolivet } else if (op == MATOP_MULT_TRANSPOSE) { 108*3c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT,has);CHKERRQ(ierr); 109*3c6db4c4SPierre Jolivet } else if (op == MATOP_MULT_ADD) { 110*3c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT_TRANSPOSE_ADD,has);CHKERRQ(ierr); 111*3c6db4c4SPierre Jolivet } else if (op == MATOP_MULT_TRANSPOSE_ADD) { 112*3c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT_ADD,has);CHKERRQ(ierr); 113*3c6db4c4SPierre Jolivet } else if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 11452c5f739Sprj- PetscFunctionReturn(0); 11552c5f739Sprj- } 11652c5f739Sprj- 1178060fb66Sstefano_zampini PetscErrorCode MatTransposeGetMat_Transpose(Mat A,Mat *M) 1188060fb66Sstefano_zampini { 1198060fb66Sstefano_zampini Mat_Transpose *Aa = (Mat_Transpose*)A->data; 1208060fb66Sstefano_zampini 1218060fb66Sstefano_zampini PetscFunctionBegin; 1228060fb66Sstefano_zampini *M = Aa->A; 1238060fb66Sstefano_zampini PetscFunctionReturn(0); 1248060fb66Sstefano_zampini } 1258060fb66Sstefano_zampini 1268060fb66Sstefano_zampini /*@ 12706511a5cSPierre Jolivet MatTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT 1288060fb66Sstefano_zampini 1298060fb66Sstefano_zampini Logically collective on Mat 1308060fb66Sstefano_zampini 1318060fb66Sstefano_zampini Input Parameter: 1328060fb66Sstefano_zampini . A - the MATTRANSPOSE matrix 1338060fb66Sstefano_zampini 1348060fb66Sstefano_zampini Output Parameter: 1358060fb66Sstefano_zampini . M - the matrix object stored inside A 1368060fb66Sstefano_zampini 1378060fb66Sstefano_zampini Level: intermediate 1388060fb66Sstefano_zampini 1398060fb66Sstefano_zampini .seealso: MatCreateTranspose() 1408060fb66Sstefano_zampini 1418060fb66Sstefano_zampini @*/ 1428060fb66Sstefano_zampini PetscErrorCode MatTransposeGetMat(Mat A,Mat *M) 1438060fb66Sstefano_zampini { 1448060fb66Sstefano_zampini PetscErrorCode ierr; 1458060fb66Sstefano_zampini 1468060fb66Sstefano_zampini PetscFunctionBegin; 1478060fb66Sstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1488060fb66Sstefano_zampini PetscValidType(A,1); 1498060fb66Sstefano_zampini PetscValidPointer(M,2); 1508060fb66Sstefano_zampini ierr = PetscUseMethod(A,"MatTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); 1518060fb66Sstefano_zampini PetscFunctionReturn(0); 1528060fb66Sstefano_zampini } 153d0de2241SAndrew Spott 15485e3dda7SBarry Smith /*@ 15585e3dda7SBarry Smith MatCreateTranspose - Creates a new matrix object that behaves like A' 15685e3dda7SBarry Smith 15785e3dda7SBarry Smith Collective on Mat 15885e3dda7SBarry Smith 15985e3dda7SBarry Smith Input Parameter: 16085e3dda7SBarry Smith . A - the (possibly rectangular) matrix 16185e3dda7SBarry Smith 16285e3dda7SBarry Smith Output Parameter: 16385e3dda7SBarry Smith . N - the matrix that represents A' 16485e3dda7SBarry Smith 16585e3dda7SBarry Smith Level: intermediate 16685e3dda7SBarry Smith 16795452b02SPatrick Sanan Notes: 16895452b02SPatrick Sanan The transpose A' is NOT actually formed! Rather the new matrix 16985e3dda7SBarry Smith object performs the matrix-vector product by using the MatMultTranspose() on 17085e3dda7SBarry Smith the original matrix 17185e3dda7SBarry Smith 17285e3dda7SBarry Smith .seealso: MatCreateNormal(), MatMult(), MatMultTranspose(), MatCreate() 17385e3dda7SBarry Smith 17485e3dda7SBarry Smith @*/ 1757087cfbeSBarry Smith PetscErrorCode MatCreateTranspose(Mat A,Mat *N) 17685e3dda7SBarry Smith { 17785e3dda7SBarry Smith PetscErrorCode ierr; 17885e3dda7SBarry Smith PetscInt m,n; 17985e3dda7SBarry Smith Mat_Transpose *Na; 18085e3dda7SBarry Smith 18185e3dda7SBarry Smith PetscFunctionBegin; 18285e3dda7SBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 183ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); 18485e3dda7SBarry Smith ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 185d97d01c0SJed Brown ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); 186d97d01c0SJed Brown ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); 187557cca28SSatish Balay ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); 18885e3dda7SBarry Smith 189b00a9115SJed Brown ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); 19085e3dda7SBarry Smith (*N)->data = (void*) Na; 19185e3dda7SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 19285e3dda7SBarry Smith Na->A = A; 19385e3dda7SBarry Smith 19485e3dda7SBarry Smith (*N)->ops->destroy = MatDestroy_Transpose; 19585e3dda7SBarry Smith (*N)->ops->mult = MatMult_Transpose; 1966d12b599SJed Brown (*N)->ops->multadd = MatMultAdd_Transpose; 19747a9afc9SBarry Smith (*N)->ops->multtranspose = MatMultTranspose_Transpose; 19847a9afc9SBarry Smith (*N)->ops->multtransposeadd = MatMultTransposeAdd_Transpose; 199d0de2241SAndrew Spott (*N)->ops->duplicate = MatDuplicate_Transpose; 200d9b48344SStefano Zampini (*N)->ops->getvecs = MatCreateVecs_Transpose; 2016171f1c8SPierre Jolivet (*N)->ops->axpy = MatAXPY_Transpose; 20252c5f739Sprj- (*N)->ops->hasoperation = MatHasOperation_Transpose; 20385e3dda7SBarry Smith (*N)->assembled = PETSC_TRUE; 20485e3dda7SBarry Smith 2058060fb66Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatTransposeGetMat_Transpose);CHKERRQ(ierr); 20633d57670SJed Brown ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 207037c98a2SJed Brown ierr = MatSetUp(*N);CHKERRQ(ierr); 20885e3dda7SBarry Smith PetscFunctionReturn(0); 20985e3dda7SBarry Smith } 21085e3dda7SBarry Smith 211