xref: /petsc/src/mat/impls/transpose/htransm.c (revision cac4c232dc4f93991e342196e27ef7b0655dac7b)
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 
12d0de2241SAndrew Spott   PetscFunctionBegin;
139566063dSJacob Faibussowitsch   PetscCall(MatMultHermitianTranspose(Na->A,x,y));
14d0de2241SAndrew Spott   PetscFunctionReturn(0);
15d0de2241SAndrew Spott }
16d0de2241SAndrew Spott 
17fb41c00aSBarry Smith PetscErrorCode MatMultAdd_HT(Mat N,Vec v1,Vec v2,Vec v3)
18d0de2241SAndrew Spott {
19fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
20d0de2241SAndrew Spott 
21d0de2241SAndrew Spott   PetscFunctionBegin;
229566063dSJacob Faibussowitsch   PetscCall(MatMultHermitianTransposeAdd(Na->A,v1,v2,v3));
23d0de2241SAndrew Spott   PetscFunctionReturn(0);
24d0de2241SAndrew Spott }
25d0de2241SAndrew Spott 
26fb41c00aSBarry Smith PetscErrorCode MatMultHermitianTranspose_HT(Mat N,Vec x,Vec y)
27d0de2241SAndrew Spott {
28fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
29d0de2241SAndrew Spott 
30d0de2241SAndrew Spott   PetscFunctionBegin;
319566063dSJacob Faibussowitsch   PetscCall(MatMult(Na->A,x,y));
32d0de2241SAndrew Spott   PetscFunctionReturn(0);
33d0de2241SAndrew Spott }
34d0de2241SAndrew Spott 
35fb41c00aSBarry Smith PetscErrorCode MatMultHermitianTransposeAdd_HT(Mat N,Vec v1,Vec v2,Vec v3)
36d0de2241SAndrew Spott {
37fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
38d0de2241SAndrew Spott 
39d0de2241SAndrew Spott   PetscFunctionBegin;
409566063dSJacob Faibussowitsch   PetscCall(MatMultAdd(Na->A,v1,v2,v3));
41d0de2241SAndrew Spott   PetscFunctionReturn(0);
42d0de2241SAndrew Spott }
43d0de2241SAndrew Spott 
44fb41c00aSBarry Smith PetscErrorCode MatDestroy_HT(Mat N)
45d0de2241SAndrew Spott {
46fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
47d0de2241SAndrew Spott 
48d0de2241SAndrew Spott   PetscFunctionBegin;
499566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&Na->A));
509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)N,"MatHermitianTransposeGetMat_C",NULL));
51204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL));
539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)N,"MatProductSetFromOptions_anytype_C",NULL));
54204606b3SStefano Zampini #endif
559566063dSJacob Faibussowitsch   PetscCall(PetscFree(N->data));
56d0de2241SAndrew Spott   PetscFunctionReturn(0);
57d0de2241SAndrew Spott }
58d0de2241SAndrew Spott 
59fb41c00aSBarry Smith PetscErrorCode MatDuplicate_HT(Mat N, MatDuplicateOption op, Mat* m)
60d0de2241SAndrew Spott {
61fb41c00aSBarry Smith   Mat_HT         *Na = (Mat_HT*)N->data;
62d0de2241SAndrew Spott 
63d0de2241SAndrew Spott   PetscFunctionBegin;
64d0de2241SAndrew Spott   if (op == MAT_COPY_VALUES) {
659566063dSJacob Faibussowitsch     PetscCall(MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,m));
66d0de2241SAndrew Spott   } else if (op == MAT_DO_NOT_COPY_VALUES) {
679566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m));
689566063dSJacob Faibussowitsch     PetscCall(MatHermitianTranspose(*m,MAT_INPLACE_MATRIX,m));
69fb41c00aSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type");
70d0de2241SAndrew Spott   PetscFunctionReturn(0);
71d0de2241SAndrew Spott }
72d0de2241SAndrew Spott 
7306511a5cSPierre Jolivet PetscErrorCode MatCreateVecs_HT(Mat N,Vec *r, Vec *l)
7406511a5cSPierre Jolivet {
7506511a5cSPierre Jolivet   Mat_HT         *Na = (Mat_HT*)N->data;
7606511a5cSPierre Jolivet 
7706511a5cSPierre Jolivet   PetscFunctionBegin;
789566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(Na->A,l,r));
7906511a5cSPierre Jolivet   PetscFunctionReturn(0);
8006511a5cSPierre Jolivet }
8106511a5cSPierre Jolivet 
826171f1c8SPierre Jolivet PetscErrorCode MatAXPY_HT(Mat Y,PetscScalar a,Mat X,MatStructure str)
836171f1c8SPierre Jolivet {
846171f1c8SPierre Jolivet   Mat_HT         *Ya = (Mat_HT*)Y->data;
856171f1c8SPierre Jolivet   Mat_HT         *Xa = (Mat_HT*)X->data;
866171f1c8SPierre Jolivet   Mat              M = Ya->A;
876171f1c8SPierre Jolivet   Mat              N = Xa->A;
886171f1c8SPierre Jolivet 
896171f1c8SPierre Jolivet   PetscFunctionBegin;
909566063dSJacob Faibussowitsch   PetscCall(MatAXPY(M,a,N,str));
916171f1c8SPierre Jolivet   PetscFunctionReturn(0);
926171f1c8SPierre Jolivet }
936171f1c8SPierre Jolivet 
9406511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat_HT(Mat N,Mat *M)
9506511a5cSPierre Jolivet {
9606511a5cSPierre Jolivet   Mat_HT         *Na = (Mat_HT*)N->data;
9706511a5cSPierre Jolivet 
9806511a5cSPierre Jolivet   PetscFunctionBegin;
9906511a5cSPierre Jolivet   *M = Na->A;
10006511a5cSPierre Jolivet   PetscFunctionReturn(0);
10106511a5cSPierre Jolivet }
10206511a5cSPierre Jolivet 
10306511a5cSPierre Jolivet /*@
10406511a5cSPierre Jolivet       MatHermitianTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT
10506511a5cSPierre Jolivet 
10606511a5cSPierre Jolivet    Logically collective on Mat
10706511a5cSPierre Jolivet 
10806511a5cSPierre Jolivet    Input Parameter:
10906511a5cSPierre Jolivet .   A  - the MATTRANSPOSE matrix
11006511a5cSPierre Jolivet 
11106511a5cSPierre Jolivet    Output Parameter:
11206511a5cSPierre Jolivet .   M - the matrix object stored inside A
11306511a5cSPierre Jolivet 
11406511a5cSPierre Jolivet    Level: intermediate
11506511a5cSPierre Jolivet 
11606511a5cSPierre Jolivet .seealso: MatCreateHermitianTranspose()
11706511a5cSPierre Jolivet 
11806511a5cSPierre Jolivet @*/
11906511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat(Mat A,Mat *M)
12006511a5cSPierre Jolivet {
12106511a5cSPierre Jolivet   PetscFunctionBegin;
12206511a5cSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
12306511a5cSPierre Jolivet   PetscValidType(A,1);
12406511a5cSPierre Jolivet   PetscValidPointer(M,2);
125*cac4c232SBarry Smith   PetscUseMethod(A,"MatHermitianTransposeGetMat_C",(Mat,Mat*),(A,M));
12606511a5cSPierre Jolivet   PetscFunctionReturn(0);
12706511a5cSPierre Jolivet }
12806511a5cSPierre Jolivet 
1296718818eSStefano Zampini PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose(Mat);
1306718818eSStefano Zampini 
131a0eea678SPierre Jolivet PetscErrorCode MatGetDiagonal_HT(Mat A,Vec v)
132a0eea678SPierre Jolivet {
133a0eea678SPierre Jolivet   Mat_HT         *Na = (Mat_HT*)A->data;
134a0eea678SPierre Jolivet 
135a0eea678SPierre Jolivet   PetscFunctionBegin;
1369566063dSJacob Faibussowitsch   PetscCall(MatGetDiagonal(Na->A,v));
1379566063dSJacob Faibussowitsch   PetscCall(VecConjugate(v));
138a0eea678SPierre Jolivet   PetscFunctionReturn(0);
139a0eea678SPierre Jolivet }
140a0eea678SPierre Jolivet 
141a0eea678SPierre Jolivet PetscErrorCode MatConvert_HT(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
142a0eea678SPierre Jolivet {
143a0eea678SPierre Jolivet   Mat_HT         *Na = (Mat_HT*)A->data;
1446a4403aaSStefano Zampini   PetscBool      flg;
145a0eea678SPierre Jolivet 
146a0eea678SPierre Jolivet   PetscFunctionBegin;
1479566063dSJacob Faibussowitsch   PetscCall(MatHasOperation(Na->A,MATOP_HERMITIAN_TRANSPOSE,&flg));
1486a4403aaSStefano Zampini   if (flg) {
1496a4403aaSStefano Zampini     Mat B;
1506a4403aaSStefano Zampini 
1519566063dSJacob Faibussowitsch     PetscCall(MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,&B));
152ff83db7bSPierre Jolivet     if (reuse != MAT_INPLACE_MATRIX) {
1539566063dSJacob Faibussowitsch       PetscCall(MatConvert(B,newtype,reuse,newmat));
1549566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&B));
155ff83db7bSPierre Jolivet     } else {
1569566063dSJacob Faibussowitsch       PetscCall(MatConvert(B,newtype,MAT_INPLACE_MATRIX,&B));
1579566063dSJacob Faibussowitsch       PetscCall(MatHeaderReplace(A,&B));
158ff83db7bSPierre Jolivet     }
1596a4403aaSStefano Zampini   } else { /* use basic converter as fallback */
1609566063dSJacob Faibussowitsch     PetscCall(MatConvert_Basic(A,newtype,reuse,newmat));
1616a4403aaSStefano Zampini   }
162a0eea678SPierre Jolivet   PetscFunctionReturn(0);
163a0eea678SPierre Jolivet }
164a0eea678SPierre Jolivet 
165d0de2241SAndrew Spott /*@
166d0de2241SAndrew Spott       MatCreateHermitianTranspose - Creates a new matrix object that behaves like A'*
167d0de2241SAndrew Spott 
168d0de2241SAndrew Spott    Collective on Mat
169d0de2241SAndrew Spott 
170d0de2241SAndrew Spott    Input Parameter:
171d0de2241SAndrew Spott .   A  - the (possibly rectangular) matrix
172d0de2241SAndrew Spott 
173d0de2241SAndrew Spott    Output Parameter:
174d0de2241SAndrew Spott .   N - the matrix that represents A'*
175d0de2241SAndrew Spott 
176d0de2241SAndrew Spott    Level: intermediate
177d0de2241SAndrew Spott 
17895452b02SPatrick Sanan    Notes:
17995452b02SPatrick Sanan     The hermitian transpose A' is NOT actually formed! Rather the new matrix
180d0de2241SAndrew Spott           object performs the matrix-vector product by using the MatMultHermitianTranspose() on
181d0de2241SAndrew Spott           the original matrix
182d0de2241SAndrew Spott 
183d0de2241SAndrew Spott .seealso: MatCreateNormal(), MatMult(), MatMultHermitianTranspose(), MatCreate()
184d0de2241SAndrew Spott @*/
185d0de2241SAndrew Spott PetscErrorCode  MatCreateHermitianTranspose(Mat A,Mat *N)
186d0de2241SAndrew Spott {
187d0de2241SAndrew Spott   PetscInt       m,n;
188fb41c00aSBarry Smith   Mat_HT         *Na;
189487d878eSStefano Zampini   VecType        vtype;
190d0de2241SAndrew Spott 
191d0de2241SAndrew Spott   PetscFunctionBegin;
1929566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(A,&m,&n));
1939566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),N));
1949566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE));
1959566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp((*N)->rmap));
1969566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp((*N)->cmap));
1979566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT));
198d0de2241SAndrew Spott 
1999566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(*N,&Na));
200d0de2241SAndrew Spott   (*N)->data = (void*) Na;
2019566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)A));
202d0de2241SAndrew Spott   Na->A      = A;
203d0de2241SAndrew Spott 
204fb41c00aSBarry Smith   (*N)->ops->destroy                   = MatDestroy_HT;
205fb41c00aSBarry Smith   (*N)->ops->mult                      = MatMult_HT;
206fb41c00aSBarry Smith   (*N)->ops->multadd                   = MatMultAdd_HT;
207fb41c00aSBarry Smith   (*N)->ops->multhermitiantranspose    = MatMultHermitianTranspose_HT;
208fb41c00aSBarry Smith   (*N)->ops->multhermitiantransposeadd = MatMultHermitianTransposeAdd_HT;
2096048efd1SBarry Smith #if !defined(PETSC_USE_COMPLEX)
2106048efd1SBarry Smith   (*N)->ops->multtranspose             = MatMultHermitianTranspose_HT;
2116048efd1SBarry Smith   (*N)->ops->multtransposeadd          = MatMultHermitianTransposeAdd_HT;
2126048efd1SBarry Smith #endif
213fb41c00aSBarry Smith   (*N)->ops->duplicate                 = MatDuplicate_HT;
21406511a5cSPierre Jolivet   (*N)->ops->getvecs                   = MatCreateVecs_HT;
2156171f1c8SPierre Jolivet   (*N)->ops->axpy                      = MatAXPY_HT;
2166718818eSStefano Zampini #if !defined(PETSC_USE_COMPLEX)
2176718818eSStefano Zampini   (*N)->ops->productsetfromoptions     = MatProductSetFromOptions_Transpose;
2186718818eSStefano Zampini #endif
219a0eea678SPierre Jolivet   (*N)->ops->getdiagonal               = MatGetDiagonal_HT;
220a0eea678SPierre Jolivet   (*N)->ops->convert                   = MatConvert_HT;
221d0de2241SAndrew Spott   (*N)->assembled                      = PETSC_TRUE;
222d0de2241SAndrew Spott 
2239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)(*N),"MatHermitianTransposeGetMat_C",MatHermitianTransposeGetMat_HT));
224204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
2259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatHermitianTransposeGetMat_HT));
2269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)(*N),"MatProductSetFromOptions_anytype_C",MatProductSetFromOptions_Transpose));
227204606b3SStefano Zampini #endif
2289566063dSJacob Faibussowitsch   PetscCall(MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs)));
2299566063dSJacob Faibussowitsch   PetscCall(MatGetVecType(A,&vtype));
2309566063dSJacob Faibussowitsch   PetscCall(MatSetVecType(*N,vtype));
2312487f3f2SStefano Zampini #if defined(PETSC_HAVE_DEVICE)
2329566063dSJacob Faibussowitsch   PetscCall(MatBindToCPU(*N,A->boundtocpu));
2332487f3f2SStefano Zampini #endif
2349566063dSJacob Faibussowitsch   PetscCall(MatSetUp(*N));
235d0de2241SAndrew Spott   PetscFunctionReturn(0);
236d0de2241SAndrew Spott }
237