1 #ifdef PETSC_RCS_HEADER 2 static char vcid[] = "$Id: axpy.c,v 1.39 1999/05/04 20:33:40 balay Exp balay $"; 3 #endif 4 5 #include "src/mat/matimpl.h" /*I "mat.h" I*/ 6 7 #undef __FUNC__ 8 #define __FUNC__ "MatAXPY" 9 /*@ 10 MatAXPY - Computes Y = a*X + Y. 11 12 Collective on Mat 13 14 Input Parameters: 15 + X, Y - the matrices 16 - a - the scalar multiplier 17 18 Contributed by: Matthew Knepley 19 20 Notes: 21 Since the current implementation of MatAXPY() uses MatGetRow() to access 22 matrix data, efficiency is somewhat limited. 23 24 Level: intermediate 25 26 .keywords: matrix, add 27 28 .seealso: MatAYPX() 29 @*/ 30 int MatAXPY(Scalar *a,Mat X,Mat Y) 31 { 32 int m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr; 33 Scalar *val,*vals; 34 35 PetscFunctionBegin; 36 PetscValidHeaderSpecific(X,MAT_COOKIE); 37 PetscValidHeaderSpecific(Y,MAT_COOKIE); 38 PetscValidScalarPointer(a); 39 40 MatGetSize(X,&m1,&n1); MatGetSize(Y,&m2,&n2); 41 if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2); 42 43 if (X->ops->axpy) { 44 ierr = (*X->ops->axpy)(a,X,Y);CHKERRQ(ierr); 45 } else { 46 ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr); 47 if (*a == 1.0) { 48 for (i = start; i < end; i++) { 49 ierr = MatGetRow(X, i, &ncols, &row, &vals);CHKERRQ(ierr); 50 ierr = MatSetValues(Y, 1, &i, ncols, row, vals, ADD_VALUES);CHKERRQ(ierr); 51 ierr = MatRestoreRow(X, i, &ncols, &row, &vals);CHKERRQ(ierr); 52 } 53 } else { 54 vals = (Scalar *) PetscMalloc( (n1+1)*sizeof(Scalar) );CHKPTRQ(vals); 55 for ( i=start; i<end; i++ ) { 56 ierr = MatGetRow(X,i,&ncols,&row,&val);CHKERRQ(ierr); 57 for ( j=0; j<ncols; j++ ) { 58 vals[j] = (*a)*val[j]; 59 } 60 ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); 61 ierr = MatRestoreRow(X,i,&ncols,&row,&val);CHKERRQ(ierr); 62 } 63 ierr = PetscFree(vals);CHKERRQ(ierr); 64 } 65 ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 66 ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 67 } 68 PetscFunctionReturn(0); 69 } 70 71 #undef __FUNC__ 72 #define __FUNC__ "MatShift" 73 /*@ 74 MatShift - Computes Y = Y + a I, where a is a scalar and I is the identity matrix. 75 76 Collective on Mat 77 78 Input Parameters: 79 + Y - the matrices 80 - a - the scalar 81 82 Level: intermediate 83 84 .keywords: matrix, add, shift 85 86 .seealso: MatDiagonalShift() 87 @*/ 88 int MatShift(Scalar *a,Mat Y) 89 { 90 int i,start,end,ierr; 91 92 PetscFunctionBegin; 93 PetscValidHeaderSpecific(Y,MAT_COOKIE); 94 PetscValidScalarPointer(a); 95 if (Y->ops->shift) { 96 ierr = (*Y->ops->shift)(a,Y);CHKERRQ(ierr); 97 } else { 98 ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 99 for ( i=start; i<end; i++ ) { 100 ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES);CHKERRQ(ierr); 101 } 102 ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 103 ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 104 } 105 PetscFunctionReturn(0); 106 } 107 108 #undef __FUNC__ 109 #define __FUNC__ "MatDiagonalShift" 110 /*@ 111 MatDiagonalShift - Computes Y = Y + D, where D is a diagonal matrix 112 that is represented as a vector. 113 114 Input Parameters: 115 + Y - the input matrix 116 - D - the diagonal matrix, represented as a vector 117 118 Input Parameters: 119 . Y - the shifted ouput matrix 120 121 Collective on Mat and Vec 122 123 Level: intermediate 124 125 .keywords: matrix, add, shift, diagonal 126 127 .seealso: MatShift() 128 @*/ 129 int MatDiagonalShift(Mat Y,Vec D) 130 { 131 int i,start,end,ierr; 132 133 PetscFunctionBegin; 134 PetscValidHeaderSpecific(Y,MAT_COOKIE); 135 PetscValidHeaderSpecific(D,VEC_COOKIE); 136 if (Y->ops->shift) { 137 ierr = (*Y->ops->diagonalshift)(D,Y);CHKERRQ(ierr); 138 } else { 139 int vstart,vend; 140 Scalar *v; 141 ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr); 142 ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 143 if (vstart != start || vend != end) { 144 SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end); 145 } 146 147 ierr = VecGetArray(D,&v);CHKERRQ(ierr); 148 for ( i=start; i<end; i++ ) { 149 ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,ADD_VALUES);CHKERRQ(ierr); 150 } 151 ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 152 ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 153 ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 154 } 155 PetscFunctionReturn(0); 156 } 157 158 #undef __FUNC__ 159 #define __FUNC__ "MatAYPX" 160 /*@ 161 MatAYPX - Computes Y = X + a*Y. 162 163 Collective on Mat 164 165 Input Parameters: 166 + X,Y - the matrices 167 - a - the scalar multiplier 168 169 Contributed by: Matthew Knepley 170 171 Notes: 172 This routine currently uses the MatAXPY() implementation. 173 174 Level: intermediate 175 176 .keywords: matrix, add 177 178 .seealso: MatAXPY() 179 @*/ 180 int MatAYPX(Scalar *a,Mat X,Mat Y) 181 { 182 Scalar one = 1.0; 183 int mX, mY,nX, nY,ierr; 184 185 PetscFunctionBegin; 186 PetscValidHeaderSpecific(X, MAT_COOKIE); 187 PetscValidHeaderSpecific(Y, MAT_COOKIE); 188 PetscValidScalarPointer(a); 189 190 MatGetSize(X, &mX, &nX); 191 MatGetSize(X, &mY, &nY); 192 if (mX != mY || nX != nY) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Non conforming matrices: %d %d first %d %d second",mX,mY,nX,nY); 193 194 ierr = MatScale(a, Y);CHKERRQ(ierr); 195 ierr = MatAXPY(&one, X, Y);CHKERRQ(ierr); 196 PetscFunctionReturn(0); 197 } 198