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