xref: /petsc/src/mat/impls/transpose/htransm.c (revision 6a4403aae2f57690d1c7fe38bfb43de1fb325a1b)
1d0de2241SAndrew Spott 
2af0996ceSBarry Smith #include <petsc/private/matimpl.h>          /*I "petscmat.h" I*/
3d0de2241SAndrew Spott 
4d0de2241SAndrew Spott typedef struct {
5d0de2241SAndrew Spott   Mat A;
6fb41c00aSBarry Smith } Mat_HT;
7d0de2241SAndrew Spott 
8fb41c00aSBarry Smith PetscErrorCode MatMult_HT(Mat N,Vec x,Vec y)
9d0de2241SAndrew Spott {
10fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
11d0de2241SAndrew Spott   PetscErrorCode ierr;
12d0de2241SAndrew Spott 
13d0de2241SAndrew Spott   PetscFunctionBegin;
14d0de2241SAndrew Spott   ierr = MatMultHermitianTranspose(Na->A,x,y);CHKERRQ(ierr);
15d0de2241SAndrew Spott   PetscFunctionReturn(0);
16d0de2241SAndrew Spott }
17d0de2241SAndrew Spott 
18fb41c00aSBarry Smith PetscErrorCode MatMultAdd_HT(Mat N,Vec v1,Vec v2,Vec v3)
19d0de2241SAndrew Spott {
20fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
21d0de2241SAndrew Spott   PetscErrorCode ierr;
22d0de2241SAndrew Spott 
23d0de2241SAndrew Spott   PetscFunctionBegin;
24d0de2241SAndrew Spott   ierr = MatMultHermitianTransposeAdd(Na->A,v1,v2,v3);CHKERRQ(ierr);
25d0de2241SAndrew Spott   PetscFunctionReturn(0);
26d0de2241SAndrew Spott }
27d0de2241SAndrew Spott 
28fb41c00aSBarry Smith PetscErrorCode MatMultHermitianTranspose_HT(Mat N,Vec x,Vec y)
29d0de2241SAndrew Spott {
30fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
31d0de2241SAndrew Spott   PetscErrorCode ierr;
32d0de2241SAndrew Spott 
33d0de2241SAndrew Spott   PetscFunctionBegin;
34d0de2241SAndrew Spott   ierr = MatMult(Na->A,x,y);CHKERRQ(ierr);
35d0de2241SAndrew Spott   PetscFunctionReturn(0);
36d0de2241SAndrew Spott }
37d0de2241SAndrew Spott 
38fb41c00aSBarry Smith PetscErrorCode MatMultHermitianTransposeAdd_HT(Mat N,Vec v1,Vec v2,Vec v3)
39d0de2241SAndrew Spott {
40fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
41d0de2241SAndrew Spott   PetscErrorCode ierr;
42d0de2241SAndrew Spott 
43d0de2241SAndrew Spott   PetscFunctionBegin;
44d0de2241SAndrew Spott   ierr = MatMultAdd(Na->A,v1,v2,v3);CHKERRQ(ierr);
45d0de2241SAndrew Spott   PetscFunctionReturn(0);
46d0de2241SAndrew Spott }
47d0de2241SAndrew Spott 
48fb41c00aSBarry Smith PetscErrorCode MatDestroy_HT(Mat N)
49d0de2241SAndrew Spott {
50fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
51d0de2241SAndrew Spott   PetscErrorCode ierr;
52d0de2241SAndrew Spott 
53d0de2241SAndrew Spott   PetscFunctionBegin;
54d0de2241SAndrew Spott   ierr = MatDestroy(&Na->A);CHKERRQ(ierr);
55204606b3SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)N,"MatHermitianTransposeGetMat_C",NULL);CHKERRQ(ierr);
56204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
57204606b3SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);CHKERRQ(ierr);
586718818eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)N,"MatProductSetFromOptions_anytype_C",NULL);CHKERRQ(ierr);
59204606b3SStefano Zampini #endif
60d0de2241SAndrew Spott   ierr = PetscFree(N->data);CHKERRQ(ierr);
61d0de2241SAndrew Spott   PetscFunctionReturn(0);
62d0de2241SAndrew Spott }
63d0de2241SAndrew Spott 
64fb41c00aSBarry Smith PetscErrorCode MatDuplicate_HT(Mat N, MatDuplicateOption op, Mat* m)
65d0de2241SAndrew Spott {
66fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
67d0de2241SAndrew Spott   PetscErrorCode ierr;
68d0de2241SAndrew Spott 
69d0de2241SAndrew Spott   PetscFunctionBegin;
70d0de2241SAndrew Spott   if (op == MAT_COPY_VALUES) {
71d0de2241SAndrew Spott     ierr = MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr);
72d0de2241SAndrew Spott   } else if (op == MAT_DO_NOT_COPY_VALUES) {
73d0de2241SAndrew Spott     ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr);
74f79c2134SBarry Smith     ierr = MatHermitianTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr);
75fb41c00aSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type");
76d0de2241SAndrew Spott   PetscFunctionReturn(0);
77d0de2241SAndrew Spott }
78d0de2241SAndrew Spott 
7906511a5cSPierre Jolivet PetscErrorCode MatCreateVecs_HT(Mat N,Vec *r, Vec *l)
8006511a5cSPierre Jolivet {
8106511a5cSPierre Jolivet   Mat_HT         *Na = (Mat_HT*)N->data;
8206511a5cSPierre Jolivet   PetscErrorCode ierr;
8306511a5cSPierre Jolivet 
8406511a5cSPierre Jolivet   PetscFunctionBegin;
8506511a5cSPierre Jolivet   ierr = MatCreateVecs(Na->A,l,r);CHKERRQ(ierr);
8606511a5cSPierre Jolivet   PetscFunctionReturn(0);
8706511a5cSPierre Jolivet }
8806511a5cSPierre Jolivet 
896171f1c8SPierre Jolivet PetscErrorCode MatAXPY_HT(Mat Y,PetscScalar a,Mat X,MatStructure str)
906171f1c8SPierre Jolivet {
916171f1c8SPierre Jolivet   Mat_HT         *Ya = (Mat_HT*)Y->data;
926171f1c8SPierre Jolivet   Mat_HT         *Xa = (Mat_HT*)X->data;
936171f1c8SPierre Jolivet   Mat              M = Ya->A;
946171f1c8SPierre Jolivet   Mat              N = Xa->A;
956171f1c8SPierre Jolivet   PetscErrorCode ierr;
966171f1c8SPierre Jolivet 
976171f1c8SPierre Jolivet   PetscFunctionBegin;
986171f1c8SPierre Jolivet   ierr = MatAXPY(M,a,N,str);CHKERRQ(ierr);
996171f1c8SPierre Jolivet   PetscFunctionReturn(0);
1006171f1c8SPierre Jolivet }
1016171f1c8SPierre Jolivet 
10206511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat_HT(Mat N,Mat *M)
10306511a5cSPierre Jolivet {
10406511a5cSPierre Jolivet   Mat_HT         *Na = (Mat_HT*)N->data;
10506511a5cSPierre Jolivet 
10606511a5cSPierre Jolivet   PetscFunctionBegin;
10706511a5cSPierre Jolivet   *M = Na->A;
10806511a5cSPierre Jolivet   PetscFunctionReturn(0);
10906511a5cSPierre Jolivet }
11006511a5cSPierre Jolivet 
11106511a5cSPierre Jolivet /*@
11206511a5cSPierre Jolivet       MatHermitianTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT
11306511a5cSPierre Jolivet 
11406511a5cSPierre Jolivet    Logically collective on Mat
11506511a5cSPierre Jolivet 
11606511a5cSPierre Jolivet    Input Parameter:
11706511a5cSPierre Jolivet .   A  - the MATTRANSPOSE matrix
11806511a5cSPierre Jolivet 
11906511a5cSPierre Jolivet    Output Parameter:
12006511a5cSPierre Jolivet .   M - the matrix object stored inside A
12106511a5cSPierre Jolivet 
12206511a5cSPierre Jolivet    Level: intermediate
12306511a5cSPierre Jolivet 
12406511a5cSPierre Jolivet .seealso: MatCreateHermitianTranspose()
12506511a5cSPierre Jolivet 
12606511a5cSPierre Jolivet @*/
12706511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat(Mat A,Mat *M)
12806511a5cSPierre Jolivet {
12906511a5cSPierre Jolivet   PetscErrorCode ierr;
13006511a5cSPierre Jolivet 
13106511a5cSPierre Jolivet   PetscFunctionBegin;
13206511a5cSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
13306511a5cSPierre Jolivet   PetscValidType(A,1);
13406511a5cSPierre Jolivet   PetscValidPointer(M,2);
13506511a5cSPierre Jolivet   ierr = PetscUseMethod(A,"MatHermitianTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr);
13606511a5cSPierre Jolivet   PetscFunctionReturn(0);
13706511a5cSPierre Jolivet }
13806511a5cSPierre Jolivet 
1396718818eSStefano Zampini PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose(Mat);
1406718818eSStefano Zampini 
141a0eea678SPierre Jolivet PetscErrorCode MatGetDiagonal_HT(Mat A,Vec v)
142a0eea678SPierre Jolivet {
143a0eea678SPierre Jolivet   Mat_HT         *Na = (Mat_HT*)A->data;
144a0eea678SPierre Jolivet   PetscErrorCode ierr;
145a0eea678SPierre Jolivet 
146a0eea678SPierre Jolivet   PetscFunctionBegin;
147a0eea678SPierre Jolivet   ierr = MatGetDiagonal(Na->A,v);CHKERRQ(ierr);
148ff83db7bSPierre Jolivet   ierr = VecConjugate(v);CHKERRQ(ierr);
149a0eea678SPierre Jolivet   PetscFunctionReturn(0);
150a0eea678SPierre Jolivet }
151a0eea678SPierre Jolivet 
152a0eea678SPierre Jolivet PetscErrorCode MatConvert_HT(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
153a0eea678SPierre Jolivet {
154a0eea678SPierre Jolivet   Mat_HT         *Na = (Mat_HT*)A->data;
155a0eea678SPierre Jolivet   PetscErrorCode ierr;
156*6a4403aaSStefano Zampini   PetscBool      flg;
157a0eea678SPierre Jolivet 
158a0eea678SPierre Jolivet   PetscFunctionBegin;
159*6a4403aaSStefano Zampini   ierr = MatHasOperation(Na->A,MATOP_HERMITIAN_TRANSPOSE,&flg);CHKERRQ(ierr);
160*6a4403aaSStefano Zampini   if (flg) {
161*6a4403aaSStefano Zampini     Mat B;
162*6a4403aaSStefano Zampini 
163a0eea678SPierre Jolivet     ierr = MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr);
164ff83db7bSPierre Jolivet     if (reuse != MAT_INPLACE_MATRIX) {
165a0eea678SPierre Jolivet       ierr = MatConvert(B,newtype,reuse,newmat);CHKERRQ(ierr);
166a0eea678SPierre Jolivet       ierr = MatDestroy(&B);CHKERRQ(ierr);
167ff83db7bSPierre Jolivet     } else {
168ff83db7bSPierre Jolivet       ierr = MatConvert(B,newtype,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr);
169ff83db7bSPierre Jolivet       ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
170ff83db7bSPierre Jolivet     }
171*6a4403aaSStefano Zampini   } else { /* use basic converter as fallback */
172*6a4403aaSStefano Zampini     ierr = MatConvert_Basic(A,newtype,reuse,newmat);CHKERRQ(ierr);
173*6a4403aaSStefano Zampini   }
174a0eea678SPierre Jolivet   PetscFunctionReturn(0);
175a0eea678SPierre Jolivet }
176a0eea678SPierre Jolivet 
177d0de2241SAndrew Spott /*@
178d0de2241SAndrew Spott       MatCreateHermitianTranspose - Creates a new matrix object that behaves like A'*
179d0de2241SAndrew Spott 
180d0de2241SAndrew Spott    Collective on Mat
181d0de2241SAndrew Spott 
182d0de2241SAndrew Spott    Input Parameter:
183d0de2241SAndrew Spott .   A  - the (possibly rectangular) matrix
184d0de2241SAndrew Spott 
185d0de2241SAndrew Spott    Output Parameter:
186d0de2241SAndrew Spott .   N - the matrix that represents A'*
187d0de2241SAndrew Spott 
188d0de2241SAndrew Spott    Level: intermediate
189d0de2241SAndrew Spott 
19095452b02SPatrick Sanan    Notes:
19195452b02SPatrick Sanan     The hermitian transpose A' is NOT actually formed! Rather the new matrix
192d0de2241SAndrew Spott           object performs the matrix-vector product by using the MatMultHermitianTranspose() on
193d0de2241SAndrew Spott           the original matrix
194d0de2241SAndrew Spott 
195d0de2241SAndrew Spott .seealso: MatCreateNormal(), MatMult(), MatMultHermitianTranspose(), MatCreate()
196d0de2241SAndrew Spott 
197d0de2241SAndrew Spott @*/
198d0de2241SAndrew Spott PetscErrorCode  MatCreateHermitianTranspose(Mat A,Mat *N)
199d0de2241SAndrew Spott {
200d0de2241SAndrew Spott   PetscErrorCode ierr;
201d0de2241SAndrew Spott   PetscInt       m,n;
202fb41c00aSBarry Smith   Mat_HT         *Na;
203487d878eSStefano Zampini   VecType        vtype;
204d0de2241SAndrew Spott 
205d0de2241SAndrew Spott   PetscFunctionBegin;
206d0de2241SAndrew Spott   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
207d0de2241SAndrew Spott   ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr);
208d0de2241SAndrew Spott   ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr);
209d0de2241SAndrew Spott   ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr);
210d0de2241SAndrew Spott   ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr);
211d0de2241SAndrew Spott   ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr);
212d0de2241SAndrew Spott 
213d0de2241SAndrew Spott   ierr       = PetscNewLog(*N,&Na);CHKERRQ(ierr);
214d0de2241SAndrew Spott   (*N)->data = (void*) Na;
215d0de2241SAndrew Spott   ierr       = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
216d0de2241SAndrew Spott   Na->A      = A;
217d0de2241SAndrew Spott 
218fb41c00aSBarry Smith   (*N)->ops->destroy                   = MatDestroy_HT;
219fb41c00aSBarry Smith   (*N)->ops->mult                      = MatMult_HT;
220fb41c00aSBarry Smith   (*N)->ops->multadd                   = MatMultAdd_HT;
221fb41c00aSBarry Smith   (*N)->ops->multhermitiantranspose    = MatMultHermitianTranspose_HT;
222fb41c00aSBarry Smith   (*N)->ops->multhermitiantransposeadd = MatMultHermitianTransposeAdd_HT;
2236048efd1SBarry Smith #if !defined(PETSC_USE_COMPLEX)
2246048efd1SBarry Smith   (*N)->ops->multtranspose             = MatMultHermitianTranspose_HT;
2256048efd1SBarry Smith   (*N)->ops->multtransposeadd          = MatMultHermitianTransposeAdd_HT;
2266048efd1SBarry Smith #endif
227fb41c00aSBarry Smith   (*N)->ops->duplicate                 = MatDuplicate_HT;
22806511a5cSPierre Jolivet   (*N)->ops->getvecs                   = MatCreateVecs_HT;
2296171f1c8SPierre Jolivet   (*N)->ops->axpy                      = MatAXPY_HT;
2306718818eSStefano Zampini #if !defined(PETSC_USE_COMPLEX)
2316718818eSStefano Zampini   (*N)->ops->productsetfromoptions     = MatProductSetFromOptions_Transpose;
2326718818eSStefano Zampini #endif
233a0eea678SPierre Jolivet   (*N)->ops->getdiagonal               = MatGetDiagonal_HT;
234a0eea678SPierre Jolivet   (*N)->ops->convert                   = MatConvert_HT;
235d0de2241SAndrew Spott   (*N)->assembled                      = PETSC_TRUE;
236d0de2241SAndrew Spott 
23706511a5cSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatHermitianTransposeGetMat_C",MatHermitianTransposeGetMat_HT);CHKERRQ(ierr);
238204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
239204606b3SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatHermitianTransposeGetMat_HT);CHKERRQ(ierr);
2406718818eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatProductSetFromOptions_anytype_C",MatProductSetFromOptions_Transpose);CHKERRQ(ierr);
241204606b3SStefano Zampini #endif
242d0de2241SAndrew Spott   ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
243487d878eSStefano Zampini   ierr = MatGetVecType(A,&vtype);CHKERRQ(ierr);
244487d878eSStefano Zampini   ierr = MatSetVecType(*N,vtype);CHKERRQ(ierr);
2452487f3f2SStefano Zampini #if defined(PETSC_HAVE_DEVICE)
2462487f3f2SStefano Zampini   ierr = MatBindToCPU(*N,A->boundtocpu);CHKERRQ(ierr);
2472487f3f2SStefano Zampini #endif
248d0de2241SAndrew Spott   ierr = MatSetUp(*N);CHKERRQ(ierr);
249d0de2241SAndrew Spott   PetscFunctionReturn(0);
250d0de2241SAndrew Spott }
251