xref: /petsc/src/mat/utils/axpy.c (revision 90f02eec332fcca4c33b4e7b21cabed76bf0614e)
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