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