xref: /petsc/src/mat/utils/axpy.c (revision d4bb536f0e426e9a0292bbfd5743770a9b03f0d5)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*d4bb536fSBarry Smith static char vcid[] = "$Id: axpy.c,v 1.26 1997/07/09 20:56:43 balay 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 
16*d4bb536fSBarry Smith    Contributed by: Mathew Knepley
17*d4bb536fSBarry Smith 
189cf4f1e8SLois Curfman McInnes .keywords: matrix, add
19*d4bb536fSBarry 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*d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
27*d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
2890f02eecSBarry Smith   PetscValidScalarPointer(a);
2990f02eecSBarry Smith 
30*d4bb536fSBarry Smith   MatGetSize(X,&m1,&n1);  MatGetSize(Y,&m2,&n2);
31e3372554SBarry Smith   if (m1 != m2 || n1 != n2) SETERRQ(1,0,"Non conforming matrix add");
321987afe7SBarry Smith 
331987afe7SBarry Smith   if (X->ops.axpy) {
341987afe7SBarry Smith     ierr = (*X->ops.axpy)(a,X,Y); CHKERRQ(ierr);
35*d4bb536fSBarry Smith   } else {
3690f02eecSBarry Smith     ierr = MatGetOwnershipRange(X,&start,&end); CHKERRQ(ierr);
37*d4bb536fSBarry Smith     if (*a == 1.0) {
38*d4bb536fSBarry Smith       for (i = start; i < end; i++) {
39*d4bb536fSBarry Smith         ierr = MatGetRow(X, i, &ncols, &row, &vals);                 CHKERRQ(ierr);
40*d4bb536fSBarry Smith         ierr = MatSetValues(Y, 1, &i, ncols, row, vals, ADD_VALUES); CHKERRQ(ierr);
41*d4bb536fSBarry Smith         ierr = MatRestoreRow(X, i, &ncols, &row, &vals);             CHKERRQ(ierr);
42*d4bb536fSBarry Smith       }
43*d4bb536fSBarry Smith     } else {
44*d4bb536fSBarry Smith       vals = (Scalar *) PetscMalloc( (n1+1)*sizeof(Scalar) ); CHKPTRQ(vals);
4506be10caSBarry Smith       for ( i=start; i<end; i++ ) {
4690f02eecSBarry Smith         ierr = MatGetRow(X,i,&ncols,&row,&val); CHKERRQ(ierr);
4706be10caSBarry Smith         for ( j=0; j<ncols; j++ ) {
4806be10caSBarry Smith           vals[j] = (*a)*val[j];
496f79c3a4SBarry Smith         }
50dbb450caSBarry Smith         ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES); CHKERRQ(ierr);
5190f02eecSBarry Smith         ierr = MatRestoreRow(X,i,&ncols,&row,&val); CHKERRQ(ierr);
526f79c3a4SBarry Smith       }
530452661fSBarry Smith       PetscFree(vals);
54*d4bb536fSBarry Smith     }
556d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
566d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
571987afe7SBarry Smith   }
586f79c3a4SBarry Smith   return 0;
596f79c3a4SBarry Smith }
60052efed2SBarry Smith 
615615d1e5SSatish Balay #undef __FUNC__
625615d1e5SSatish Balay #define __FUNC__ "MatShift"
63052efed2SBarry Smith /*@
646b9ee512SLois Curfman McInnes    MatShift - Computes Y =  Y + a I, where a is a scalar and I is the identity
656b9ee512SLois Curfman McInnes    matrix.
66052efed2SBarry Smith 
67052efed2SBarry Smith    Input Parameters:
68052efed2SBarry Smith .  Y - the matrices
69052efed2SBarry Smith .  a - the scalar
70052efed2SBarry Smith 
71052efed2SBarry Smith .keywords: matrix, add, shift
726b9ee512SLois Curfman McInnes 
736b9ee512SLois Curfman McInnes .seealso: MatDiagonalShift()
74052efed2SBarry Smith  @*/
75052efed2SBarry Smith int MatShift(Scalar *a,Mat Y)
76052efed2SBarry Smith {
77052efed2SBarry Smith   int    i,start,end,ierr;
78052efed2SBarry Smith 
7977c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
8090f02eecSBarry Smith   PetscValidScalarPointer(a);
81052efed2SBarry Smith   if (Y->ops.shift) {
82052efed2SBarry Smith     ierr = (*Y->ops.shift)(a,Y); CHKERRQ(ierr);
83052efed2SBarry Smith   }
84052efed2SBarry Smith   else {
85*d4bb536fSBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end); CHKERRQ(ierr);
86052efed2SBarry Smith     for ( i=start; i<end; i++ ) {
87052efed2SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES); CHKERRQ(ierr);
88052efed2SBarry Smith     }
896d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
906d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
91052efed2SBarry Smith   }
92052efed2SBarry Smith   return 0;
93052efed2SBarry Smith }
946d84be18SBarry Smith 
955615d1e5SSatish Balay #undef __FUNC__
965615d1e5SSatish Balay #define __FUNC__ "MatDiagonalShift"
976d84be18SBarry Smith /*@
986b9ee512SLois Curfman McInnes    MatDiagonalShift - Computes Y = Y + D, where D is a diagonal matrix
996b9ee512SLois Curfman McInnes    that is represented as a vector.
1006d84be18SBarry Smith 
1016d84be18SBarry Smith    Input Parameters:
1026b9ee512SLois Curfman McInnes .  Y - the input matrix
1036d84be18SBarry Smith .  D - the diagonal matrix, represented as a vector
1046d84be18SBarry Smith 
1056b9ee512SLois Curfman McInnes    Input Parameters:
1066b9ee512SLois Curfman McInnes .  Y - the shifted ouput matrix
1076d84be18SBarry Smith 
1086b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal
1096b9ee512SLois Curfman McInnes 
1106b9ee512SLois Curfman McInnes .seealso: MatShift()
1116d84be18SBarry Smith @*/
1126d84be18SBarry Smith int MatDiagonalShift(Mat Y,Vec D)
1136d84be18SBarry Smith {
1146d84be18SBarry Smith   int    i,start,end,ierr;
1156d84be18SBarry Smith 
11677c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
11790f02eecSBarry Smith   PetscValidHeaderSpecific(D,VEC_COOKIE);
1186d84be18SBarry Smith   if (Y->ops.shift) {
1196d84be18SBarry Smith     ierr = (*Y->ops.diagonalshift)(D,Y); CHKERRQ(ierr);
1206d84be18SBarry Smith   }
1216d84be18SBarry Smith   else {
1226d84be18SBarry Smith     int    vstart,vend;
1236d84be18SBarry Smith     Scalar *v;
1246d84be18SBarry Smith     ierr = VecGetOwnershipRange(D,&vstart,&vend); CHKERRQ(ierr);
1256d84be18SBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end); CHKERRQ(ierr);
126*d4bb536fSBarry Smith     if (vstart != start || vend != end) {
127*d4bb536fSBarry Smith       SETERRQ(1,0,"Vector ownership range not compatible with matrix");
128*d4bb536fSBarry Smith     }
1296d84be18SBarry Smith 
1306d84be18SBarry Smith     ierr = VecGetArray(D,&v); CHKERRQ(ierr);
1316d84be18SBarry Smith     for ( i=start; i<end; i++ ) {
1326d84be18SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,ADD_VALUES); CHKERRQ(ierr);
1336d84be18SBarry Smith     }
1346d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1356d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1366d84be18SBarry Smith   }
1376d84be18SBarry Smith   return 0;
1386d84be18SBarry Smith }
139*d4bb536fSBarry Smith 
140*d4bb536fSBarry Smith #undef __FUNC__
141*d4bb536fSBarry Smith #define __FUNC__ "MatAYPX"
142*d4bb536fSBarry Smith /*@
143*d4bb536fSBarry Smith    MatAYPX - Computes Y = X + a*Y.
144*d4bb536fSBarry Smith 
145*d4bb536fSBarry Smith    Input Parameters:
146*d4bb536fSBarry Smith .  X,Y - the matrices
147*d4bb536fSBarry Smith .  a - the scalar multiplier
148*d4bb536fSBarry Smith 
149*d4bb536fSBarry Smith    Contributed by: Mathew Knepley
150*d4bb536fSBarry Smith 
151*d4bb536fSBarry Smith .keywords: matrix, add
152*d4bb536fSBarry Smith 
153*d4bb536fSBarry Smith  @*/
154*d4bb536fSBarry Smith int MatAYPX(Scalar *a,Mat X,Mat Y)
155*d4bb536fSBarry Smith {
156*d4bb536fSBarry Smith   Scalar one = 1.0;
157*d4bb536fSBarry Smith   int    mX, mY,nX, nY,ierr;
158*d4bb536fSBarry Smith 
159*d4bb536fSBarry Smith   PetscValidHeaderSpecific(X, MAT_COOKIE);
160*d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y, MAT_COOKIE);
161*d4bb536fSBarry Smith   PetscValidScalarPointer(a);
162*d4bb536fSBarry Smith 
163*d4bb536fSBarry Smith   MatGetSize(X, &mX, &nX);
164*d4bb536fSBarry Smith   MatGetSize(X, &mY, &nY);
165*d4bb536fSBarry Smith   if (mX != mY || nX != nY) SETERRQ(1,0,"Non conforming matrices");
166*d4bb536fSBarry Smith 
167*d4bb536fSBarry Smith   ierr = MatScale(a, Y);      CHKERRQ(ierr);
168*d4bb536fSBarry Smith   ierr = MatAXPY(&one, X, Y); CHKERRQ(ierr);
169*d4bb536fSBarry Smith   return(0);
170*d4bb536fSBarry Smith }
171