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