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