186a22c91SHong Zhang 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 386a22c91SHong Zhang 4e573050aSPierre Jolivet static PetscErrorCode MatMultEqual_Private(Mat A,Mat B,PetscInt n,PetscBool *flg,PetscInt t,PetscBool add) 5447fed29SStefano Zampini { 6447fed29SStefano Zampini PetscErrorCode ierr; 7b84f494bSStefano Zampini Vec Ax = NULL,Bx = NULL,s1 = NULL,s2 = NULL,Ay = NULL, By = NULL; 8447fed29SStefano Zampini PetscRandom rctx; 9447fed29SStefano Zampini PetscReal r1,r2,tol=PETSC_SQRT_MACHINE_EPSILON; 10447fed29SStefano Zampini PetscInt am,an,bm,bn,k; 11447fed29SStefano Zampini PetscScalar none = -1.0; 12e573050aSPierre Jolivet const char* sops[] = {"MatMult","MatMultAdd","MatMultTranspose","MatMultTransposeAdd","MatMultHermitianTranspose","MatMultHermitianTranposeAdd"}; 13447fed29SStefano Zampini const char* sop; 14447fed29SStefano Zampini 15447fed29SStefano Zampini PetscFunctionBegin; 16447fed29SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 17447fed29SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,2); 18447fed29SStefano Zampini PetscCheckSameComm(A,1,B,2); 19447fed29SStefano Zampini PetscValidLogicalCollectiveInt(A,n,3); 20447fed29SStefano Zampini PetscValidPointer(flg,4); 21e573050aSPierre Jolivet PetscValidLogicalCollectiveInt(A,t,5); 22447fed29SStefano Zampini PetscValidLogicalCollectiveBool(A,add,6); 23447fed29SStefano Zampini ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); 24447fed29SStefano Zampini ierr = MatGetLocalSize(B,&bm,&bn);CHKERRQ(ierr); 25*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(am != bm || an != bn,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,am,bm,an,bn); 26e573050aSPierre Jolivet sop = sops[(add ? 1 : 0) + 2 * t]; /* t = 0 => no transpose, t = 1 => transpose, t = 2 => Hermitian transpose */ 27447fed29SStefano Zampini ierr = PetscRandomCreate(PetscObjectComm((PetscObject)A),&rctx);CHKERRQ(ierr); 28447fed29SStefano Zampini ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); 29447fed29SStefano Zampini if (t) { 30447fed29SStefano Zampini ierr = MatCreateVecs(A,&s1,&Ax);CHKERRQ(ierr); 31447fed29SStefano Zampini ierr = MatCreateVecs(B,&s2,&Bx);CHKERRQ(ierr); 32447fed29SStefano Zampini } else { 33447fed29SStefano Zampini ierr = MatCreateVecs(A,&Ax,&s1);CHKERRQ(ierr); 34447fed29SStefano Zampini ierr = MatCreateVecs(B,&Bx,&s2);CHKERRQ(ierr); 35447fed29SStefano Zampini } 36447fed29SStefano Zampini if (add) { 37447fed29SStefano Zampini ierr = VecDuplicate(s1,&Ay);CHKERRQ(ierr); 38447fed29SStefano Zampini ierr = VecDuplicate(s2,&By);CHKERRQ(ierr); 39447fed29SStefano Zampini } 40447fed29SStefano Zampini 41447fed29SStefano Zampini *flg = PETSC_TRUE; 42447fed29SStefano Zampini for (k=0; k<n; k++) { 43447fed29SStefano Zampini ierr = VecSetRandom(Ax,rctx);CHKERRQ(ierr); 44447fed29SStefano Zampini ierr = VecCopy(Ax,Bx);CHKERRQ(ierr); 45447fed29SStefano Zampini if (add) { 46447fed29SStefano Zampini ierr = VecSetRandom(Ay,rctx);CHKERRQ(ierr); 47447fed29SStefano Zampini ierr = VecCopy(Ay,By);CHKERRQ(ierr); 48447fed29SStefano Zampini } 49e573050aSPierre Jolivet if (t == 1) { 50447fed29SStefano Zampini if (add) { 51447fed29SStefano Zampini ierr = MatMultTransposeAdd(A,Ax,Ay,s1);CHKERRQ(ierr); 52447fed29SStefano Zampini ierr = MatMultTransposeAdd(B,Bx,By,s2);CHKERRQ(ierr); 53447fed29SStefano Zampini } else { 54447fed29SStefano Zampini ierr = MatMultTranspose(A,Ax,s1);CHKERRQ(ierr); 55447fed29SStefano Zampini ierr = MatMultTranspose(B,Bx,s2);CHKERRQ(ierr); 56447fed29SStefano Zampini } 57e573050aSPierre Jolivet } else if (t == 2) { 58e573050aSPierre Jolivet if (add) { 59e573050aSPierre Jolivet ierr = MatMultHermitianTransposeAdd(A,Ax,Ay,s1);CHKERRQ(ierr); 60e573050aSPierre Jolivet ierr = MatMultHermitianTransposeAdd(B,Bx,By,s2);CHKERRQ(ierr); 61e573050aSPierre Jolivet } else { 62e573050aSPierre Jolivet ierr = MatMultHermitianTranspose(A,Ax,s1);CHKERRQ(ierr); 63e573050aSPierre Jolivet ierr = MatMultHermitianTranspose(B,Bx,s2);CHKERRQ(ierr); 64e573050aSPierre Jolivet } 65447fed29SStefano Zampini } else { 66447fed29SStefano Zampini if (add) { 67447fed29SStefano Zampini ierr = MatMultAdd(A,Ax,Ay,s1);CHKERRQ(ierr); 68447fed29SStefano Zampini ierr = MatMultAdd(B,Bx,By,s2);CHKERRQ(ierr); 69447fed29SStefano Zampini } else { 70447fed29SStefano Zampini ierr = MatMult(A,Ax,s1);CHKERRQ(ierr); 71447fed29SStefano Zampini ierr = MatMult(B,Bx,s2);CHKERRQ(ierr); 72447fed29SStefano Zampini } 73447fed29SStefano Zampini } 74447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r2);CHKERRQ(ierr); 75447fed29SStefano Zampini if (r2 < tol) { 76447fed29SStefano Zampini ierr = VecNorm(s1,NORM_INFINITY,&r1);CHKERRQ(ierr); 77447fed29SStefano Zampini } else { 78447fed29SStefano Zampini ierr = VecAXPY(s2,none,s1);CHKERRQ(ierr); 79447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r1);CHKERRQ(ierr); 80447fed29SStefano Zampini r1 /= r2; 81447fed29SStefano Zampini } 82447fed29SStefano Zampini if (r1 > tol) { 83447fed29SStefano Zampini *flg = PETSC_FALSE; 847d3de750SJacob Faibussowitsch ierr = PetscInfo(A,"Error: %" PetscInt_FMT "-th %s() %g\n",k,sop,(double)r1);CHKERRQ(ierr); 85447fed29SStefano Zampini break; 86447fed29SStefano Zampini } 87447fed29SStefano Zampini } 88447fed29SStefano Zampini ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); 89447fed29SStefano Zampini ierr = VecDestroy(&Ax);CHKERRQ(ierr); 90447fed29SStefano Zampini ierr = VecDestroy(&Bx);CHKERRQ(ierr); 91447fed29SStefano Zampini ierr = VecDestroy(&Ay);CHKERRQ(ierr); 92447fed29SStefano Zampini ierr = VecDestroy(&By);CHKERRQ(ierr); 93447fed29SStefano Zampini ierr = VecDestroy(&s1);CHKERRQ(ierr); 94447fed29SStefano Zampini ierr = VecDestroy(&s2);CHKERRQ(ierr); 95447fed29SStefano Zampini PetscFunctionReturn(0); 96447fed29SStefano Zampini } 97447fed29SStefano Zampini 98447fed29SStefano Zampini static PetscErrorCode MatMatMultEqual_Private(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg,PetscBool At,PetscBool Bt) 99447fed29SStefano Zampini { 100447fed29SStefano Zampini PetscErrorCode ierr; 101447fed29SStefano Zampini Vec Ax,Bx,Cx,s1,s2,s3; 102447fed29SStefano Zampini PetscRandom rctx; 103447fed29SStefano Zampini PetscReal r1,r2,tol=PETSC_SQRT_MACHINE_EPSILON; 104447fed29SStefano Zampini PetscInt am,an,bm,bn,cm,cn,k; 105447fed29SStefano Zampini PetscScalar none = -1.0; 106447fed29SStefano Zampini const char* sops[] = {"MatMatMult","MatTransposeMatMult","MatMatTransposeMult","MatTransposeMatTranposeMult"}; 107447fed29SStefano Zampini const char* sop; 108447fed29SStefano Zampini 109447fed29SStefano Zampini PetscFunctionBegin; 110447fed29SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 111447fed29SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,2); 112447fed29SStefano Zampini PetscCheckSameComm(A,1,B,2); 113447fed29SStefano Zampini PetscValidHeaderSpecific(C,MAT_CLASSID,3); 114447fed29SStefano Zampini PetscCheckSameComm(A,1,C,3); 115447fed29SStefano Zampini PetscValidLogicalCollectiveInt(A,n,4); 116447fed29SStefano Zampini PetscValidPointer(flg,5); 117447fed29SStefano Zampini PetscValidLogicalCollectiveBool(A,At,6); 118447fed29SStefano Zampini PetscValidLogicalCollectiveBool(B,Bt,7); 119447fed29SStefano Zampini ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); 120447fed29SStefano Zampini ierr = MatGetLocalSize(B,&bm,&bn);CHKERRQ(ierr); 121447fed29SStefano Zampini ierr = MatGetLocalSize(C,&cm,&cn);CHKERRQ(ierr); 122447fed29SStefano Zampini if (At) { PetscInt tt = an; an = am; am = tt; }; 123447fed29SStefano Zampini if (Bt) { PetscInt tt = bn; bn = bm; bm = tt; }; 124*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(an != bm || am != cm || bn != cn,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A, B, C local dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,am,an,bm,bn,cm,cn); 125447fed29SStefano Zampini 126447fed29SStefano Zampini sop = sops[(At ? 1 : 0) + 2 * (Bt ? 1 : 0)]; 127447fed29SStefano Zampini ierr = PetscRandomCreate(PetscObjectComm((PetscObject)C),&rctx);CHKERRQ(ierr); 128447fed29SStefano Zampini ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); 129447fed29SStefano Zampini if (Bt) { 130447fed29SStefano Zampini ierr = MatCreateVecs(B,&s1,&Bx);CHKERRQ(ierr); 131447fed29SStefano Zampini } else { 132447fed29SStefano Zampini ierr = MatCreateVecs(B,&Bx,&s1);CHKERRQ(ierr); 133447fed29SStefano Zampini } 134447fed29SStefano Zampini if (At) { 135447fed29SStefano Zampini ierr = MatCreateVecs(A,&s2,&Ax);CHKERRQ(ierr); 136447fed29SStefano Zampini } else { 137447fed29SStefano Zampini ierr = MatCreateVecs(A,&Ax,&s2);CHKERRQ(ierr); 138447fed29SStefano Zampini } 139447fed29SStefano Zampini ierr = MatCreateVecs(C,&Cx,&s3);CHKERRQ(ierr); 140447fed29SStefano Zampini 141447fed29SStefano Zampini *flg = PETSC_TRUE; 142447fed29SStefano Zampini for (k=0; k<n; k++) { 143447fed29SStefano Zampini ierr = VecSetRandom(Bx,rctx);CHKERRQ(ierr); 144447fed29SStefano Zampini if (Bt) { 145447fed29SStefano Zampini ierr = MatMultTranspose(B,Bx,s1);CHKERRQ(ierr); 146447fed29SStefano Zampini } else { 147447fed29SStefano Zampini ierr = MatMult(B,Bx,s1);CHKERRQ(ierr); 148447fed29SStefano Zampini } 149447fed29SStefano Zampini ierr = VecCopy(s1,Ax);CHKERRQ(ierr); 150447fed29SStefano Zampini if (At) { 151447fed29SStefano Zampini ierr = MatMultTranspose(A,Ax,s2);CHKERRQ(ierr); 152447fed29SStefano Zampini } else { 153447fed29SStefano Zampini ierr = MatMult(A,Ax,s2);CHKERRQ(ierr); 154447fed29SStefano Zampini } 155447fed29SStefano Zampini ierr = VecCopy(Bx,Cx);CHKERRQ(ierr); 156447fed29SStefano Zampini ierr = MatMult(C,Cx,s3);CHKERRQ(ierr); 157447fed29SStefano Zampini 158447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r2);CHKERRQ(ierr); 159447fed29SStefano Zampini if (r2 < tol) { 160447fed29SStefano Zampini ierr = VecNorm(s3,NORM_INFINITY,&r1);CHKERRQ(ierr); 161447fed29SStefano Zampini } else { 162447fed29SStefano Zampini ierr = VecAXPY(s2,none,s3);CHKERRQ(ierr); 163447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r1);CHKERRQ(ierr); 164447fed29SStefano Zampini r1 /= r2; 165447fed29SStefano Zampini } 166447fed29SStefano Zampini if (r1 > tol) { 167447fed29SStefano Zampini *flg = PETSC_FALSE; 1687d3de750SJacob Faibussowitsch ierr = PetscInfo(A,"Error: %" PetscInt_FMT "-th %s %g\n",k,sop,(double)r1);CHKERRQ(ierr); 169447fed29SStefano Zampini break; 170447fed29SStefano Zampini } 171447fed29SStefano Zampini } 172447fed29SStefano Zampini ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); 173447fed29SStefano Zampini ierr = VecDestroy(&Ax);CHKERRQ(ierr); 174447fed29SStefano Zampini ierr = VecDestroy(&Bx);CHKERRQ(ierr); 175447fed29SStefano Zampini ierr = VecDestroy(&Cx);CHKERRQ(ierr); 176447fed29SStefano Zampini ierr = VecDestroy(&s1);CHKERRQ(ierr); 177447fed29SStefano Zampini ierr = VecDestroy(&s2);CHKERRQ(ierr); 178447fed29SStefano Zampini ierr = VecDestroy(&s3);CHKERRQ(ierr); 179447fed29SStefano Zampini PetscFunctionReturn(0); 180447fed29SStefano Zampini } 181447fed29SStefano Zampini 18286a22c91SHong Zhang /*@ 18386a22c91SHong Zhang MatMultEqual - Compares matrix-vector products of two matrices. 18486a22c91SHong Zhang 18586a22c91SHong Zhang Collective on Mat 18686a22c91SHong Zhang 18786a22c91SHong Zhang Input Parameters: 18886a22c91SHong Zhang + A - the first matrix 1894222ddf1SHong Zhang . B - the second matrix 19086a22c91SHong Zhang - n - number of random vectors to be tested 19186a22c91SHong Zhang 19286a22c91SHong Zhang Output Parameter: 19386a22c91SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 19486a22c91SHong Zhang 19586a22c91SHong Zhang Level: intermediate 19686a22c91SHong Zhang 19786a22c91SHong Zhang @*/ 1987087cfbeSBarry Smith PetscErrorCode MatMultEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 19986a22c91SHong Zhang { 20086a22c91SHong Zhang PetscErrorCode ierr; 20186a22c91SHong Zhang 20286a22c91SHong Zhang PetscFunctionBegin; 203e573050aSPierre Jolivet ierr = MatMultEqual_Private(A,B,n,flg,0,PETSC_FALSE);CHKERRQ(ierr); 20486a22c91SHong Zhang PetscFunctionReturn(0); 20586a22c91SHong Zhang } 20686a22c91SHong Zhang 20786a22c91SHong Zhang /*@ 20886a22c91SHong Zhang MatMultAddEqual - Compares matrix-vector products of two matrices. 20986a22c91SHong Zhang 21086a22c91SHong Zhang Collective on Mat 21186a22c91SHong Zhang 21286a22c91SHong Zhang Input Parameters: 21386a22c91SHong Zhang + A - the first matrix 2144222ddf1SHong Zhang . B - the second matrix 21586a22c91SHong Zhang - n - number of random vectors to be tested 21686a22c91SHong Zhang 21786a22c91SHong Zhang Output Parameter: 21886a22c91SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 21986a22c91SHong Zhang 22086a22c91SHong Zhang Level: intermediate 22186a22c91SHong Zhang 22286a22c91SHong Zhang @*/ 2237087cfbeSBarry Smith PetscErrorCode MatMultAddEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 22486a22c91SHong Zhang { 22586a22c91SHong Zhang PetscErrorCode ierr; 22686a22c91SHong Zhang 22786a22c91SHong Zhang PetscFunctionBegin; 228e573050aSPierre Jolivet ierr = MatMultEqual_Private(A,B,n,flg,0,PETSC_TRUE);CHKERRQ(ierr); 22963879571SHong Zhang PetscFunctionReturn(0); 23063879571SHong Zhang } 23163879571SHong Zhang 23263879571SHong Zhang /*@ 23363879571SHong Zhang MatMultTransposeEqual - Compares matrix-vector products of two matrices. 23463879571SHong Zhang 23563879571SHong Zhang Collective on Mat 23663879571SHong Zhang 23763879571SHong Zhang Input Parameters: 23863879571SHong Zhang + A - the first matrix 2394222ddf1SHong Zhang . B - the second matrix 24063879571SHong Zhang - n - number of random vectors to be tested 24163879571SHong Zhang 24263879571SHong Zhang Output Parameter: 24363879571SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 24463879571SHong Zhang 24563879571SHong Zhang Level: intermediate 24663879571SHong Zhang 24763879571SHong Zhang @*/ 2487087cfbeSBarry Smith PetscErrorCode MatMultTransposeEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 24963879571SHong Zhang { 25063879571SHong Zhang PetscErrorCode ierr; 25163879571SHong Zhang 25263879571SHong Zhang PetscFunctionBegin; 253e573050aSPierre Jolivet ierr = MatMultEqual_Private(A,B,n,flg,1,PETSC_FALSE);CHKERRQ(ierr); 25463879571SHong Zhang PetscFunctionReturn(0); 25563879571SHong Zhang } 25663879571SHong Zhang 25763879571SHong Zhang /*@ 25863879571SHong Zhang MatMultTransposeAddEqual - Compares matrix-vector products of two matrices. 25963879571SHong Zhang 26063879571SHong Zhang Collective on Mat 26163879571SHong Zhang 26263879571SHong Zhang Input Parameters: 26363879571SHong Zhang + A - the first matrix 2644222ddf1SHong Zhang . B - the second matrix 26563879571SHong Zhang - n - number of random vectors to be tested 26663879571SHong Zhang 26763879571SHong Zhang Output Parameter: 26863879571SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 26963879571SHong Zhang 27063879571SHong Zhang Level: intermediate 27163879571SHong Zhang 27263879571SHong Zhang @*/ 2737087cfbeSBarry Smith PetscErrorCode MatMultTransposeAddEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 27463879571SHong Zhang { 27563879571SHong Zhang PetscErrorCode ierr; 27663879571SHong Zhang 27763879571SHong Zhang PetscFunctionBegin; 278e573050aSPierre Jolivet ierr = MatMultEqual_Private(A,B,n,flg,1,PETSC_TRUE);CHKERRQ(ierr); 279e573050aSPierre Jolivet PetscFunctionReturn(0); 280e573050aSPierre Jolivet } 281e573050aSPierre Jolivet 282e573050aSPierre Jolivet /*@ 283e573050aSPierre Jolivet MatMultHermitianTransposeEqual - Compares matrix-vector products of two matrices. 284e573050aSPierre Jolivet 285e573050aSPierre Jolivet Collective on Mat 286e573050aSPierre Jolivet 287e573050aSPierre Jolivet Input Parameters: 288e573050aSPierre Jolivet + A - the first matrix 289e573050aSPierre Jolivet . B - the second matrix 290e573050aSPierre Jolivet - n - number of random vectors to be tested 291e573050aSPierre Jolivet 292e573050aSPierre Jolivet Output Parameter: 293e573050aSPierre Jolivet . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 294e573050aSPierre Jolivet 295e573050aSPierre Jolivet Level: intermediate 296e573050aSPierre Jolivet 297e573050aSPierre Jolivet @*/ 298e573050aSPierre Jolivet PetscErrorCode MatMultHermitianTransposeEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 299e573050aSPierre Jolivet { 300e573050aSPierre Jolivet PetscErrorCode ierr; 301e573050aSPierre Jolivet 302e573050aSPierre Jolivet PetscFunctionBegin; 303e573050aSPierre Jolivet ierr = MatMultEqual_Private(A,B,n,flg,2,PETSC_FALSE);CHKERRQ(ierr); 304e573050aSPierre Jolivet PetscFunctionReturn(0); 305e573050aSPierre Jolivet } 306e573050aSPierre Jolivet 307e573050aSPierre Jolivet /*@ 308e573050aSPierre Jolivet MatMultHermitianTransposeAddEqual - Compares matrix-vector products of two matrices. 309e573050aSPierre Jolivet 310e573050aSPierre Jolivet Collective on Mat 311e573050aSPierre Jolivet 312e573050aSPierre Jolivet Input Parameters: 313e573050aSPierre Jolivet + A - the first matrix 314e573050aSPierre Jolivet . B - the second matrix 315e573050aSPierre Jolivet - n - number of random vectors to be tested 316e573050aSPierre Jolivet 317e573050aSPierre Jolivet Output Parameter: 318e573050aSPierre Jolivet . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 319e573050aSPierre Jolivet 320e573050aSPierre Jolivet Level: intermediate 321e573050aSPierre Jolivet 322e573050aSPierre Jolivet @*/ 323e573050aSPierre Jolivet PetscErrorCode MatMultHermitianTransposeAddEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 324e573050aSPierre Jolivet { 325e573050aSPierre Jolivet PetscErrorCode ierr; 326e573050aSPierre Jolivet 327e573050aSPierre Jolivet PetscFunctionBegin; 328e573050aSPierre Jolivet ierr = MatMultEqual_Private(A,B,n,flg,2,PETSC_TRUE);CHKERRQ(ierr); 32986a22c91SHong Zhang PetscFunctionReturn(0); 33086a22c91SHong Zhang } 331a52676ecSHong Zhang 332a52676ecSHong Zhang /*@ 333a52676ecSHong Zhang MatMatMultEqual - Test A*B*x = C*x for n random vector x 334a52676ecSHong Zhang 335a52676ecSHong Zhang Collective on Mat 336a52676ecSHong Zhang 337a52676ecSHong Zhang Input Parameters: 338a52676ecSHong Zhang + A - the first matrix 339c2916339SPierre Jolivet . B - the second matrix 340c2916339SPierre Jolivet . C - the third matrix 341a52676ecSHong Zhang - n - number of random vectors to be tested 342a52676ecSHong Zhang 343a52676ecSHong Zhang Output Parameter: 344f0fc11ceSJed Brown . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 345a52676ecSHong Zhang 346a52676ecSHong Zhang Level: intermediate 347a52676ecSHong Zhang 348a52676ecSHong Zhang @*/ 349a52676ecSHong Zhang PetscErrorCode MatMatMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 350a52676ecSHong Zhang { 351a52676ecSHong Zhang PetscErrorCode ierr; 352a52676ecSHong Zhang 353a52676ecSHong Zhang PetscFunctionBegin; 354447fed29SStefano Zampini ierr = MatMatMultEqual_Private(A,B,C,n,flg,PETSC_FALSE,PETSC_FALSE);CHKERRQ(ierr); 355a52676ecSHong Zhang PetscFunctionReturn(0); 356a52676ecSHong Zhang } 357a52676ecSHong Zhang 358a52676ecSHong Zhang /*@ 359a52676ecSHong Zhang MatTransposeMatMultEqual - Test A^T*B*x = C*x for n random vector x 360a52676ecSHong Zhang 361a52676ecSHong Zhang Collective on Mat 362a52676ecSHong Zhang 363a52676ecSHong Zhang Input Parameters: 364a52676ecSHong Zhang + A - the first matrix 3654222ddf1SHong Zhang . B - the second matrix 3664222ddf1SHong Zhang . C - the third matrix 367a52676ecSHong Zhang - n - number of random vectors to be tested 368a52676ecSHong Zhang 369a52676ecSHong Zhang Output Parameter: 370a52676ecSHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 371a52676ecSHong Zhang 372a52676ecSHong Zhang Level: intermediate 373a52676ecSHong Zhang 374a52676ecSHong Zhang @*/ 375a52676ecSHong Zhang PetscErrorCode MatTransposeMatMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 376a52676ecSHong Zhang { 377a52676ecSHong Zhang PetscErrorCode ierr; 378a52676ecSHong Zhang 379a52676ecSHong Zhang PetscFunctionBegin; 380447fed29SStefano Zampini ierr = MatMatMultEqual_Private(A,B,C,n,flg,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 381a52676ecSHong Zhang PetscFunctionReturn(0); 382a52676ecSHong Zhang } 38386919fd6SHong Zhang 38426546c1bSToby Isaac /*@ 38526546c1bSToby Isaac MatMatTransposeMultEqual - Test A*B^T*x = C*x for n random vector x 38626546c1bSToby Isaac 38726546c1bSToby Isaac Collective on Mat 38826546c1bSToby Isaac 38926546c1bSToby Isaac Input Parameters: 39026546c1bSToby Isaac + A - the first matrix 3914222ddf1SHong Zhang . B - the second matrix 3924222ddf1SHong Zhang . C - the third matrix 39326546c1bSToby Isaac - n - number of random vectors to be tested 39426546c1bSToby Isaac 39526546c1bSToby Isaac Output Parameter: 39626546c1bSToby Isaac . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 39726546c1bSToby Isaac 39826546c1bSToby Isaac Level: intermediate 39926546c1bSToby Isaac 40026546c1bSToby Isaac @*/ 401cc48ffa7SToby Isaac PetscErrorCode MatMatTransposeMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 402cc48ffa7SToby Isaac { 403cc48ffa7SToby Isaac PetscErrorCode ierr; 404447fed29SStefano Zampini 405447fed29SStefano Zampini PetscFunctionBegin; 406447fed29SStefano Zampini ierr = MatMatMultEqual_Private(A,B,C,n,flg,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 407447fed29SStefano Zampini PetscFunctionReturn(0); 408447fed29SStefano Zampini } 409447fed29SStefano Zampini 410447fed29SStefano Zampini static PetscErrorCode MatProjMultEqual_Private(Mat A,Mat B,Mat C,PetscInt n,PetscBool rart,PetscBool *flg) 411447fed29SStefano Zampini { 412447fed29SStefano Zampini PetscErrorCode ierr; 413447fed29SStefano Zampini Vec x,v1,v2,v3,v4,Cx,Bx; 414447fed29SStefano Zampini PetscReal norm_abs,norm_rel,tol=PETSC_SQRT_MACHINE_EPSILON; 415447fed29SStefano Zampini PetscInt i,am,an,bm,bn,cm,cn; 416447fed29SStefano Zampini PetscRandom rdm; 417cc48ffa7SToby Isaac PetscScalar none = -1.0; 418cc48ffa7SToby Isaac 419cc48ffa7SToby Isaac PetscFunctionBegin; 420cc48ffa7SToby Isaac ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); 421cc48ffa7SToby Isaac ierr = MatGetLocalSize(B,&bm,&bn);CHKERRQ(ierr); 422447fed29SStefano Zampini if (rart) { PetscInt t = bm; bm = bn; bn = t; } 423cc48ffa7SToby Isaac ierr = MatGetLocalSize(C,&cm,&cn);CHKERRQ(ierr); 424*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(an != bm || bn != cm || bn != cn,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A, B, C local dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,am,an,bm,bn,cm,cn); 425cc48ffa7SToby Isaac 426447fed29SStefano Zampini /* Create left vector of A: v2 */ 427447fed29SStefano Zampini ierr = MatCreateVecs(A,&Bx,&v2);CHKERRQ(ierr); 428447fed29SStefano Zampini 429447fed29SStefano Zampini /* Create right vectors of B: x, v3, v4 */ 430447fed29SStefano Zampini if (rart) { 431447fed29SStefano Zampini ierr = MatCreateVecs(B,&v1,&x);CHKERRQ(ierr); 432447fed29SStefano Zampini } else { 433447fed29SStefano Zampini ierr = MatCreateVecs(B,&x,&v1);CHKERRQ(ierr); 434447fed29SStefano Zampini } 435447fed29SStefano Zampini ierr = VecDuplicate(x,&v3);CHKERRQ(ierr); 436447fed29SStefano Zampini 437447fed29SStefano Zampini ierr = MatCreateVecs(C,&Cx,&v4);CHKERRQ(ierr); 438447fed29SStefano Zampini ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rdm);CHKERRQ(ierr); 439447fed29SStefano Zampini ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); 440cc48ffa7SToby Isaac 441cc48ffa7SToby Isaac *flg = PETSC_TRUE; 442447fed29SStefano Zampini for (i=0; i<n; i++) { 443447fed29SStefano Zampini ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); 444447fed29SStefano Zampini ierr = VecCopy(x,Cx);CHKERRQ(ierr); 445447fed29SStefano Zampini ierr = MatMult(C,Cx,v4);CHKERRQ(ierr); /* v4 = C*x */ 446447fed29SStefano Zampini if (rart) { 447447fed29SStefano Zampini ierr = MatMultTranspose(B,x,v1);CHKERRQ(ierr); 448cc48ffa7SToby Isaac } else { 449447fed29SStefano Zampini ierr = MatMult(B,x,v1);CHKERRQ(ierr); 450cc48ffa7SToby Isaac } 451447fed29SStefano Zampini ierr = VecCopy(v1,Bx);CHKERRQ(ierr); 452447fed29SStefano Zampini ierr = MatMult(A,Bx,v2);CHKERRQ(ierr); /* v2 = A*B*x */ 453447fed29SStefano Zampini ierr = VecCopy(v2,v1);CHKERRQ(ierr); 454447fed29SStefano Zampini if (rart) { 455447fed29SStefano Zampini ierr = MatMult(B,v1,v3);CHKERRQ(ierr); /* v3 = R*A*R^t*x */ 456447fed29SStefano Zampini } else { 457447fed29SStefano Zampini ierr = MatMultTranspose(B,v1,v3);CHKERRQ(ierr); /* v3 = Bt*A*B*x */ 458447fed29SStefano Zampini } 459447fed29SStefano Zampini ierr = VecNorm(v4,NORM_2,&norm_abs);CHKERRQ(ierr); 460447fed29SStefano Zampini ierr = VecAXPY(v4,none,v3);CHKERRQ(ierr); 461447fed29SStefano Zampini ierr = VecNorm(v4,NORM_2,&norm_rel);CHKERRQ(ierr); 462447fed29SStefano Zampini 463447fed29SStefano Zampini if (norm_abs > tol) norm_rel /= norm_abs; 464447fed29SStefano Zampini if (norm_rel > tol) { 465cc48ffa7SToby Isaac *flg = PETSC_FALSE; 4667d3de750SJacob Faibussowitsch ierr = PetscInfo(A,"Error: %" PetscInt_FMT "-th Mat%sMult() %g\n",i,rart ? "RARt" : "PtAP",(double)norm_rel);CHKERRQ(ierr); 467cc48ffa7SToby Isaac break; 468cc48ffa7SToby Isaac } 469cc48ffa7SToby Isaac } 470447fed29SStefano Zampini 471447fed29SStefano Zampini ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); 472cc48ffa7SToby Isaac ierr = VecDestroy(&x);CHKERRQ(ierr); 473447fed29SStefano Zampini ierr = VecDestroy(&Bx);CHKERRQ(ierr); 474447fed29SStefano Zampini ierr = VecDestroy(&Cx);CHKERRQ(ierr); 475447fed29SStefano Zampini ierr = VecDestroy(&v1);CHKERRQ(ierr); 476447fed29SStefano Zampini ierr = VecDestroy(&v2);CHKERRQ(ierr); 477447fed29SStefano Zampini ierr = VecDestroy(&v3);CHKERRQ(ierr); 478447fed29SStefano Zampini ierr = VecDestroy(&v4);CHKERRQ(ierr); 479cc48ffa7SToby Isaac PetscFunctionReturn(0); 480cc48ffa7SToby Isaac } 481cc48ffa7SToby Isaac 48286919fd6SHong Zhang /*@ 4834222ddf1SHong Zhang MatPtAPMultEqual - Compares matrix-vector products of C = Bt*A*B 4844222ddf1SHong Zhang 4854222ddf1SHong Zhang Collective on Mat 4864222ddf1SHong Zhang 4874222ddf1SHong Zhang Input Parameters: 4884222ddf1SHong Zhang + A - the first matrix 4894222ddf1SHong Zhang . B - the second matrix 4904222ddf1SHong Zhang . C - the third matrix 4914222ddf1SHong Zhang - n - number of random vectors to be tested 4924222ddf1SHong Zhang 4934222ddf1SHong Zhang Output Parameter: 4944222ddf1SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 4954222ddf1SHong Zhang 4964222ddf1SHong Zhang Level: intermediate 4974222ddf1SHong Zhang 4984222ddf1SHong Zhang @*/ 4994222ddf1SHong Zhang PetscErrorCode MatPtAPMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 5004222ddf1SHong Zhang { 5014222ddf1SHong Zhang PetscErrorCode ierr; 5024222ddf1SHong Zhang 5034222ddf1SHong Zhang PetscFunctionBegin; 504447fed29SStefano Zampini ierr = MatProjMultEqual_Private(A,B,C,n,PETSC_FALSE,flg);CHKERRQ(ierr); 505447fed29SStefano Zampini PetscFunctionReturn(0); 5064222ddf1SHong Zhang } 5074222ddf1SHong Zhang 508447fed29SStefano Zampini /*@ 509447fed29SStefano Zampini MatRARtMultEqual - Compares matrix-vector products of C = B*A*B^t 510447fed29SStefano Zampini 511447fed29SStefano Zampini Collective on Mat 512447fed29SStefano Zampini 513447fed29SStefano Zampini Input Parameters: 514447fed29SStefano Zampini + A - the first matrix 515447fed29SStefano Zampini . B - the second matrix 516447fed29SStefano Zampini . C - the third matrix 517447fed29SStefano Zampini - n - number of random vectors to be tested 518447fed29SStefano Zampini 519447fed29SStefano Zampini Output Parameter: 520447fed29SStefano Zampini . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 521447fed29SStefano Zampini 522447fed29SStefano Zampini Level: intermediate 523447fed29SStefano Zampini 524447fed29SStefano Zampini @*/ 525447fed29SStefano Zampini PetscErrorCode MatRARtMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 526447fed29SStefano Zampini { 527447fed29SStefano Zampini PetscErrorCode ierr; 528447fed29SStefano Zampini 529447fed29SStefano Zampini PetscFunctionBegin; 530447fed29SStefano Zampini ierr = MatProjMultEqual_Private(A,B,C,n,PETSC_TRUE,flg);CHKERRQ(ierr); 5314222ddf1SHong Zhang PetscFunctionReturn(0); 5324222ddf1SHong Zhang } 5334222ddf1SHong Zhang 5344222ddf1SHong Zhang /*@ 53586919fd6SHong Zhang MatIsLinear - Check if a shell matrix A is a linear operator. 53686919fd6SHong Zhang 53786919fd6SHong Zhang Collective on Mat 53886919fd6SHong Zhang 53986919fd6SHong Zhang Input Parameters: 54086919fd6SHong Zhang + A - the shell matrix 54186919fd6SHong Zhang - n - number of random vectors to be tested 54286919fd6SHong Zhang 54386919fd6SHong Zhang Output Parameter: 54486919fd6SHong Zhang . flg - PETSC_TRUE if the shell matrix is linear; PETSC_FALSE otherwise. 54586919fd6SHong Zhang 54686919fd6SHong Zhang Level: intermediate 54786919fd6SHong Zhang @*/ 54886919fd6SHong Zhang PetscErrorCode MatIsLinear(Mat A,PetscInt n,PetscBool *flg) 54986919fd6SHong Zhang { 55086919fd6SHong Zhang PetscErrorCode ierr; 55186919fd6SHong Zhang Vec x,y,s1,s2; 55286919fd6SHong Zhang PetscRandom rctx; 55386919fd6SHong Zhang PetscScalar a; 55486919fd6SHong Zhang PetscInt k; 55586919fd6SHong Zhang PetscReal norm,normA; 55686919fd6SHong Zhang MPI_Comm comm; 55786919fd6SHong Zhang PetscMPIInt rank; 55886919fd6SHong Zhang 55986919fd6SHong Zhang PetscFunctionBegin; 56086919fd6SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 56186919fd6SHong Zhang ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 562ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 56386919fd6SHong Zhang 56486919fd6SHong Zhang ierr = PetscRandomCreate(comm,&rctx);CHKERRQ(ierr); 56586919fd6SHong Zhang ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); 56686919fd6SHong Zhang ierr = MatCreateVecs(A,&x,&s1);CHKERRQ(ierr); 56786919fd6SHong Zhang ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 56886919fd6SHong Zhang ierr = VecDuplicate(s1,&s2);CHKERRQ(ierr); 56986919fd6SHong Zhang 57086919fd6SHong Zhang *flg = PETSC_TRUE; 57186919fd6SHong Zhang for (k=0; k<n; k++) { 57286919fd6SHong Zhang ierr = VecSetRandom(x,rctx);CHKERRQ(ierr); 5736d5db48cSHong Zhang ierr = VecSetRandom(y,rctx);CHKERRQ(ierr); 574dd400576SPatrick Sanan if (rank == 0) { 57586919fd6SHong Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 57686919fd6SHong Zhang } 577ffc4695bSBarry Smith ierr = MPI_Bcast(&a, 1, MPIU_SCALAR, 0, comm);CHKERRMPI(ierr); 57886919fd6SHong Zhang 57986919fd6SHong Zhang /* s2 = a*A*x + A*y */ 58086919fd6SHong Zhang ierr = MatMult(A,y,s2);CHKERRQ(ierr); /* s2 = A*y */ 58186919fd6SHong Zhang ierr = MatMult(A,x,s1);CHKERRQ(ierr); /* s1 = A*x */ 58286919fd6SHong Zhang ierr = VecAXPY(s2,a,s1);CHKERRQ(ierr); /* s2 = a s1 + s2 */ 58386919fd6SHong Zhang 58486919fd6SHong Zhang /* s1 = A * (a x + y) */ 58586919fd6SHong Zhang ierr = VecAXPY(y,a,x);CHKERRQ(ierr); /* y = a x + y */ 58686919fd6SHong Zhang ierr = MatMult(A,y,s1);CHKERRQ(ierr); 58786919fd6SHong Zhang ierr = VecNorm(s1,NORM_INFINITY,&normA);CHKERRQ(ierr); 58886919fd6SHong Zhang 58986919fd6SHong Zhang ierr = VecAXPY(s2,-1.0,s1);CHKERRQ(ierr); /* s2 = - s1 + s2 */ 59086919fd6SHong Zhang ierr = VecNorm(s2,NORM_INFINITY,&norm);CHKERRQ(ierr); 5911b8dac88SHong Zhang if (norm/normA > 100.*PETSC_MACHINE_EPSILON) { 59286919fd6SHong Zhang *flg = PETSC_FALSE; 5937d3de750SJacob Faibussowitsch ierr = PetscInfo(A,"Error: %" PetscInt_FMT "-th |A*(ax+y) - (a*A*x+A*y)|/|A(ax+y)| %g > tol %g\n",k,(double)(norm/normA),(double)(100.*PETSC_MACHINE_EPSILON));CHKERRQ(ierr); 59486919fd6SHong Zhang break; 59586919fd6SHong Zhang } 59686919fd6SHong Zhang } 59786919fd6SHong Zhang ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); 59886919fd6SHong Zhang ierr = VecDestroy(&x);CHKERRQ(ierr); 59986919fd6SHong Zhang ierr = VecDestroy(&y);CHKERRQ(ierr); 60086919fd6SHong Zhang ierr = VecDestroy(&s1);CHKERRQ(ierr); 60186919fd6SHong Zhang ierr = VecDestroy(&s2);CHKERRQ(ierr); 60286919fd6SHong Zhang PetscFunctionReturn(0); 60386919fd6SHong Zhang } 604