xref: /petsc/src/mat/utils/axpy.c (revision 606d414c6e034e02e67059b83ebaefc3ebe99698)
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