186a22c91SHong Zhang 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 386a22c91SHong Zhang 4*447fed29SStefano Zampini static PetscErrorCode MatMultEqual_Private(Mat A,Mat B,PetscInt n,PetscBool *flg,PetscBool t,PetscBool add) 5*447fed29SStefano Zampini { 6*447fed29SStefano Zampini PetscErrorCode ierr; 7*447fed29SStefano Zampini Vec Ax,Bx,s1,s2,Ay = NULL, By = NULL; 8*447fed29SStefano Zampini PetscRandom rctx; 9*447fed29SStefano Zampini PetscReal r1,r2,tol=PETSC_SQRT_MACHINE_EPSILON; 10*447fed29SStefano Zampini PetscInt am,an,bm,bn,k; 11*447fed29SStefano Zampini PetscScalar none = -1.0; 12*447fed29SStefano Zampini const char* sops[] = {"MatMult","MatMultAdd","MatMultTranspose","MatMultTranposeAdd"}; 13*447fed29SStefano Zampini const char* sop; 14*447fed29SStefano Zampini 15*447fed29SStefano Zampini PetscFunctionBegin; 16*447fed29SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 17*447fed29SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,2); 18*447fed29SStefano Zampini PetscCheckSameComm(A,1,B,2); 19*447fed29SStefano Zampini PetscValidLogicalCollectiveInt(A,n,3); 20*447fed29SStefano Zampini PetscValidPointer(flg,4); 21*447fed29SStefano Zampini PetscValidLogicalCollectiveBool(A,t,5); 22*447fed29SStefano Zampini PetscValidLogicalCollectiveBool(A,add,6); 23*447fed29SStefano Zampini ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); 24*447fed29SStefano Zampini ierr = MatGetLocalSize(B,&bm,&bn);CHKERRQ(ierr); 25*447fed29SStefano Zampini if (am != bm || an != bn) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D %D %D",am,bm,an,bn); 26*447fed29SStefano Zampini sop = sops[(add ? 1 : 0) + 2 * (t ? 1 : 0)]; 27*447fed29SStefano Zampini ierr = PetscRandomCreate(PetscObjectComm((PetscObject)A),&rctx);CHKERRQ(ierr); 28*447fed29SStefano Zampini ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); 29*447fed29SStefano Zampini if (t) { 30*447fed29SStefano Zampini ierr = MatCreateVecs(A,&s1,&Ax);CHKERRQ(ierr); 31*447fed29SStefano Zampini ierr = MatCreateVecs(B,&s2,&Bx);CHKERRQ(ierr); 32*447fed29SStefano Zampini } else { 33*447fed29SStefano Zampini ierr = MatCreateVecs(A,&Ax,&s1);CHKERRQ(ierr); 34*447fed29SStefano Zampini ierr = MatCreateVecs(B,&Bx,&s2);CHKERRQ(ierr); 35*447fed29SStefano Zampini } 36*447fed29SStefano Zampini if (add) { 37*447fed29SStefano Zampini ierr = VecDuplicate(s1,&Ay);CHKERRQ(ierr); 38*447fed29SStefano Zampini ierr = VecDuplicate(s2,&By);CHKERRQ(ierr); 39*447fed29SStefano Zampini } 40*447fed29SStefano Zampini 41*447fed29SStefano Zampini *flg = PETSC_TRUE; 42*447fed29SStefano Zampini for (k=0; k<n; k++) { 43*447fed29SStefano Zampini ierr = VecSetRandom(Ax,rctx);CHKERRQ(ierr); 44*447fed29SStefano Zampini ierr = VecCopy(Ax,Bx);CHKERRQ(ierr); 45*447fed29SStefano Zampini if (add) { 46*447fed29SStefano Zampini ierr = VecSetRandom(Ay,rctx);CHKERRQ(ierr); 47*447fed29SStefano Zampini ierr = VecCopy(Ay,By);CHKERRQ(ierr); 48*447fed29SStefano Zampini } 49*447fed29SStefano Zampini if (t) { 50*447fed29SStefano Zampini if (add) { 51*447fed29SStefano Zampini ierr = MatMultTransposeAdd(A,Ax,Ay,s1);CHKERRQ(ierr); 52*447fed29SStefano Zampini ierr = MatMultTransposeAdd(B,Bx,By,s2);CHKERRQ(ierr); 53*447fed29SStefano Zampini } else { 54*447fed29SStefano Zampini ierr = MatMultTranspose(A,Ax,s1);CHKERRQ(ierr); 55*447fed29SStefano Zampini ierr = MatMultTranspose(B,Bx,s2);CHKERRQ(ierr); 56*447fed29SStefano Zampini } 57*447fed29SStefano Zampini } else { 58*447fed29SStefano Zampini if (add) { 59*447fed29SStefano Zampini ierr = MatMultAdd(A,Ax,Ay,s1);CHKERRQ(ierr); 60*447fed29SStefano Zampini ierr = MatMultAdd(B,Bx,By,s2);CHKERRQ(ierr); 61*447fed29SStefano Zampini } else { 62*447fed29SStefano Zampini ierr = MatMult(A,Ax,s1);CHKERRQ(ierr); 63*447fed29SStefano Zampini ierr = MatMult(B,Bx,s2);CHKERRQ(ierr); 64*447fed29SStefano Zampini } 65*447fed29SStefano Zampini } 66*447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r2);CHKERRQ(ierr); 67*447fed29SStefano Zampini if (r2 < tol) { 68*447fed29SStefano Zampini ierr = VecNorm(s1,NORM_INFINITY,&r1);CHKERRQ(ierr); 69*447fed29SStefano Zampini } else { 70*447fed29SStefano Zampini ierr = VecAXPY(s2,none,s1);CHKERRQ(ierr); 71*447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r1);CHKERRQ(ierr); 72*447fed29SStefano Zampini r1 /= r2; 73*447fed29SStefano Zampini } 74*447fed29SStefano Zampini if (r1 > tol) { 75*447fed29SStefano Zampini *flg = PETSC_FALSE; 76*447fed29SStefano Zampini ierr = PetscInfo3(A,"Error: %D-th %s() %g\n",k,sop,(double)r1);CHKERRQ(ierr); 77*447fed29SStefano Zampini break; 78*447fed29SStefano Zampini } 79*447fed29SStefano Zampini } 80*447fed29SStefano Zampini ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); 81*447fed29SStefano Zampini ierr = VecDestroy(&Ax);CHKERRQ(ierr); 82*447fed29SStefano Zampini ierr = VecDestroy(&Bx);CHKERRQ(ierr); 83*447fed29SStefano Zampini ierr = VecDestroy(&Ay);CHKERRQ(ierr); 84*447fed29SStefano Zampini ierr = VecDestroy(&By);CHKERRQ(ierr); 85*447fed29SStefano Zampini ierr = VecDestroy(&s1);CHKERRQ(ierr); 86*447fed29SStefano Zampini ierr = VecDestroy(&s2);CHKERRQ(ierr); 87*447fed29SStefano Zampini PetscFunctionReturn(0); 88*447fed29SStefano Zampini } 89*447fed29SStefano Zampini 90*447fed29SStefano Zampini static PetscErrorCode MatMatMultEqual_Private(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg,PetscBool At,PetscBool Bt) 91*447fed29SStefano Zampini { 92*447fed29SStefano Zampini PetscErrorCode ierr; 93*447fed29SStefano Zampini Vec Ax,Bx,Cx,s1,s2,s3; 94*447fed29SStefano Zampini PetscRandom rctx; 95*447fed29SStefano Zampini PetscReal r1,r2,tol=PETSC_SQRT_MACHINE_EPSILON; 96*447fed29SStefano Zampini PetscInt am,an,bm,bn,cm,cn,k; 97*447fed29SStefano Zampini PetscScalar none = -1.0; 98*447fed29SStefano Zampini const char* sops[] = {"MatMatMult","MatTransposeMatMult","MatMatTransposeMult","MatTransposeMatTranposeMult"}; 99*447fed29SStefano Zampini const char* sop; 100*447fed29SStefano Zampini 101*447fed29SStefano Zampini PetscFunctionBegin; 102*447fed29SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 103*447fed29SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,2); 104*447fed29SStefano Zampini PetscCheckSameComm(A,1,B,2); 105*447fed29SStefano Zampini PetscValidHeaderSpecific(C,MAT_CLASSID,3); 106*447fed29SStefano Zampini PetscCheckSameComm(A,1,C,3); 107*447fed29SStefano Zampini PetscValidLogicalCollectiveInt(A,n,4); 108*447fed29SStefano Zampini PetscValidPointer(flg,5); 109*447fed29SStefano Zampini PetscValidLogicalCollectiveBool(A,At,6); 110*447fed29SStefano Zampini PetscValidLogicalCollectiveBool(B,Bt,7); 111*447fed29SStefano Zampini ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); 112*447fed29SStefano Zampini ierr = MatGetLocalSize(B,&bm,&bn);CHKERRQ(ierr); 113*447fed29SStefano Zampini ierr = MatGetLocalSize(C,&cm,&cn);CHKERRQ(ierr); 114*447fed29SStefano Zampini if (At) { PetscInt tt = an; an = am; am = tt; }; 115*447fed29SStefano Zampini if (Bt) { PetscInt tt = bn; bn = bm; bm = tt; }; 116*447fed29SStefano Zampini if (an != bm || am != cm || bn != cn) SETERRQ6(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A, B, C local dim %D %D %D %D",am,an,bm,bn,cm,cn); 117*447fed29SStefano Zampini 118*447fed29SStefano Zampini sop = sops[(At ? 1 : 0) + 2 * (Bt ? 1 : 0)]; 119*447fed29SStefano Zampini ierr = PetscRandomCreate(PetscObjectComm((PetscObject)C),&rctx);CHKERRQ(ierr); 120*447fed29SStefano Zampini ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); 121*447fed29SStefano Zampini if (Bt) { 122*447fed29SStefano Zampini ierr = MatCreateVecs(B,&s1,&Bx);CHKERRQ(ierr); 123*447fed29SStefano Zampini } else { 124*447fed29SStefano Zampini ierr = MatCreateVecs(B,&Bx,&s1);CHKERRQ(ierr); 125*447fed29SStefano Zampini } 126*447fed29SStefano Zampini if (At) { 127*447fed29SStefano Zampini ierr = MatCreateVecs(A,&s2,&Ax);CHKERRQ(ierr); 128*447fed29SStefano Zampini } else { 129*447fed29SStefano Zampini ierr = MatCreateVecs(A,&Ax,&s2);CHKERRQ(ierr); 130*447fed29SStefano Zampini } 131*447fed29SStefano Zampini ierr = MatCreateVecs(C,&Cx,&s3);CHKERRQ(ierr); 132*447fed29SStefano Zampini 133*447fed29SStefano Zampini *flg = PETSC_TRUE; 134*447fed29SStefano Zampini for (k=0; k<n; k++) { 135*447fed29SStefano Zampini ierr = VecSetRandom(Bx,rctx);CHKERRQ(ierr); 136*447fed29SStefano Zampini if (Bt) { 137*447fed29SStefano Zampini ierr = MatMultTranspose(B,Bx,s1);CHKERRQ(ierr); 138*447fed29SStefano Zampini } else { 139*447fed29SStefano Zampini ierr = MatMult(B,Bx,s1);CHKERRQ(ierr); 140*447fed29SStefano Zampini } 141*447fed29SStefano Zampini ierr = VecCopy(s1,Ax);CHKERRQ(ierr); 142*447fed29SStefano Zampini if (At) { 143*447fed29SStefano Zampini ierr = MatMultTranspose(A,Ax,s2);CHKERRQ(ierr); 144*447fed29SStefano Zampini } else { 145*447fed29SStefano Zampini ierr = MatMult(A,Ax,s2);CHKERRQ(ierr); 146*447fed29SStefano Zampini } 147*447fed29SStefano Zampini ierr = VecCopy(Bx,Cx);CHKERRQ(ierr); 148*447fed29SStefano Zampini ierr = MatMult(C,Cx,s3);CHKERRQ(ierr); 149*447fed29SStefano Zampini 150*447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r2);CHKERRQ(ierr); 151*447fed29SStefano Zampini if (r2 < tol) { 152*447fed29SStefano Zampini ierr = VecNorm(s3,NORM_INFINITY,&r1);CHKERRQ(ierr); 153*447fed29SStefano Zampini } else { 154*447fed29SStefano Zampini ierr = VecAXPY(s2,none,s3);CHKERRQ(ierr); 155*447fed29SStefano Zampini ierr = VecNorm(s2,NORM_INFINITY,&r1);CHKERRQ(ierr); 156*447fed29SStefano Zampini r1 /= r2; 157*447fed29SStefano Zampini } 158*447fed29SStefano Zampini if (r1 > tol) { 159*447fed29SStefano Zampini *flg = PETSC_FALSE; 160*447fed29SStefano Zampini ierr = PetscInfo3(A,"Error: %D-th %s %g\n",k,sop,(double)r1);CHKERRQ(ierr); 161*447fed29SStefano Zampini break; 162*447fed29SStefano Zampini } 163*447fed29SStefano Zampini } 164*447fed29SStefano Zampini ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); 165*447fed29SStefano Zampini ierr = VecDestroy(&Ax);CHKERRQ(ierr); 166*447fed29SStefano Zampini ierr = VecDestroy(&Bx);CHKERRQ(ierr); 167*447fed29SStefano Zampini ierr = VecDestroy(&Cx);CHKERRQ(ierr); 168*447fed29SStefano Zampini ierr = VecDestroy(&s1);CHKERRQ(ierr); 169*447fed29SStefano Zampini ierr = VecDestroy(&s2);CHKERRQ(ierr); 170*447fed29SStefano Zampini ierr = VecDestroy(&s3);CHKERRQ(ierr); 171*447fed29SStefano Zampini PetscFunctionReturn(0); 172*447fed29SStefano Zampini } 173*447fed29SStefano Zampini 17486a22c91SHong Zhang /*@ 17586a22c91SHong Zhang MatMultEqual - Compares matrix-vector products of two matrices. 17686a22c91SHong Zhang 17786a22c91SHong Zhang Collective on Mat 17886a22c91SHong Zhang 17986a22c91SHong Zhang Input Parameters: 18086a22c91SHong Zhang + A - the first matrix 1814222ddf1SHong Zhang . B - the second matrix 18286a22c91SHong Zhang - n - number of random vectors to be tested 18386a22c91SHong Zhang 18486a22c91SHong Zhang Output Parameter: 18586a22c91SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 18686a22c91SHong Zhang 18786a22c91SHong Zhang Level: intermediate 18886a22c91SHong Zhang 18986a22c91SHong Zhang @*/ 1907087cfbeSBarry Smith PetscErrorCode MatMultEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 19186a22c91SHong Zhang { 19286a22c91SHong Zhang PetscErrorCode ierr; 19386a22c91SHong Zhang 19486a22c91SHong Zhang PetscFunctionBegin; 195*447fed29SStefano Zampini ierr = MatMultEqual_Private(A,B,n,flg,PETSC_FALSE,PETSC_FALSE);CHKERRQ(ierr); 19686a22c91SHong Zhang PetscFunctionReturn(0); 19786a22c91SHong Zhang } 19886a22c91SHong Zhang 19986a22c91SHong Zhang /*@ 20086a22c91SHong Zhang MatMultAddEqual - Compares matrix-vector products of two matrices. 20186a22c91SHong Zhang 20286a22c91SHong Zhang Collective on Mat 20386a22c91SHong Zhang 20486a22c91SHong Zhang Input Parameters: 20586a22c91SHong Zhang + A - the first matrix 2064222ddf1SHong Zhang . B - the second matrix 20786a22c91SHong Zhang - n - number of random vectors to be tested 20886a22c91SHong Zhang 20986a22c91SHong Zhang Output Parameter: 21086a22c91SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 21186a22c91SHong Zhang 21286a22c91SHong Zhang Level: intermediate 21386a22c91SHong Zhang 21486a22c91SHong Zhang @*/ 2157087cfbeSBarry Smith PetscErrorCode MatMultAddEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 21686a22c91SHong Zhang { 21786a22c91SHong Zhang PetscErrorCode ierr; 21886a22c91SHong Zhang 21986a22c91SHong Zhang PetscFunctionBegin; 220*447fed29SStefano Zampini ierr = MatMultEqual_Private(A,B,n,flg,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 22163879571SHong Zhang PetscFunctionReturn(0); 22263879571SHong Zhang } 22363879571SHong Zhang 22463879571SHong Zhang /*@ 22563879571SHong Zhang MatMultTransposeEqual - Compares matrix-vector products of two matrices. 22663879571SHong Zhang 22763879571SHong Zhang Collective on Mat 22863879571SHong Zhang 22963879571SHong Zhang Input Parameters: 23063879571SHong Zhang + A - the first matrix 2314222ddf1SHong Zhang . B - the second matrix 23263879571SHong Zhang - n - number of random vectors to be tested 23363879571SHong Zhang 23463879571SHong Zhang Output Parameter: 23563879571SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 23663879571SHong Zhang 23763879571SHong Zhang Level: intermediate 23863879571SHong Zhang 23963879571SHong Zhang @*/ 2407087cfbeSBarry Smith PetscErrorCode MatMultTransposeEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 24163879571SHong Zhang { 24263879571SHong Zhang PetscErrorCode ierr; 24363879571SHong Zhang 24463879571SHong Zhang PetscFunctionBegin; 245*447fed29SStefano Zampini ierr = MatMultEqual_Private(A,B,n,flg,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 24663879571SHong Zhang PetscFunctionReturn(0); 24763879571SHong Zhang } 24863879571SHong Zhang 24963879571SHong Zhang /*@ 25063879571SHong Zhang MatMultTransposeAddEqual - Compares matrix-vector products of two matrices. 25163879571SHong Zhang 25263879571SHong Zhang Collective on Mat 25363879571SHong Zhang 25463879571SHong Zhang Input Parameters: 25563879571SHong Zhang + A - the first matrix 2564222ddf1SHong Zhang . B - the second matrix 25763879571SHong Zhang - n - number of random vectors to be tested 25863879571SHong Zhang 25963879571SHong Zhang Output Parameter: 26063879571SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 26163879571SHong Zhang 26263879571SHong Zhang Level: intermediate 26363879571SHong Zhang 26463879571SHong Zhang @*/ 2657087cfbeSBarry Smith PetscErrorCode MatMultTransposeAddEqual(Mat A,Mat B,PetscInt n,PetscBool *flg) 26663879571SHong Zhang { 26763879571SHong Zhang PetscErrorCode ierr; 26863879571SHong Zhang 26963879571SHong Zhang PetscFunctionBegin; 270*447fed29SStefano Zampini ierr = MatMultEqual_Private(A,B,n,flg,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 27186a22c91SHong Zhang PetscFunctionReturn(0); 27286a22c91SHong Zhang } 273a52676ecSHong Zhang 274a52676ecSHong Zhang /*@ 275a52676ecSHong Zhang MatMatMultEqual - Test A*B*x = C*x for n random vector x 276a52676ecSHong Zhang 277a52676ecSHong Zhang Collective on Mat 278a52676ecSHong Zhang 279a52676ecSHong Zhang Input Parameters: 280a52676ecSHong Zhang + A - the first matrix 281c2916339SPierre Jolivet . B - the second matrix 282c2916339SPierre Jolivet . C - the third matrix 283a52676ecSHong Zhang - n - number of random vectors to be tested 284a52676ecSHong Zhang 285a52676ecSHong Zhang Output Parameter: 286f0fc11ceSJed Brown . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 287a52676ecSHong Zhang 288a52676ecSHong Zhang Level: intermediate 289a52676ecSHong Zhang 290a52676ecSHong Zhang @*/ 291a52676ecSHong Zhang PetscErrorCode MatMatMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 292a52676ecSHong Zhang { 293a52676ecSHong Zhang PetscErrorCode ierr; 294a52676ecSHong Zhang 295a52676ecSHong Zhang PetscFunctionBegin; 296*447fed29SStefano Zampini ierr = MatMatMultEqual_Private(A,B,C,n,flg,PETSC_FALSE,PETSC_FALSE);CHKERRQ(ierr); 297a52676ecSHong Zhang PetscFunctionReturn(0); 298a52676ecSHong Zhang } 299a52676ecSHong Zhang 300a52676ecSHong Zhang /*@ 301a52676ecSHong Zhang MatTransposeMatMultEqual - Test A^T*B*x = C*x for n random vector x 302a52676ecSHong Zhang 303a52676ecSHong Zhang Collective on Mat 304a52676ecSHong Zhang 305a52676ecSHong Zhang Input Parameters: 306a52676ecSHong Zhang + A - the first matrix 3074222ddf1SHong Zhang . B - the second matrix 3084222ddf1SHong Zhang . C - the third matrix 309a52676ecSHong Zhang - n - number of random vectors to be tested 310a52676ecSHong Zhang 311a52676ecSHong Zhang Output Parameter: 312a52676ecSHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 313a52676ecSHong Zhang 314a52676ecSHong Zhang Level: intermediate 315a52676ecSHong Zhang 316a52676ecSHong Zhang @*/ 317a52676ecSHong Zhang PetscErrorCode MatTransposeMatMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 318a52676ecSHong Zhang { 319a52676ecSHong Zhang PetscErrorCode ierr; 320a52676ecSHong Zhang 321a52676ecSHong Zhang PetscFunctionBegin; 322*447fed29SStefano Zampini ierr = MatMatMultEqual_Private(A,B,C,n,flg,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 323a52676ecSHong Zhang PetscFunctionReturn(0); 324a52676ecSHong Zhang } 32586919fd6SHong Zhang 32626546c1bSToby Isaac /*@ 32726546c1bSToby Isaac MatMatTransposeMultEqual - Test A*B^T*x = C*x for n random vector x 32826546c1bSToby Isaac 32926546c1bSToby Isaac Collective on Mat 33026546c1bSToby Isaac 33126546c1bSToby Isaac Input Parameters: 33226546c1bSToby Isaac + A - the first matrix 3334222ddf1SHong Zhang . B - the second matrix 3344222ddf1SHong Zhang . C - the third matrix 33526546c1bSToby Isaac - n - number of random vectors to be tested 33626546c1bSToby Isaac 33726546c1bSToby Isaac Output Parameter: 33826546c1bSToby Isaac . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 33926546c1bSToby Isaac 34026546c1bSToby Isaac Level: intermediate 34126546c1bSToby Isaac 34226546c1bSToby Isaac @*/ 343cc48ffa7SToby Isaac PetscErrorCode MatMatTransposeMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 344cc48ffa7SToby Isaac { 345cc48ffa7SToby Isaac PetscErrorCode ierr; 346*447fed29SStefano Zampini 347*447fed29SStefano Zampini PetscFunctionBegin; 348*447fed29SStefano Zampini ierr = MatMatMultEqual_Private(A,B,C,n,flg,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 349*447fed29SStefano Zampini PetscFunctionReturn(0); 350*447fed29SStefano Zampini } 351*447fed29SStefano Zampini 352*447fed29SStefano Zampini static PetscErrorCode MatProjMultEqual_Private(Mat A,Mat B,Mat C,PetscInt n,PetscBool rart,PetscBool *flg) 353*447fed29SStefano Zampini { 354*447fed29SStefano Zampini PetscErrorCode ierr; 355*447fed29SStefano Zampini Vec x,v1,v2,v3,v4,Cx,Bx; 356*447fed29SStefano Zampini PetscReal norm_abs,norm_rel,tol=PETSC_SQRT_MACHINE_EPSILON; 357*447fed29SStefano Zampini PetscInt i,am,an,bm,bn,cm,cn; 358*447fed29SStefano Zampini PetscRandom rdm; 359cc48ffa7SToby Isaac PetscScalar none = -1.0; 360cc48ffa7SToby Isaac 361cc48ffa7SToby Isaac PetscFunctionBegin; 362cc48ffa7SToby Isaac ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); 363cc48ffa7SToby Isaac ierr = MatGetLocalSize(B,&bm,&bn);CHKERRQ(ierr); 364*447fed29SStefano Zampini if (rart) { PetscInt t = bm; bm = bn; bn = t; } 365cc48ffa7SToby Isaac ierr = MatGetLocalSize(C,&cm,&cn);CHKERRQ(ierr); 366*447fed29SStefano Zampini if (an != bm || bn != cm || bn != cn) SETERRQ6(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A, B, C local dim %D %D %D %D %D %D",am,an,bm,bn,cm,cn); 367cc48ffa7SToby Isaac 368*447fed29SStefano Zampini /* Create left vector of A: v2 */ 369*447fed29SStefano Zampini ierr = MatCreateVecs(A,&Bx,&v2);CHKERRQ(ierr); 370*447fed29SStefano Zampini 371*447fed29SStefano Zampini /* Create right vectors of B: x, v3, v4 */ 372*447fed29SStefano Zampini if (rart) { 373*447fed29SStefano Zampini ierr = MatCreateVecs(B,&v1,&x);CHKERRQ(ierr); 374*447fed29SStefano Zampini } else { 375*447fed29SStefano Zampini ierr = MatCreateVecs(B,&x,&v1);CHKERRQ(ierr); 376*447fed29SStefano Zampini } 377*447fed29SStefano Zampini ierr = VecDuplicate(x,&v3);CHKERRQ(ierr); 378*447fed29SStefano Zampini 379*447fed29SStefano Zampini ierr = MatCreateVecs(C,&Cx,&v4);CHKERRQ(ierr); 380*447fed29SStefano Zampini ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rdm);CHKERRQ(ierr); 381*447fed29SStefano Zampini ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); 382cc48ffa7SToby Isaac 383cc48ffa7SToby Isaac *flg = PETSC_TRUE; 384*447fed29SStefano Zampini for (i=0; i<n; i++) { 385*447fed29SStefano Zampini ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); 386*447fed29SStefano Zampini ierr = VecCopy(x,Cx);CHKERRQ(ierr); 387*447fed29SStefano Zampini ierr = MatMult(C,Cx,v4);CHKERRQ(ierr); /* v4 = C*x */ 388*447fed29SStefano Zampini if (rart) { 389*447fed29SStefano Zampini ierr = MatMultTranspose(B,x,v1);CHKERRQ(ierr); 390cc48ffa7SToby Isaac } else { 391*447fed29SStefano Zampini ierr = MatMult(B,x,v1);CHKERRQ(ierr); 392cc48ffa7SToby Isaac } 393*447fed29SStefano Zampini ierr = VecCopy(v1,Bx);CHKERRQ(ierr); 394*447fed29SStefano Zampini ierr = MatMult(A,Bx,v2);CHKERRQ(ierr); /* v2 = A*B*x */ 395*447fed29SStefano Zampini ierr = VecCopy(v2,v1);CHKERRQ(ierr); 396*447fed29SStefano Zampini if (rart) { 397*447fed29SStefano Zampini ierr = MatMult(B,v1,v3);CHKERRQ(ierr); /* v3 = R*A*R^t*x */ 398*447fed29SStefano Zampini } else { 399*447fed29SStefano Zampini ierr = MatMultTranspose(B,v1,v3);CHKERRQ(ierr); /* v3 = Bt*A*B*x */ 400*447fed29SStefano Zampini } 401*447fed29SStefano Zampini ierr = VecNorm(v4,NORM_2,&norm_abs);CHKERRQ(ierr); 402*447fed29SStefano Zampini ierr = VecAXPY(v4,none,v3);CHKERRQ(ierr); 403*447fed29SStefano Zampini ierr = VecNorm(v4,NORM_2,&norm_rel);CHKERRQ(ierr); 404*447fed29SStefano Zampini 405*447fed29SStefano Zampini if (norm_abs > tol) norm_rel /= norm_abs; 406*447fed29SStefano Zampini if (norm_rel > tol) { 407cc48ffa7SToby Isaac *flg = PETSC_FALSE; 408*447fed29SStefano Zampini ierr = PetscInfo3(A,"Error: %D-th Mat%sMult() %g\n",i,rart ? "RARt" : "PtAP",(double)norm_rel);CHKERRQ(ierr); 409cc48ffa7SToby Isaac break; 410cc48ffa7SToby Isaac } 411cc48ffa7SToby Isaac } 412*447fed29SStefano Zampini 413*447fed29SStefano Zampini ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); 414cc48ffa7SToby Isaac ierr = VecDestroy(&x);CHKERRQ(ierr); 415*447fed29SStefano Zampini ierr = VecDestroy(&Bx);CHKERRQ(ierr); 416*447fed29SStefano Zampini ierr = VecDestroy(&Cx);CHKERRQ(ierr); 417*447fed29SStefano Zampini ierr = VecDestroy(&v1);CHKERRQ(ierr); 418*447fed29SStefano Zampini ierr = VecDestroy(&v2);CHKERRQ(ierr); 419*447fed29SStefano Zampini ierr = VecDestroy(&v3);CHKERRQ(ierr); 420*447fed29SStefano Zampini ierr = VecDestroy(&v4);CHKERRQ(ierr); 421cc48ffa7SToby Isaac PetscFunctionReturn(0); 422cc48ffa7SToby Isaac } 423cc48ffa7SToby Isaac 42486919fd6SHong Zhang /*@ 4254222ddf1SHong Zhang MatPtAPMultEqual - Compares matrix-vector products of C = Bt*A*B 4264222ddf1SHong Zhang 4274222ddf1SHong Zhang Collective on Mat 4284222ddf1SHong Zhang 4294222ddf1SHong Zhang Input Parameters: 4304222ddf1SHong Zhang + A - the first matrix 4314222ddf1SHong Zhang . B - the second matrix 4324222ddf1SHong Zhang . C - the third matrix 4334222ddf1SHong Zhang - n - number of random vectors to be tested 4344222ddf1SHong Zhang 4354222ddf1SHong Zhang Output Parameter: 4364222ddf1SHong Zhang . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 4374222ddf1SHong Zhang 4384222ddf1SHong Zhang Level: intermediate 4394222ddf1SHong Zhang 4404222ddf1SHong Zhang @*/ 4414222ddf1SHong Zhang PetscErrorCode MatPtAPMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 4424222ddf1SHong Zhang { 4434222ddf1SHong Zhang PetscErrorCode ierr; 4444222ddf1SHong Zhang 4454222ddf1SHong Zhang PetscFunctionBegin; 446*447fed29SStefano Zampini ierr = MatProjMultEqual_Private(A,B,C,n,PETSC_FALSE,flg);CHKERRQ(ierr); 447*447fed29SStefano Zampini PetscFunctionReturn(0); 4484222ddf1SHong Zhang } 4494222ddf1SHong Zhang 450*447fed29SStefano Zampini /*@ 451*447fed29SStefano Zampini MatRARtMultEqual - Compares matrix-vector products of C = B*A*B^t 452*447fed29SStefano Zampini 453*447fed29SStefano Zampini Collective on Mat 454*447fed29SStefano Zampini 455*447fed29SStefano Zampini Input Parameters: 456*447fed29SStefano Zampini + A - the first matrix 457*447fed29SStefano Zampini . B - the second matrix 458*447fed29SStefano Zampini . C - the third matrix 459*447fed29SStefano Zampini - n - number of random vectors to be tested 460*447fed29SStefano Zampini 461*447fed29SStefano Zampini Output Parameter: 462*447fed29SStefano Zampini . flg - PETSC_TRUE if the products are equal; PETSC_FALSE otherwise. 463*447fed29SStefano Zampini 464*447fed29SStefano Zampini Level: intermediate 465*447fed29SStefano Zampini 466*447fed29SStefano Zampini @*/ 467*447fed29SStefano Zampini PetscErrorCode MatRARtMultEqual(Mat A,Mat B,Mat C,PetscInt n,PetscBool *flg) 468*447fed29SStefano Zampini { 469*447fed29SStefano Zampini PetscErrorCode ierr; 470*447fed29SStefano Zampini 471*447fed29SStefano Zampini PetscFunctionBegin; 472*447fed29SStefano Zampini ierr = MatProjMultEqual_Private(A,B,C,n,PETSC_TRUE,flg);CHKERRQ(ierr); 4734222ddf1SHong Zhang PetscFunctionReturn(0); 4744222ddf1SHong Zhang } 4754222ddf1SHong Zhang 4764222ddf1SHong Zhang /*@ 47786919fd6SHong Zhang MatIsLinear - Check if a shell matrix A is a linear operator. 47886919fd6SHong Zhang 47986919fd6SHong Zhang Collective on Mat 48086919fd6SHong Zhang 48186919fd6SHong Zhang Input Parameters: 48286919fd6SHong Zhang + A - the shell matrix 48386919fd6SHong Zhang - n - number of random vectors to be tested 48486919fd6SHong Zhang 48586919fd6SHong Zhang Output Parameter: 48686919fd6SHong Zhang . flg - PETSC_TRUE if the shell matrix is linear; PETSC_FALSE otherwise. 48786919fd6SHong Zhang 48886919fd6SHong Zhang Level: intermediate 48986919fd6SHong Zhang @*/ 49086919fd6SHong Zhang PetscErrorCode MatIsLinear(Mat A,PetscInt n,PetscBool *flg) 49186919fd6SHong Zhang { 49286919fd6SHong Zhang PetscErrorCode ierr; 49386919fd6SHong Zhang Vec x,y,s1,s2; 49486919fd6SHong Zhang PetscRandom rctx; 49586919fd6SHong Zhang PetscScalar a; 49686919fd6SHong Zhang PetscInt k; 49786919fd6SHong Zhang PetscReal norm,normA; 49886919fd6SHong Zhang MPI_Comm comm; 49986919fd6SHong Zhang PetscMPIInt rank; 50086919fd6SHong Zhang 50186919fd6SHong Zhang PetscFunctionBegin; 50286919fd6SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 50386919fd6SHong Zhang ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 50486919fd6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 50586919fd6SHong Zhang 50686919fd6SHong Zhang ierr = PetscRandomCreate(comm,&rctx);CHKERRQ(ierr); 50786919fd6SHong Zhang ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); 50886919fd6SHong Zhang ierr = MatCreateVecs(A,&x,&s1);CHKERRQ(ierr); 50986919fd6SHong Zhang ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 51086919fd6SHong Zhang ierr = VecDuplicate(s1,&s2);CHKERRQ(ierr); 51186919fd6SHong Zhang 51286919fd6SHong Zhang *flg = PETSC_TRUE; 51386919fd6SHong Zhang for (k=0; k<n; k++) { 51486919fd6SHong Zhang ierr = VecSetRandom(x,rctx);CHKERRQ(ierr); 5156d5db48cSHong Zhang ierr = VecSetRandom(y,rctx);CHKERRQ(ierr); 51686919fd6SHong Zhang if (!rank) { 51786919fd6SHong Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 51886919fd6SHong Zhang } 51986919fd6SHong Zhang ierr = MPI_Bcast(&a, 1, MPIU_SCALAR, 0, comm);CHKERRQ(ierr); 52086919fd6SHong Zhang 52186919fd6SHong Zhang /* s2 = a*A*x + A*y */ 52286919fd6SHong Zhang ierr = MatMult(A,y,s2);CHKERRQ(ierr); /* s2 = A*y */ 52386919fd6SHong Zhang ierr = MatMult(A,x,s1);CHKERRQ(ierr); /* s1 = A*x */ 52486919fd6SHong Zhang ierr = VecAXPY(s2,a,s1);CHKERRQ(ierr); /* s2 = a s1 + s2 */ 52586919fd6SHong Zhang 52686919fd6SHong Zhang /* s1 = A * (a x + y) */ 52786919fd6SHong Zhang ierr = VecAXPY(y,a,x);CHKERRQ(ierr); /* y = a x + y */ 52886919fd6SHong Zhang ierr = MatMult(A,y,s1);CHKERRQ(ierr); 52986919fd6SHong Zhang ierr = VecNorm(s1,NORM_INFINITY,&normA);CHKERRQ(ierr); 53086919fd6SHong Zhang 53186919fd6SHong Zhang ierr = VecAXPY(s2,-1.0,s1);CHKERRQ(ierr); /* s2 = - s1 + s2 */ 53286919fd6SHong Zhang ierr = VecNorm(s2,NORM_INFINITY,&norm);CHKERRQ(ierr); 5331b8dac88SHong Zhang if (norm/normA > 100.*PETSC_MACHINE_EPSILON) { 53486919fd6SHong Zhang *flg = PETSC_FALSE; 5351b8dac88SHong Zhang ierr = PetscInfo3(A,"Error: %D-th |A*(ax+y) - (a*A*x+A*y)|/|A(ax+y)| %g > tol %g\n",k,(double)norm/normA,100.*PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 53686919fd6SHong Zhang break; 53786919fd6SHong Zhang } 53886919fd6SHong Zhang } 53986919fd6SHong Zhang ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); 54086919fd6SHong Zhang ierr = VecDestroy(&x);CHKERRQ(ierr); 54186919fd6SHong Zhang ierr = VecDestroy(&y);CHKERRQ(ierr); 54286919fd6SHong Zhang ierr = VecDestroy(&s1);CHKERRQ(ierr); 54386919fd6SHong Zhang ierr = VecDestroy(&s2);CHKERRQ(ierr); 54486919fd6SHong Zhang PetscFunctionReturn(0); 54586919fd6SHong Zhang } 546