xref: /petsc/src/mat/utils/axpy.c (revision 3a40ed3dce77c081171d005ae1a6ff4bb9d13b6f)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*3a40ed3dSBarry Smith static char vcid[] = "$Id: axpy.c,v 1.28 1997/09/11 20:40:16 bsmith Exp bsmith $";
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 
126f79c3a4SBarry Smith    Input Parameters:
1306be10caSBarry Smith .  X,Y - the matrices
149cf4f1e8SLois Curfman McInnes .  a - the scalar multiplier
156f79c3a4SBarry Smith 
16e182c471SBarry Smith    Contributed by: Matthew Knepley
17d4bb536fSBarry Smith 
189cf4f1e8SLois Curfman McInnes .keywords: matrix, add
19d4bb536fSBarry Smith 
2006be10caSBarry Smith  @*/
2106be10caSBarry Smith int MatAXPY(Scalar *a,Mat X,Mat Y)
226f79c3a4SBarry Smith {
2306be10caSBarry Smith   int    m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr;
2406be10caSBarry Smith   Scalar *val,*vals;
256f79c3a4SBarry Smith 
26*3a40ed3dSBarry Smith   PetscFunctionBegin;
27d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
28d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
2990f02eecSBarry Smith   PetscValidScalarPointer(a);
3090f02eecSBarry Smith 
31d4bb536fSBarry Smith   MatGetSize(X,&m1,&n1);  MatGetSize(Y,&m2,&n2);
32e3372554SBarry Smith   if (m1 != m2 || n1 != n2) SETERRQ(1,0,"Non conforming matrix add");
331987afe7SBarry Smith 
341987afe7SBarry Smith   if (X->ops.axpy) {
351987afe7SBarry Smith     ierr = (*X->ops.axpy)(a,X,Y); CHKERRQ(ierr);
36d4bb536fSBarry Smith   } else {
3790f02eecSBarry Smith     ierr = MatGetOwnershipRange(X,&start,&end); CHKERRQ(ierr);
38d4bb536fSBarry Smith     if (*a == 1.0) {
39d4bb536fSBarry Smith       for (i = start; i < end; i++) {
40d4bb536fSBarry Smith         ierr = MatGetRow(X, i, &ncols, &row, &vals);                 CHKERRQ(ierr);
41d4bb536fSBarry Smith         ierr = MatSetValues(Y, 1, &i, ncols, row, vals, ADD_VALUES); CHKERRQ(ierr);
42d4bb536fSBarry Smith         ierr = MatRestoreRow(X, i, &ncols, &row, &vals);             CHKERRQ(ierr);
43d4bb536fSBarry Smith       }
44d4bb536fSBarry Smith     } else {
45d4bb536fSBarry Smith       vals = (Scalar *) PetscMalloc( (n1+1)*sizeof(Scalar) ); CHKPTRQ(vals);
4606be10caSBarry Smith       for ( i=start; i<end; i++ ) {
4790f02eecSBarry Smith         ierr = MatGetRow(X,i,&ncols,&row,&val); CHKERRQ(ierr);
4806be10caSBarry Smith         for ( j=0; j<ncols; j++ ) {
4906be10caSBarry Smith           vals[j] = (*a)*val[j];
506f79c3a4SBarry Smith         }
51dbb450caSBarry Smith         ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES); CHKERRQ(ierr);
5290f02eecSBarry Smith         ierr = MatRestoreRow(X,i,&ncols,&row,&val); CHKERRQ(ierr);
536f79c3a4SBarry Smith       }
540452661fSBarry Smith       PetscFree(vals);
55d4bb536fSBarry Smith     }
566d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
576d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
581987afe7SBarry Smith   }
59*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
606f79c3a4SBarry Smith }
61052efed2SBarry Smith 
625615d1e5SSatish Balay #undef __FUNC__
635615d1e5SSatish Balay #define __FUNC__ "MatShift"
64052efed2SBarry Smith /*@
656b9ee512SLois Curfman McInnes    MatShift - Computes Y =  Y + a I, where a is a scalar and I is the identity
666b9ee512SLois Curfman McInnes    matrix.
67052efed2SBarry Smith 
68052efed2SBarry Smith    Input Parameters:
69052efed2SBarry Smith .  Y - the matrices
70052efed2SBarry Smith .  a - the scalar
71052efed2SBarry Smith 
72052efed2SBarry Smith .keywords: matrix, add, shift
736b9ee512SLois Curfman McInnes 
746b9ee512SLois Curfman McInnes .seealso: MatDiagonalShift()
75052efed2SBarry Smith  @*/
76052efed2SBarry Smith int MatShift(Scalar *a,Mat Y)
77052efed2SBarry Smith {
78052efed2SBarry Smith   int    i,start,end,ierr;
79052efed2SBarry Smith 
80*3a40ed3dSBarry Smith   PetscFunctionBegin;
8177c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
8290f02eecSBarry Smith   PetscValidScalarPointer(a);
83052efed2SBarry Smith   if (Y->ops.shift) {
84052efed2SBarry Smith     ierr = (*Y->ops.shift)(a,Y); CHKERRQ(ierr);
85052efed2SBarry Smith   }
86052efed2SBarry Smith   else {
87d4bb536fSBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end); CHKERRQ(ierr);
88052efed2SBarry Smith     for ( i=start; i<end; i++ ) {
89052efed2SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES); CHKERRQ(ierr);
90052efed2SBarry Smith     }
916d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
926d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
93052efed2SBarry Smith   }
94*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
95052efed2SBarry Smith }
966d84be18SBarry Smith 
975615d1e5SSatish Balay #undef __FUNC__
985615d1e5SSatish Balay #define __FUNC__ "MatDiagonalShift"
996d84be18SBarry Smith /*@
1006b9ee512SLois Curfman McInnes    MatDiagonalShift - Computes Y = Y + D, where D is a diagonal matrix
1016b9ee512SLois Curfman McInnes    that is represented as a vector.
1026d84be18SBarry Smith 
1036d84be18SBarry Smith    Input Parameters:
1046b9ee512SLois Curfman McInnes .  Y - the input matrix
1056d84be18SBarry Smith .  D - the diagonal matrix, represented as a vector
1066d84be18SBarry Smith 
1076b9ee512SLois Curfman McInnes    Input Parameters:
1086b9ee512SLois Curfman McInnes .  Y - the shifted ouput matrix
1096d84be18SBarry Smith 
1106b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal
1116b9ee512SLois Curfman McInnes 
1126b9ee512SLois Curfman McInnes .seealso: MatShift()
1136d84be18SBarry Smith @*/
1146d84be18SBarry Smith int MatDiagonalShift(Mat Y,Vec D)
1156d84be18SBarry Smith {
1166d84be18SBarry Smith   int    i,start,end,ierr;
1176d84be18SBarry Smith 
118*3a40ed3dSBarry Smith   PetscFunctionBegin;
11977c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
12090f02eecSBarry Smith   PetscValidHeaderSpecific(D,VEC_COOKIE);
1216d84be18SBarry Smith   if (Y->ops.shift) {
1226d84be18SBarry Smith     ierr = (*Y->ops.diagonalshift)(D,Y); CHKERRQ(ierr);
1236d84be18SBarry Smith   }
1246d84be18SBarry Smith   else {
1256d84be18SBarry Smith     int    vstart,vend;
1266d84be18SBarry Smith     Scalar *v;
1276d84be18SBarry Smith     ierr = VecGetOwnershipRange(D,&vstart,&vend); CHKERRQ(ierr);
1286d84be18SBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end); CHKERRQ(ierr);
129d4bb536fSBarry Smith     if (vstart != start || vend != end) {
130d4bb536fSBarry Smith       SETERRQ(1,0,"Vector ownership range not compatible with matrix");
131d4bb536fSBarry Smith     }
1326d84be18SBarry Smith 
1336d84be18SBarry Smith     ierr = VecGetArray(D,&v); CHKERRQ(ierr);
1346d84be18SBarry Smith     for ( i=start; i<end; i++ ) {
1356d84be18SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,ADD_VALUES); CHKERRQ(ierr);
1366d84be18SBarry Smith     }
1376d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1386d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1396d84be18SBarry Smith   }
140*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
1416d84be18SBarry Smith }
142d4bb536fSBarry Smith 
143d4bb536fSBarry Smith #undef __FUNC__
144d4bb536fSBarry Smith #define __FUNC__ "MatAYPX"
145d4bb536fSBarry Smith /*@
146d4bb536fSBarry Smith    MatAYPX - Computes Y = X + a*Y.
147d4bb536fSBarry Smith 
148d4bb536fSBarry Smith    Input Parameters:
149d4bb536fSBarry Smith .  X,Y - the matrices
150d4bb536fSBarry Smith .  a - the scalar multiplier
151d4bb536fSBarry Smith 
152e182c471SBarry Smith    Contributed by: Matthew Knepley
153d4bb536fSBarry Smith 
154d4bb536fSBarry Smith .keywords: matrix, add
155d4bb536fSBarry Smith 
156d4bb536fSBarry Smith  @*/
157d4bb536fSBarry Smith int MatAYPX(Scalar *a,Mat X,Mat Y)
158d4bb536fSBarry Smith {
159d4bb536fSBarry Smith   Scalar one = 1.0;
160d4bb536fSBarry Smith   int    mX, mY,nX, nY,ierr;
161d4bb536fSBarry Smith 
162*3a40ed3dSBarry Smith   PetscFunctionBegin;
163d4bb536fSBarry Smith   PetscValidHeaderSpecific(X, MAT_COOKIE);
164d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y, MAT_COOKIE);
165d4bb536fSBarry Smith   PetscValidScalarPointer(a);
166d4bb536fSBarry Smith 
167d4bb536fSBarry Smith   MatGetSize(X, &mX, &nX);
168d4bb536fSBarry Smith   MatGetSize(X, &mY, &nY);
169d4bb536fSBarry Smith   if (mX != mY || nX != nY) SETERRQ(1,0,"Non conforming matrices");
170d4bb536fSBarry Smith 
171d4bb536fSBarry Smith   ierr = MatScale(a, Y);      CHKERRQ(ierr);
172d4bb536fSBarry Smith   ierr = MatAXPY(&one, X, Y); CHKERRQ(ierr);
173*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
174d4bb536fSBarry Smith }
175