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: #undef __FUNCT__  
  7: /*@
  8:    MatAXPY - Computes Y = a*X + Y.

 10:    Collective on Mat

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

 18:    Contributed by: Matthew Knepley

 20:    Notes:
 21:      Will only be efficient if one has the SAME_NONZERO_PATTERN

 23:    Level: intermediate

 25: .keywords: matrix, add

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


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

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


 51: #undef __FUNCT__  
 53: int MatAXPY_Basic(PetscScalar *a,Mat X,Mat Y,MatStructure str)
 54: {
 55:   int         i,*row,start,end,j,ncols,ierr,m,n;
 56:   PetscScalar *val,*vals;

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

 84: #undef __FUNCT__  
 86: /*@
 87:    MatShift - Computes Y =  Y + a I, where a is a PetscScalar and I is the identity matrix.

 89:    Collective on Mat

 91:    Input Parameters:
 92: +  Y - the matrices
 93: -  a - the PetscScalar 

 95:    Level: intermediate

 97: .keywords: matrix, add, shift

 99: .seealso: MatDiagonalSet()
100:  @*/
101: int MatShift(PetscScalar *a,Mat Y)
102: {
103:   int    i,start,end,ierr;

108:   if (Y->ops->shift) {
109:     (*Y->ops->shift)(a,Y);
110:   } else {
111:     MatGetOwnershipRange(Y,&start,&end);
112:     for (i=start; i<end; i++) {
113:       MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES);
114:     }
115:     MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);
116:     MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);
117:   }
118:   return(0);
119: }

121: #undef __FUNCT__  
123: /*@
124:    MatDiagonalSet - Computes Y = Y + D, where D is a diagonal matrix
125:    that is represented as a vector. Or Y[i,i] = D[i] if InsertMode is
126:    INSERT_VALUES.

128:    Input Parameters:
129: +  Y - the input matrix
130: .  D - the diagonal matrix, represented as a vector
131: -  i - INSERT_VALUES or ADD_VALUES

133:    Collective on Mat and Vec

135:    Level: intermediate

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

139: .seealso: MatShift()
140: @*/
141: int MatDiagonalSet(Mat Y,Vec D,InsertMode is)
142: {
143:   int    i,start,end,ierr;

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

169: #undef __FUNCT__  
171: /*@
172:    MatAYPX - Computes Y = X + a*Y.

174:    Collective on Mat

176:    Input Parameters:
177: +  X,Y - the matrices
178: -  a - the PetscScalar multiplier

180:    Contributed by: Matthew Knepley

182:    Notes:
183:    This routine currently uses the MatAXPY() implementation.

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

187:    Level: intermediate

189: .keywords: matrix, add

191: .seealso: MatAXPY()
192:  @*/
193: int MatAYPX(PetscScalar *a,Mat X,Mat Y)
194: {
195:   PetscScalar one = 1.0;
196:   int         mX,mY,nX,nY,ierr;


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

207:   MatScale(a,Y);
208:   MatAXPY(&one,X,Y,DIFFERENT_NONZERO_PATTERN);
209:   return(0);
210: }

212: #undef __FUNCT__  
214: /*@
215:     MatComputeExplicitOperator - Computes the explicit matrix

217:     Collective on Mat

219:     Input Parameter:
220: .   inmat - the matrix

222:     Output Parameter:
223: .   mat - the explict preconditioned operator

225:     Notes:
226:     This computation is done by applying the operators to columns of the 
227:     identity matrix.

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

233:     Level: advanced
234:    
235: .keywords: Mat, compute, explicit, operator

237: @*/
238: int MatComputeExplicitOperator(Mat inmat,Mat *mat)
239: {
240:   Vec      in,out;
241:   int      ierr,i,M,m,size,*rows,start,end;
242:   MPI_Comm comm;
243:   PetscScalar   *array,zero = 0.0,one = 1.0;


249:   comm = inmat->comm;
250:   MPI_Comm_size(comm,&size);

252:   MatGetLocalSize(inmat,&m,0);
253:   MatGetSize(inmat,&M,0);
254:   VecCreateMPI(comm,m,M,&in);
255:   VecDuplicate(in,&out);
256:   VecGetOwnershipRange(in,&start,&end);
257:   PetscMalloc((m+1)*sizeof(int),&rows);
258:   for (i=0; i<m; i++) {rows[i] = start + i;}

260:   if (size == 1) {
261:     MatCreateSeqDense(comm,M,M,PETSC_NULL,mat);
262:   } else {
263:     MatCreateMPIAIJ(comm,m,m,M,M,0,0,0,0,mat);
264:   }

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

268:     VecSet(&zero,in);
269:     VecSetValues(in,1,&i,&one,INSERT_VALUES);
270:     VecAssemblyBegin(in);
271:     VecAssemblyEnd(in);

273:     MatMult(inmat,in,out);
274: 
275:     VecGetArray(out,&array);
276:     MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);
277:     VecRestoreArray(out,&array);

279:   }
280:   PetscFree(rows);
281:   VecDestroy(out);
282:   VecDestroy(in);
283:   MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);
284:   MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);
285:   return(0);
286: }