xref: /petsc/src/mat/utils/axpy.c (revision e090d5668ba2b2ea997ebb925e3a05be0dc5d9ab)
1*e090d566SSatish Balay /*$Id: axpy.c,v 1.44 2000/04/12 04:24:13 bsmith Exp balay $*/
26f79c3a4SBarry Smith 
3*e090d566SSatish Balay #include "src/mat/matimpl.h"  /*I   "petscmat.h"  I*/
46f79c3a4SBarry Smith 
55615d1e5SSatish Balay #undef __FUNC__
6b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatAXPY"
706be10caSBarry Smith /*@
821c89e3eSBarry Smith    MatAXPY - Computes Y = a*X + Y.
96f79c3a4SBarry Smith 
10fee21e36SBarry Smith    Collective on Mat
11fee21e36SBarry Smith 
1298a79cdbSBarry Smith    Input Parameters:
1398a79cdbSBarry Smith +  X, Y - the matrices
1498a79cdbSBarry Smith -  a - the scalar multiplier
1598a79cdbSBarry Smith 
16e182c471SBarry Smith    Contributed by: Matthew Knepley
17d4bb536fSBarry Smith 
182860a424SLois Curfman McInnes    Notes:
192860a424SLois Curfman McInnes    Since the current implementation of MatAXPY() uses MatGetRow() to access
202860a424SLois Curfman McInnes    matrix data, efficiency is somewhat limited.
212860a424SLois Curfman McInnes 
222860a424SLois Curfman McInnes    Level: intermediate
232860a424SLois Curfman McInnes 
249cf4f1e8SLois Curfman McInnes .keywords: matrix, add
25d4bb536fSBarry Smith 
262860a424SLois Curfman McInnes .seealso: MatAYPX()
2706be10caSBarry Smith  @*/
2806be10caSBarry Smith int MatAXPY(Scalar *a,Mat X,Mat Y)
296f79c3a4SBarry Smith {
3006be10caSBarry Smith   int    m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr;
3106be10caSBarry Smith   Scalar *val,*vals;
326f79c3a4SBarry Smith 
333a40ed3dSBarry Smith   PetscFunctionBegin;
34d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
35d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
3690f02eecSBarry Smith   PetscValidScalarPointer(a);
3790f02eecSBarry Smith 
38d4bb536fSBarry Smith   MatGetSize(X,&m1,&n1);  MatGetSize(Y,&m2,&n2);
39596552b5SBarry Smith   if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2);
401987afe7SBarry Smith 
41f830108cSBarry Smith   if (X->ops->axpy) {
42f830108cSBarry Smith     ierr = (*X->ops->axpy)(a,X,Y);CHKERRQ(ierr);
43d4bb536fSBarry Smith   } else {
4490f02eecSBarry Smith     ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr);
45d4bb536fSBarry Smith     if (*a == 1.0) {
46d4bb536fSBarry Smith       for (i = start; i < end; i++) {
47d4bb536fSBarry Smith         ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
48d4bb536fSBarry Smith         ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
49d4bb536fSBarry Smith         ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
50d4bb536fSBarry Smith       }
51d4bb536fSBarry Smith     } else {
52d4bb536fSBarry Smith       vals = (Scalar*)PetscMalloc((n1+1)*sizeof(Scalar));CHKPTRQ(vals);
5306be10caSBarry Smith       for (i=start; i<end; i++) {
5490f02eecSBarry Smith         ierr = MatGetRow(X,i,&ncols,&row,&val);CHKERRQ(ierr);
5506be10caSBarry Smith         for (j=0; j<ncols; j++) {
5606be10caSBarry Smith           vals[j] = (*a)*val[j];
576f79c3a4SBarry Smith         }
58dbb450caSBarry Smith         ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
5990f02eecSBarry Smith         ierr = MatRestoreRow(X,i,&ncols,&row,&val);CHKERRQ(ierr);
606f79c3a4SBarry Smith       }
61606d414cSSatish Balay       ierr = PetscFree(vals);CHKERRQ(ierr);
62d4bb536fSBarry Smith     }
636d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
646d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
651987afe7SBarry Smith   }
663a40ed3dSBarry Smith   PetscFunctionReturn(0);
676f79c3a4SBarry Smith }
68052efed2SBarry Smith 
695615d1e5SSatish Balay #undef __FUNC__
70b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatShift"
71052efed2SBarry Smith /*@
722860a424SLois Curfman McInnes    MatShift - Computes Y =  Y + a I, where a is a scalar and I is the identity matrix.
73052efed2SBarry Smith 
74fee21e36SBarry Smith    Collective on Mat
75fee21e36SBarry Smith 
7698a79cdbSBarry Smith    Input Parameters:
7798a79cdbSBarry Smith +  Y - the matrices
7898a79cdbSBarry Smith -  a - the scalar
7998a79cdbSBarry Smith 
802860a424SLois Curfman McInnes    Level: intermediate
812860a424SLois Curfman McInnes 
82052efed2SBarry Smith .keywords: matrix, add, shift
836b9ee512SLois Curfman McInnes 
846b9ee512SLois Curfman McInnes .seealso: MatDiagonalShift()
85052efed2SBarry Smith  @*/
86052efed2SBarry Smith int MatShift(Scalar *a,Mat Y)
87052efed2SBarry Smith {
88052efed2SBarry Smith   int    i,start,end,ierr;
89052efed2SBarry Smith 
903a40ed3dSBarry Smith   PetscFunctionBegin;
9177c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
9290f02eecSBarry Smith   PetscValidScalarPointer(a);
93f830108cSBarry Smith   if (Y->ops->shift) {
94f830108cSBarry Smith     ierr = (*Y->ops->shift)(a,Y);CHKERRQ(ierr);
9562d58ce1SBarry Smith   } else {
96d4bb536fSBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
97052efed2SBarry Smith     for (i=start; i<end; i++) {
98052efed2SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES);CHKERRQ(ierr);
99052efed2SBarry Smith     }
1006d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1016d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
102052efed2SBarry Smith   }
1033a40ed3dSBarry Smith   PetscFunctionReturn(0);
104052efed2SBarry Smith }
1056d84be18SBarry Smith 
1065615d1e5SSatish Balay #undef __FUNC__
107b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDiagonalShift"
1086d84be18SBarry Smith /*@
1096b9ee512SLois Curfman McInnes    MatDiagonalShift - Computes Y = Y + D, where D is a diagonal matrix
1106b9ee512SLois Curfman McInnes    that is represented as a vector.
1116d84be18SBarry Smith 
1126d84be18SBarry Smith    Input Parameters:
11398a79cdbSBarry Smith +  Y - the input matrix
11498a79cdbSBarry Smith -  D - the diagonal matrix, represented as a vector
1156d84be18SBarry Smith 
1166b9ee512SLois Curfman McInnes    Input Parameters:
1176b9ee512SLois Curfman McInnes .  Y - the shifted ouput matrix
1186d84be18SBarry Smith 
119fee21e36SBarry Smith    Collective on Mat and Vec
120fee21e36SBarry Smith 
1212860a424SLois Curfman McInnes    Level: intermediate
1222860a424SLois Curfman McInnes 
1236b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal
1246b9ee512SLois Curfman McInnes 
1256b9ee512SLois Curfman McInnes .seealso: MatShift()
1266d84be18SBarry Smith @*/
1276d84be18SBarry Smith int MatDiagonalShift(Mat Y,Vec D)
1286d84be18SBarry Smith {
1296d84be18SBarry Smith   int    i,start,end,ierr;
1306d84be18SBarry Smith 
1313a40ed3dSBarry Smith   PetscFunctionBegin;
13277c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
13390f02eecSBarry Smith   PetscValidHeaderSpecific(D,VEC_COOKIE);
134f830108cSBarry Smith   if (Y->ops->shift) {
135f830108cSBarry Smith     ierr = (*Y->ops->diagonalshift)(D,Y);CHKERRQ(ierr);
13694d884c6SBarry Smith   } else {
1376d84be18SBarry Smith     int    vstart,vend;
1386d84be18SBarry Smith     Scalar *v;
1396d84be18SBarry Smith     ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr);
1406d84be18SBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
141d4bb536fSBarry Smith     if (vstart != start || vend != end) {
142596552b5SBarry Smith       SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end);
143d4bb536fSBarry Smith     }
1446d84be18SBarry Smith 
1456d84be18SBarry Smith     ierr = VecGetArray(D,&v);CHKERRQ(ierr);
1466d84be18SBarry Smith     for (i=start; i<end; i++) {
1476d84be18SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,ADD_VALUES);CHKERRQ(ierr);
1486d84be18SBarry Smith     }
1492e8a6d31SBarry Smith     ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
1506d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1516d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1526d84be18SBarry Smith   }
1533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1546d84be18SBarry Smith }
155d4bb536fSBarry Smith 
156d4bb536fSBarry Smith #undef __FUNC__
157b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatAYPX"
158d4bb536fSBarry Smith /*@
159d4bb536fSBarry Smith    MatAYPX - Computes Y = X + a*Y.
160d4bb536fSBarry Smith 
161fee21e36SBarry Smith    Collective on Mat
162fee21e36SBarry Smith 
16398a79cdbSBarry Smith    Input Parameters:
16498a79cdbSBarry Smith +  X,Y - the matrices
16598a79cdbSBarry Smith -  a - the scalar multiplier
16698a79cdbSBarry Smith 
167e182c471SBarry Smith    Contributed by: Matthew Knepley
168d4bb536fSBarry Smith 
1692860a424SLois Curfman McInnes    Notes:
1702860a424SLois Curfman McInnes    This routine currently uses the MatAXPY() implementation.
1712860a424SLois Curfman McInnes 
1722860a424SLois Curfman McInnes    Level: intermediate
1732860a424SLois Curfman McInnes 
174d4bb536fSBarry Smith .keywords: matrix, add
175d4bb536fSBarry Smith 
1762860a424SLois Curfman McInnes .seealso: MatAXPY()
177d4bb536fSBarry Smith  @*/
178d4bb536fSBarry Smith int MatAYPX(Scalar *a,Mat X,Mat Y)
179d4bb536fSBarry Smith {
180d4bb536fSBarry Smith   Scalar one = 1.0;
181d4bb536fSBarry Smith   int    mX,mY,nX,nY,ierr;
182d4bb536fSBarry Smith 
1833a40ed3dSBarry Smith   PetscFunctionBegin;
184d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
185d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
186d4bb536fSBarry Smith   PetscValidScalarPointer(a);
187d4bb536fSBarry Smith 
188329f5518SBarry Smith   ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr);
189329f5518SBarry Smith   ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr);
190596552b5SBarry 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);
191d4bb536fSBarry Smith 
192d4bb536fSBarry Smith   ierr = MatScale(a,Y);CHKERRQ(ierr);
193d4bb536fSBarry Smith   ierr = MatAXPY(&one,X,Y);CHKERRQ(ierr);
1943a40ed3dSBarry Smith   PetscFunctionReturn(0);
195d4bb536fSBarry Smith }
196