1 #ifndef lint 2 static char vcid[] = "$Id: axpy.c,v 1.19 1996/08/08 14:44:19 bsmith Exp bsmith $"; 3 #endif 4 5 #include "src/mat/matimpl.h" /*I "mat.h" I*/ 6 7 /*@ 8 MatAXPY - Computes Y = a*X + Y. 9 10 Input Parameters: 11 . X,Y - the matrices 12 . a - the scalar multiplier 13 14 .keywords: matrix, add 15 @*/ 16 int MatAXPY(Scalar *a,Mat X,Mat Y) 17 { 18 int m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr; 19 Scalar *val,*vals; 20 21 PetscValidHeaderSpecific(X,MAT_COOKIE); PetscValidHeaderSpecific(Y,MAT_COOKIE); 22 PetscValidScalarPointer(a); 23 24 MatGetSize(X,&m1,&n1); MatGetSize(X,&m2,&n2); 25 if (m1 != m2 || n1 != n2) SETERRQ(1,"MatAXPY:Non conforming matrix add"); 26 27 if (X->ops.axpy) { 28 ierr = (*X->ops.axpy)(a,X,Y); CHKERRQ(ierr); 29 } 30 else { 31 vals = (Scalar *) PetscMalloc( n1*sizeof(Scalar) ); CHKPTRQ(vals); 32 ierr = MatGetOwnershipRange(X,&start,&end); CHKERRQ(ierr); 33 for ( i=start; i<end; i++ ) { 34 ierr = MatGetRow(X,i,&ncols,&row,&val); CHKERRQ(ierr); 35 for ( j=0; j<ncols; j++ ) { 36 vals[j] = (*a)*val[j]; 37 } 38 ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES); CHKERRQ(ierr); 39 ierr = MatRestoreRow(X,i,&ncols,&row,&val); CHKERRQ(ierr); 40 } 41 PetscFree(vals); 42 ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 43 ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 44 } 45 return 0; 46 } 47 48 /*@ 49 MatShift - Computes Y = Y + a I, where a is a scalar and I is the identity 50 matrix. 51 52 Input Parameters: 53 . Y - the matrices 54 . a - the scalar 55 56 .keywords: matrix, add, shift 57 58 .seealso: MatDiagonalShift() 59 @*/ 60 int MatShift(Scalar *a,Mat Y) 61 { 62 int i,start,end,ierr; 63 64 PetscValidHeaderSpecific(Y,MAT_COOKIE); 65 PetscValidScalarPointer(a); 66 if (Y->ops.shift) { 67 ierr = (*Y->ops.shift)(a,Y); CHKERRQ(ierr); 68 } 69 else { 70 MatGetOwnershipRange(Y,&start,&end); 71 for ( i=start; i<end; i++ ) { 72 ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES); CHKERRQ(ierr); 73 } 74 ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 75 ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 76 } 77 return 0; 78 } 79 80 /*@ 81 MatDiagonalShift - Computes Y = Y + D, where D is a diagonal matrix 82 that is represented as a vector. 83 84 Input Parameters: 85 . Y - the input matrix 86 . D - the diagonal matrix, represented as a vector 87 88 Input Parameters: 89 . Y - the shifted ouput matrix 90 91 .keywords: matrix, add, shift, diagonal 92 93 .seealso: MatShift() 94 @*/ 95 int MatDiagonalShift(Mat Y,Vec D) 96 { 97 int i,start,end,ierr; 98 99 PetscValidHeaderSpecific(Y,MAT_COOKIE); 100 PetscValidHeaderSpecific(D,VEC_COOKIE); 101 if (Y->ops.shift) { 102 ierr = (*Y->ops.diagonalshift)(D,Y); CHKERRQ(ierr); 103 } 104 else { 105 int vstart,vend; 106 Scalar *v; 107 ierr = VecGetOwnershipRange(D,&vstart,&vend); CHKERRQ(ierr); 108 ierr = MatGetOwnershipRange(Y,&start,&end); CHKERRQ(ierr); 109 if (vstart != start || vend != end) 110 SETERRQ(1,"MatDiagonalShift:Vector shift not compatible with matrix"); 111 112 ierr = VecGetArray(D,&v); CHKERRQ(ierr); 113 for ( i=start; i<end; i++ ) { 114 ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,ADD_VALUES); CHKERRQ(ierr); 115 } 116 ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 117 ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 118 } 119 return 0; 120 } 121