xref: /petsc/src/mat/impls/transpose/transm.c (revision 3c6db4c431ac39a10b8dd411361ad175785545d7)
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