Actual source code: axpy.c

  1: /*$Id: axpy.c,v 1.54 2001/08/06 21:16:10 bsmith Exp bsmith $*/

 3:  #include src/mat/matimpl.h

  5: /*@
  6:    MatAXPY - Computes Y = a*X + Y.

  8:    Collective on Mat

 10:    Input Parameters:
 11: +  a - the scalar multiplier
 12: .  X - the first matrix
 13: .  Y - the second matrix
 14: -  str - either SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

 16:    Contributed by: Matthew Knepley

 18:    Notes:
 19:      Will only be efficient if one has the SAME_NONZERO_PATTERN

 21:    Level: intermediate

 23: .keywords: matrix, add

 25: .seealso: MatAYPX()
 26:  @*/
 27: int MatAXPY(PetscScalar *a,Mat X,Mat Y,MatStructure str)
 28: {
 29:   int         m1,m2,n1,n2,ierr;


 36:   MatGetSize(X,&m1,&n1);
 37:   MatGetSize(Y,&m2,&n2);
 38:   if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2);

 40:   if (X->ops->axpy) {
 41:     (*X->ops->axpy)(a,X,Y,str);
 42:   } else {
 43:     MatAXPY_Basic(a,X,Y,str);
 44:   }
 45:   return(0);
 46: }


 49: int MatAXPY_Basic(PetscScalar *a,Mat X,Mat Y,MatStructure str)
 50: {
 51:   int         i,*row,start,end,j,ncols,ierr,m,n;
 52:   PetscScalar *val,*vals;

 55:   MatGetSize(X,&m,&n);
 56:   MatGetOwnershipRange(X,&start,&end);
 57:   if (*a == 1.0) {
 58:     for (i = start; i < end; i++) {
 59:       MatGetRow(X,i,&ncols,&row,&vals);
 60:       MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);
 61:       MatRestoreRow(X,i,&ncols,&row,&vals);
 62:     }
 63:   } else {
 64:     PetscMalloc((n+1)*sizeof(PetscScalar),&vals);
 65:     for (i=start; i<end; i++) {
 66:       MatGetRow(X,i,&ncols,&row,&val);
 67:       for (j=0; j<ncols; j++) {
 68:         vals[j] = (*a)*val[j];
 69:       }
 70:       MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);
 71:       MatRestoreRow(X,i,&ncols,&row,&val);
 72:     }
 73:     PetscFree(vals);
 74:   }
 75:   MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);
 76:   MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);
 77:   return(0);
 78: }

 80: /*@
 81:    MatShift - Computes Y =  Y + a I, where a is a PetscScalar and I is the identity matrix.

 83:    Collective on Mat

 85:    Input Parameters:
 86: +  Y - the matrices
 87: -  a - the PetscScalar 

 89:    Level: intermediate

 91: .keywords: matrix, add, shift

 93: .seealso: MatDiagonalSet()
 94:  @*/
 95: int MatShift(PetscScalar *a,Mat Y)
 96: {
 97:   int    i,start,end,ierr;

102:   if (Y->ops->shift) {
103:     (*Y->ops->shift)(a,Y);
104:   } else {
105:     MatGetOwnershipRange(Y,&start,&end);
106:     for (i=start; i<end; i++) {
107:       MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES);
108:     }
109:     MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);
110:     MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);
111:   }
112:   return(0);
113: }

115: /*@
116:    MatDiagonalSet - Computes Y = Y + D, where D is a diagonal matrix
117:    that is represented as a vector. Or Y[i,i] = D[i] if InsertMode is
118:    INSERT_VALUES.

120:    Input Parameters:
121: +  Y - the input matrix
122: .  D - the diagonal matrix, represented as a vector
123: -  i - INSERT_VALUES or ADD_VALUES

125:    Collective on Mat and Vec

127:    Level: intermediate

129: .keywords: matrix, add, shift, diagonal

131: .seealso: MatShift()
132: @*/
133: int MatDiagonalSet(Mat Y,Vec D,InsertMode is)
134: {
135:   int    i,start,end,ierr;

140:   if (Y->ops->diagonalset) {
141:     (*Y->ops->diagonalset)(Y,D,is);
142:   } else {
143:     int    vstart,vend;
144:     PetscScalar *v;
145:     VecGetOwnershipRange(D,&vstart,&vend);
146:     MatGetOwnershipRange(Y,&start,&end);
147:     if (vstart != start || vend != end) {
148:       SETERRQ4(PETSC_ERR_ARG_SIZ,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end);
149:     }
150:     VecGetArray(D,&v);
151:     for (i=start; i<end; i++) {
152:       MatSetValues(Y,1,&i,1,&i,v+i-start,is);
153:     }
154:     VecRestoreArray(D,&v);
155:     MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);
156:     MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);
157:   }
158:   return(0);
159: }

161: /*@
162:    MatAYPX - Computes Y = X + a*Y.

164:    Collective on Mat

166:    Input Parameters:
167: +  X,Y - the matrices
168: -  a - the PetscScalar multiplier

170:    Contributed by: Matthew Knepley

172:    Notes:
173:    This routine currently uses the MatAXPY() implementation.

175:    This is slow, if you need it fast send email to petsc-maint@mcs.anl.gov

177:    Level: intermediate

179: .keywords: matrix, add

181: .seealso: MatAXPY()
182:  @*/
183: int MatAYPX(PetscScalar *a,Mat X,Mat Y)
184: {
185:   PetscScalar one = 1.0;
186:   int         mX,mY,nX,nY,ierr;


193:   MatGetSize(X,&mX,&nX);
194:   MatGetSize(X,&mY,&nY);
195:   if (mX != mY || nX != nY) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrices: %d %d first %d %d second",mX,mY,nX,nY);

197:   MatScale(a,Y);
198:   MatAXPY(&one,X,Y,DIFFERENT_NONZERO_PATTERN);
199:   return(0);
200: }

202: /*@
203:     MatComputeExplicitOperator - Computes the explicit matrix

205:     Collective on Mat

207:     Input Parameter:
208: .   inmat - the matrix

210:     Output Parameter:
211: .   mat - the explict preconditioned operator

213:     Notes:
214:     This computation is done by applying the operators to columns of the 
215:     identity matrix.

217:     Currently, this routine uses a dense matrix format when 1 processor
218:     is used and a sparse format otherwise.  This routine is costly in general,
219:     and is recommended for use only with relatively small systems.

221:     Level: advanced
222:    
223: .keywords: Mat, compute, explicit, operator

225: @*/
226: int MatComputeExplicitOperator(Mat inmat,Mat *mat)
227: {
228:   Vec      in,out;
229:   int      ierr,i,M,m,size,*rows,start,end;
230:   MPI_Comm comm;
231:   PetscScalar   *array,zero = 0.0,one = 1.0;


237:   comm = inmat->comm;
238:   MPI_Comm_size(comm,&size);

240:   MatGetLocalSize(inmat,&m,0);
241:   MatGetSize(inmat,&M,0);
242:   VecCreateMPI(comm,m,M,&in);
243:   VecDuplicate(in,&out);
244:   VecGetOwnershipRange(in,&start,&end);
245:   PetscMalloc((m+1)*sizeof(int),&rows);
246:   for (i=0; i<m; i++) {rows[i] = start + i;}

248:   if (size == 1) {
249:     MatCreateSeqDense(comm,M,M,PETSC_NULL,mat);
250:   } else {
251:     MatCreateMPIAIJ(comm,m,m,M,M,0,0,0,0,mat);
252:   }

254:   for (i=0; i<M; i++) {

256:     VecSet(&zero,in);
257:     VecSetValues(in,1,&i,&one,INSERT_VALUES);
258:     VecAssemblyBegin(in);
259:     VecAssemblyEnd(in);

261:     MatMult(inmat,in,out);
262: 
263:     VecGetArray(out,&array);
264:     MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);
265:     VecRestoreArray(out,&array);

267:   }
268:   PetscFree(rows);
269:   VecDestroy(out);
270:   VecDestroy(in);
271:   MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);
272:   MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);
273:   return(0);
274: }