/*$Id: axpy.c,v 1.43 2000/04/09 04:36:57 bsmith Exp bsmith $*/ #include "src/mat/matimpl.h" /*I "mat.h" I*/ #undef __FUNC__ #define __FUNC__ /**/"MatAXPY" /*@ MatAXPY - Computes Y = a*X + Y. Collective on Mat Input Parameters: + X, Y - the matrices - a - the scalar multiplier Contributed by: Matthew Knepley Notes: Since the current implementation of MatAXPY() uses MatGetRow() to access matrix data, efficiency is somewhat limited. Level: intermediate .keywords: matrix, add .seealso: MatAYPX() @*/ int MatAXPY(Scalar *a,Mat X,Mat Y) { int m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr; Scalar *val,*vals; PetscFunctionBegin; PetscValidHeaderSpecific(X,MAT_COOKIE); PetscValidHeaderSpecific(Y,MAT_COOKIE); PetscValidScalarPointer(a); MatGetSize(X,&m1,&n1); MatGetSize(Y,&m2,&n2); if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2); if (X->ops->axpy) { ierr = (*X->ops->axpy)(a,X,Y);CHKERRQ(ierr); } else { ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr); if (*a == 1.0) { for (i = start; i < end; i++) { ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); } } else { vals = (Scalar*)PetscMalloc((n1+1)*sizeof(Scalar));CHKPTRQ(vals); for (i=start; i*/"MatShift" /*@ MatShift - Computes Y = Y + a I, where a is a scalar and I is the identity matrix. Collective on Mat Input Parameters: + Y - the matrices - a - the scalar Level: intermediate .keywords: matrix, add, shift .seealso: MatDiagonalShift() @*/ int MatShift(Scalar *a,Mat Y) { int i,start,end,ierr; PetscFunctionBegin; PetscValidHeaderSpecific(Y,MAT_COOKIE); PetscValidScalarPointer(a); if (Y->ops->shift) { ierr = (*Y->ops->shift)(a,Y);CHKERRQ(ierr); } else { ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); for (i=start; i*/"MatDiagonalShift" /*@ MatDiagonalShift - Computes Y = Y + D, where D is a diagonal matrix that is represented as a vector. Input Parameters: + Y - the input matrix - D - the diagonal matrix, represented as a vector Input Parameters: . Y - the shifted ouput matrix Collective on Mat and Vec Level: intermediate .keywords: matrix, add, shift, diagonal .seealso: MatShift() @*/ int MatDiagonalShift(Mat Y,Vec D) { int i,start,end,ierr; PetscFunctionBegin; PetscValidHeaderSpecific(Y,MAT_COOKIE); PetscValidHeaderSpecific(D,VEC_COOKIE); if (Y->ops->shift) { ierr = (*Y->ops->diagonalshift)(D,Y);CHKERRQ(ierr); } else { int vstart,vend; Scalar *v; ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); if (vstart != start || vend != end) { SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end); } ierr = VecGetArray(D,&v);CHKERRQ(ierr); for (i=start; i*/"MatAYPX" /*@ MatAYPX - Computes Y = X + a*Y. Collective on Mat Input Parameters: + X,Y - the matrices - a - the scalar multiplier Contributed by: Matthew Knepley Notes: This routine currently uses the MatAXPY() implementation. Level: intermediate .keywords: matrix, add .seealso: MatAXPY() @*/ int MatAYPX(Scalar *a,Mat X,Mat Y) { Scalar one = 1.0; int mX,mY,nX,nY,ierr; PetscFunctionBegin; PetscValidHeaderSpecific(X,MAT_COOKIE); PetscValidHeaderSpecific(Y,MAT_COOKIE); PetscValidScalarPointer(a); ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr); ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr); if (mX != mY || nX != nY) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Non conforming matrices: %d %d first %d %d second",mX,mY,nX,nY); ierr = MatScale(a,Y);CHKERRQ(ierr); ierr = MatAXPY(&one,X,Y);CHKERRQ(ierr); PetscFunctionReturn(0); }