1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*606d414cSSatish Balay static char vcid[] = "$Id: axpy.c,v 1.39 1999/05/04 20:33:40 balay Exp balay $"; 36f79c3a4SBarry Smith #endif 46f79c3a4SBarry Smith 570f55243SBarry Smith #include "src/mat/matimpl.h" /*I "mat.h" I*/ 66f79c3a4SBarry Smith 75615d1e5SSatish Balay #undef __FUNC__ 85615d1e5SSatish Balay #define __FUNC__ "MatAXPY" 906be10caSBarry Smith /*@ 1021c89e3eSBarry Smith MatAXPY - Computes Y = a*X + Y. 116f79c3a4SBarry Smith 12fee21e36SBarry Smith Collective on Mat 13fee21e36SBarry Smith 1498a79cdbSBarry Smith Input Parameters: 1598a79cdbSBarry Smith + X, Y - the matrices 1698a79cdbSBarry Smith - a - the scalar multiplier 1798a79cdbSBarry Smith 18e182c471SBarry Smith Contributed by: Matthew Knepley 19d4bb536fSBarry Smith 202860a424SLois Curfman McInnes Notes: 212860a424SLois Curfman McInnes Since the current implementation of MatAXPY() uses MatGetRow() to access 222860a424SLois Curfman McInnes matrix data, efficiency is somewhat limited. 232860a424SLois Curfman McInnes 242860a424SLois Curfman McInnes Level: intermediate 252860a424SLois Curfman McInnes 269cf4f1e8SLois Curfman McInnes .keywords: matrix, add 27d4bb536fSBarry Smith 282860a424SLois Curfman McInnes .seealso: MatAYPX() 2906be10caSBarry Smith @*/ 3006be10caSBarry Smith int MatAXPY(Scalar *a,Mat X,Mat Y) 316f79c3a4SBarry Smith { 3206be10caSBarry Smith int m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr; 3306be10caSBarry Smith Scalar *val,*vals; 346f79c3a4SBarry Smith 353a40ed3dSBarry Smith PetscFunctionBegin; 36d4bb536fSBarry Smith PetscValidHeaderSpecific(X,MAT_COOKIE); 37d4bb536fSBarry Smith PetscValidHeaderSpecific(Y,MAT_COOKIE); 3890f02eecSBarry Smith PetscValidScalarPointer(a); 3990f02eecSBarry Smith 40d4bb536fSBarry Smith MatGetSize(X,&m1,&n1); MatGetSize(Y,&m2,&n2); 41596552b5SBarry Smith if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2); 421987afe7SBarry Smith 43f830108cSBarry Smith if (X->ops->axpy) { 44f830108cSBarry Smith ierr = (*X->ops->axpy)(a,X,Y);CHKERRQ(ierr); 45d4bb536fSBarry Smith } else { 4690f02eecSBarry Smith ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr); 47d4bb536fSBarry Smith if (*a == 1.0) { 48d4bb536fSBarry Smith for (i = start; i < end; i++) { 49d4bb536fSBarry Smith ierr = MatGetRow(X, i, &ncols, &row, &vals);CHKERRQ(ierr); 50d4bb536fSBarry Smith ierr = MatSetValues(Y, 1, &i, ncols, row, vals, ADD_VALUES);CHKERRQ(ierr); 51d4bb536fSBarry Smith ierr = MatRestoreRow(X, i, &ncols, &row, &vals);CHKERRQ(ierr); 52d4bb536fSBarry Smith } 53d4bb536fSBarry Smith } else { 54d4bb536fSBarry Smith vals = (Scalar *) PetscMalloc( (n1+1)*sizeof(Scalar) );CHKPTRQ(vals); 5506be10caSBarry Smith for ( i=start; i<end; i++ ) { 5690f02eecSBarry Smith ierr = MatGetRow(X,i,&ncols,&row,&val);CHKERRQ(ierr); 5706be10caSBarry Smith for ( j=0; j<ncols; j++ ) { 5806be10caSBarry Smith vals[j] = (*a)*val[j]; 596f79c3a4SBarry Smith } 60dbb450caSBarry Smith ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); 6190f02eecSBarry Smith ierr = MatRestoreRow(X,i,&ncols,&row,&val);CHKERRQ(ierr); 626f79c3a4SBarry Smith } 63*606d414cSSatish Balay ierr = PetscFree(vals);CHKERRQ(ierr); 64d4bb536fSBarry Smith } 656d4a8577SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 666d4a8577SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 671987afe7SBarry Smith } 683a40ed3dSBarry Smith PetscFunctionReturn(0); 696f79c3a4SBarry Smith } 70052efed2SBarry Smith 715615d1e5SSatish Balay #undef __FUNC__ 725615d1e5SSatish Balay #define __FUNC__ "MatShift" 73052efed2SBarry Smith /*@ 742860a424SLois Curfman McInnes MatShift - Computes Y = Y + a I, where a is a scalar and I is the identity matrix. 75052efed2SBarry Smith 76fee21e36SBarry Smith Collective on Mat 77fee21e36SBarry Smith 7898a79cdbSBarry Smith Input Parameters: 7998a79cdbSBarry Smith + Y - the matrices 8098a79cdbSBarry Smith - a - the scalar 8198a79cdbSBarry Smith 822860a424SLois Curfman McInnes Level: intermediate 832860a424SLois Curfman McInnes 84052efed2SBarry Smith .keywords: matrix, add, shift 856b9ee512SLois Curfman McInnes 866b9ee512SLois Curfman McInnes .seealso: MatDiagonalShift() 87052efed2SBarry Smith @*/ 88052efed2SBarry Smith int MatShift(Scalar *a,Mat Y) 89052efed2SBarry Smith { 90052efed2SBarry Smith int i,start,end,ierr; 91052efed2SBarry Smith 923a40ed3dSBarry Smith PetscFunctionBegin; 9377c4ece6SBarry Smith PetscValidHeaderSpecific(Y,MAT_COOKIE); 9490f02eecSBarry Smith PetscValidScalarPointer(a); 95f830108cSBarry Smith if (Y->ops->shift) { 96f830108cSBarry Smith ierr = (*Y->ops->shift)(a,Y);CHKERRQ(ierr); 9762d58ce1SBarry Smith } else { 98d4bb536fSBarry Smith ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 99052efed2SBarry Smith for ( i=start; i<end; i++ ) { 100052efed2SBarry Smith ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES);CHKERRQ(ierr); 101052efed2SBarry Smith } 1026d4a8577SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1036d4a8577SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 104052efed2SBarry Smith } 1053a40ed3dSBarry Smith PetscFunctionReturn(0); 106052efed2SBarry Smith } 1076d84be18SBarry Smith 1085615d1e5SSatish Balay #undef __FUNC__ 1095615d1e5SSatish Balay #define __FUNC__ "MatDiagonalShift" 1106d84be18SBarry Smith /*@ 1116b9ee512SLois Curfman McInnes MatDiagonalShift - Computes Y = Y + D, where D is a diagonal matrix 1126b9ee512SLois Curfman McInnes that is represented as a vector. 1136d84be18SBarry Smith 1146d84be18SBarry Smith Input Parameters: 11598a79cdbSBarry Smith + Y - the input matrix 11698a79cdbSBarry Smith - D - the diagonal matrix, represented as a vector 1176d84be18SBarry Smith 1186b9ee512SLois Curfman McInnes Input Parameters: 1196b9ee512SLois Curfman McInnes . Y - the shifted ouput matrix 1206d84be18SBarry Smith 121fee21e36SBarry Smith Collective on Mat and Vec 122fee21e36SBarry Smith 1232860a424SLois Curfman McInnes Level: intermediate 1242860a424SLois Curfman McInnes 1256b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal 1266b9ee512SLois Curfman McInnes 1276b9ee512SLois Curfman McInnes .seealso: MatShift() 1286d84be18SBarry Smith @*/ 1296d84be18SBarry Smith int MatDiagonalShift(Mat Y,Vec D) 1306d84be18SBarry Smith { 1316d84be18SBarry Smith int i,start,end,ierr; 1326d84be18SBarry Smith 1333a40ed3dSBarry Smith PetscFunctionBegin; 13477c4ece6SBarry Smith PetscValidHeaderSpecific(Y,MAT_COOKIE); 13590f02eecSBarry Smith PetscValidHeaderSpecific(D,VEC_COOKIE); 136f830108cSBarry Smith if (Y->ops->shift) { 137f830108cSBarry Smith ierr = (*Y->ops->diagonalshift)(D,Y);CHKERRQ(ierr); 13894d884c6SBarry Smith } else { 1396d84be18SBarry Smith int vstart,vend; 1406d84be18SBarry Smith Scalar *v; 1416d84be18SBarry Smith ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr); 1426d84be18SBarry Smith ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 143d4bb536fSBarry Smith if (vstart != start || vend != end) { 144596552b5SBarry Smith SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end); 145d4bb536fSBarry Smith } 1466d84be18SBarry Smith 1476d84be18SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 1486d84be18SBarry Smith for ( i=start; i<end; i++ ) { 1496d84be18SBarry Smith ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,ADD_VALUES);CHKERRQ(ierr); 1506d84be18SBarry Smith } 1512e8a6d31SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 1526d4a8577SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1536d4a8577SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1546d84be18SBarry Smith } 1553a40ed3dSBarry Smith PetscFunctionReturn(0); 1566d84be18SBarry Smith } 157d4bb536fSBarry Smith 158d4bb536fSBarry Smith #undef __FUNC__ 159d4bb536fSBarry Smith #define __FUNC__ "MatAYPX" 160d4bb536fSBarry Smith /*@ 161d4bb536fSBarry Smith MatAYPX - Computes Y = X + a*Y. 162d4bb536fSBarry Smith 163fee21e36SBarry Smith Collective on Mat 164fee21e36SBarry Smith 16598a79cdbSBarry Smith Input Parameters: 16698a79cdbSBarry Smith + X,Y - the matrices 16798a79cdbSBarry Smith - a - the scalar multiplier 16898a79cdbSBarry Smith 169e182c471SBarry Smith Contributed by: Matthew Knepley 170d4bb536fSBarry Smith 1712860a424SLois Curfman McInnes Notes: 1722860a424SLois Curfman McInnes This routine currently uses the MatAXPY() implementation. 1732860a424SLois Curfman McInnes 1742860a424SLois Curfman McInnes Level: intermediate 1752860a424SLois Curfman McInnes 176d4bb536fSBarry Smith .keywords: matrix, add 177d4bb536fSBarry Smith 1782860a424SLois Curfman McInnes .seealso: MatAXPY() 179d4bb536fSBarry Smith @*/ 180d4bb536fSBarry Smith int MatAYPX(Scalar *a,Mat X,Mat Y) 181d4bb536fSBarry Smith { 182d4bb536fSBarry Smith Scalar one = 1.0; 183d4bb536fSBarry Smith int mX, mY,nX, nY,ierr; 184d4bb536fSBarry Smith 1853a40ed3dSBarry Smith PetscFunctionBegin; 186d4bb536fSBarry Smith PetscValidHeaderSpecific(X, MAT_COOKIE); 187d4bb536fSBarry Smith PetscValidHeaderSpecific(Y, MAT_COOKIE); 188d4bb536fSBarry Smith PetscValidScalarPointer(a); 189d4bb536fSBarry Smith 190d4bb536fSBarry Smith MatGetSize(X, &mX, &nX); 191d4bb536fSBarry Smith MatGetSize(X, &mY, &nY); 192596552b5SBarry Smith if (mX != mY || nX != nY) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Non conforming matrices: %d %d first %d %d second",mX,mY,nX,nY); 193d4bb536fSBarry Smith 194d4bb536fSBarry Smith ierr = MatScale(a, Y);CHKERRQ(ierr); 195d4bb536fSBarry Smith ierr = MatAXPY(&one, X, Y);CHKERRQ(ierr); 1963a40ed3dSBarry Smith PetscFunctionReturn(0); 197d4bb536fSBarry Smith } 198