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