xref: /petsc/src/mat/impls/dense/seq/dense.c (revision d65003e9c0983ba191c94bf6b6984ff0152fc0d6)
1cb512458SBarry Smith #ifndef lint
2*d65003e9SLois Curfman McInnes static char vcid[] = "$Id: dense.c,v 1.22 1995/04/16 16:09:24 curfman Exp curfman $";
3cb512458SBarry Smith #endif
4289bc588SBarry Smith 
5289bc588SBarry Smith /*
6289bc588SBarry Smith     Standard Fortran style matrices
7289bc588SBarry Smith */
8289bc588SBarry Smith #include "ptscimpl.h"
9289bc588SBarry Smith #include "plapack.h"
10289bc588SBarry Smith #include "matimpl.h"
11289bc588SBarry Smith #include "math.h"
12289bc588SBarry Smith #include "vec/vecimpl.h"
13289bc588SBarry Smith 
14289bc588SBarry Smith typedef struct {
15289bc588SBarry Smith   Scalar *v;
16289bc588SBarry Smith   int    roworiented;
17289bc588SBarry Smith   int    m,n,pad;
18289bc588SBarry Smith   int    *pivots;   /* pivots in LU factorization */
1944a69424SLois Curfman McInnes } Mat_Dense;
20289bc588SBarry Smith 
21289bc588SBarry Smith 
22fa9ec3f1SLois Curfman McInnes static int MatGetInfo_Dense(Mat matin,int flag,int *nz,int *nzalloc,int *mem)
23289bc588SBarry Smith {
2444a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
25289bc588SBarry Smith   int    i,N = mat->m*mat->n,count = 0;
26289bc588SBarry Smith   Scalar *v = mat->v;
27289bc588SBarry Smith   for ( i=0; i<N; i++ ) {if (*v != 0.0) count++; v++;}
28fa9ec3f1SLois Curfman McInnes   *nz = count; *nzalloc = N; *mem = N*sizeof(Scalar);
29fa9ec3f1SLois Curfman McInnes   return 0;
30289bc588SBarry Smith }
31289bc588SBarry Smith 
32289bc588SBarry Smith /* ---------------------------------------------------------------*/
33289bc588SBarry Smith /* COMMENT: I have chosen to hide column permutation in the pivots,
34289bc588SBarry Smith    rather than put it in the Mat->col slot.*/
3544a69424SLois Curfman McInnes static int MatLUFactor_Dense(Mat matin,IS row,IS col)
36289bc588SBarry Smith {
3744a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
386abc6512SBarry Smith   int    info;
39289bc588SBarry Smith   if (!mat->pivots) {
40289bc588SBarry Smith     mat->pivots = (int *) MALLOC( mat->m*sizeof(int) );
41289bc588SBarry Smith     CHKPTR(mat->pivots);
42289bc588SBarry Smith   }
43289bc588SBarry Smith   LAgetrf_(&mat->m,&mat->n,mat->v,&mat->m,mat->pivots,&info);
44289bc588SBarry Smith   if (info) SETERR(1,"Bad LU factorization");
45289bc588SBarry Smith   matin->factor = FACTOR_LU;
46289bc588SBarry Smith   return 0;
47289bc588SBarry Smith }
4844a69424SLois Curfman McInnes static int MatLUFactorSymbolic_Dense(Mat matin,IS row,IS col,Mat *fact)
49289bc588SBarry Smith {
50289bc588SBarry Smith   int ierr;
516abc6512SBarry Smith   if ((ierr = MatCopy(matin,fact))) SETERR(ierr,0);
52289bc588SBarry Smith   return 0;
53289bc588SBarry Smith }
5444a69424SLois Curfman McInnes static int MatLUFactorNumeric_Dense(Mat matin,Mat *fact)
55289bc588SBarry Smith {
5620563c6bSBarry Smith   return MatLUFactor(*fact,0,0);
57289bc588SBarry Smith }
5844a69424SLois Curfman McInnes static int MatChFactorSymbolic_Dense(Mat matin,IS row,Mat *fact)
59289bc588SBarry Smith {
60289bc588SBarry Smith   int ierr;
616abc6512SBarry Smith   if ((ierr = MatCopy(matin,fact))) SETERR(ierr,0);
62289bc588SBarry Smith   return 0;
63289bc588SBarry Smith }
6444a69424SLois Curfman McInnes static int MatChFactorNumeric_Dense(Mat matin,Mat *fact)
65289bc588SBarry Smith {
6620563c6bSBarry Smith   return MatCholeskyFactor(*fact,0);
67289bc588SBarry Smith }
6844a69424SLois Curfman McInnes static int MatChFactor_Dense(Mat matin,IS perm)
69289bc588SBarry Smith {
7044a69424SLois Curfman McInnes   Mat_Dense    *mat = (Mat_Dense *) matin->data;
716abc6512SBarry Smith   int       info;
72289bc588SBarry Smith   if (mat->pivots) {FREE(mat->pivots); mat->pivots = 0;}
73289bc588SBarry Smith   LApotrf_("L",&mat->n,mat->v,&mat->m,&info);
74289bc588SBarry Smith   if (info) SETERR(1,"Bad Cholesky factorization");
75289bc588SBarry Smith   matin->factor = FACTOR_CHOLESKY;
76289bc588SBarry Smith   return 0;
77289bc588SBarry Smith }
78289bc588SBarry Smith 
7944a69424SLois Curfman McInnes static int MatSolve_Dense(Mat matin,Vec xx,Vec yy)
80289bc588SBarry Smith {
8144a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
826abc6512SBarry Smith   int    one = 1, info;
836abc6512SBarry Smith   Scalar *x, *y;
84289bc588SBarry Smith   VecGetArray(xx,&x); VecGetArray(yy,&y);
85289bc588SBarry Smith   MEMCPY(y,x,mat->m*sizeof(Scalar));
869e25ed09SBarry Smith   if (matin->factor == FACTOR_LU) {
87289bc588SBarry Smith     LAgetrs_( "N", &mat->m, &one, mat->v, &mat->m, mat->pivots,
88289bc588SBarry Smith               y, &mat->m, &info );
89289bc588SBarry Smith   }
909e25ed09SBarry Smith   else if (matin->factor == FACTOR_CHOLESKY){
91289bc588SBarry Smith     LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,
92289bc588SBarry Smith               y, &mat->m, &info );
93289bc588SBarry Smith   }
949e25ed09SBarry Smith   else SETERR(1,"Matrix must be factored to solve");
95289bc588SBarry Smith   if (info) SETERR(1,"Bad solve");
96289bc588SBarry Smith   return 0;
97289bc588SBarry Smith }
9844a69424SLois Curfman McInnes static int MatSolveTrans_Dense(Mat matin,Vec xx,Vec yy)
99da3a660dSBarry Smith {
10044a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
1016abc6512SBarry Smith   int    one = 1, info;
1026abc6512SBarry Smith   Scalar *x, *y;
103da3a660dSBarry Smith   VecGetArray(xx,&x); VecGetArray(yy,&y);
104da3a660dSBarry Smith   MEMCPY(y,x,mat->m*sizeof(Scalar));
105da3a660dSBarry Smith   /* assume if pivots exist then LU else Cholesky */
106da3a660dSBarry Smith   if (mat->pivots) {
107da3a660dSBarry Smith     LAgetrs_( "T", &mat->m, &one, mat->v, &mat->m, mat->pivots,
108da3a660dSBarry Smith               y, &mat->m, &info );
109da3a660dSBarry Smith   }
110da3a660dSBarry Smith   else {
111da3a660dSBarry Smith     LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,
112da3a660dSBarry Smith               y, &mat->m, &info );
113da3a660dSBarry Smith   }
114da3a660dSBarry Smith   if (info) SETERR(1,"Bad solve");
115da3a660dSBarry Smith   return 0;
116da3a660dSBarry Smith }
11744a69424SLois Curfman McInnes static int MatSolveAdd_Dense(Mat matin,Vec xx,Vec zz,Vec yy)
118da3a660dSBarry Smith {
11944a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
1206abc6512SBarry Smith   int    one = 1, info,ierr;
1216abc6512SBarry Smith   Scalar *x, *y, sone = 1.0;
122da3a660dSBarry Smith   Vec    tmp = 0;
123da3a660dSBarry Smith   VecGetArray(xx,&x); VecGetArray(yy,&y);
124da3a660dSBarry Smith   if (yy == zz) {
125da3a660dSBarry Smith     ierr = VecCreate(yy,&tmp); CHKERR(ierr);
126da3a660dSBarry Smith     ierr = VecCopy(yy,tmp); CHKERR(ierr);
127da3a660dSBarry Smith   }
128da3a660dSBarry Smith   MEMCPY(y,x,mat->m*sizeof(Scalar));
129da3a660dSBarry Smith   /* assume if pivots exist then LU else Cholesky */
130da3a660dSBarry Smith   if (mat->pivots) {
131da3a660dSBarry Smith     LAgetrs_( "N", &mat->m, &one, mat->v, &mat->m, mat->pivots,
132da3a660dSBarry Smith               y, &mat->m, &info );
133da3a660dSBarry Smith   }
134da3a660dSBarry Smith   else {
135da3a660dSBarry Smith     LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,
136da3a660dSBarry Smith               y, &mat->m, &info );
137da3a660dSBarry Smith   }
138da3a660dSBarry Smith   if (info) SETERR(1,"Bad solve");
139da3a660dSBarry Smith   if (tmp) {VecAXPY(&sone,tmp,yy); VecDestroy(tmp);}
140da3a660dSBarry Smith   else VecAXPY(&sone,zz,yy);
141da3a660dSBarry Smith   return 0;
142da3a660dSBarry Smith }
14344a69424SLois Curfman McInnes static int MatSolveTransAdd_Dense(Mat matin,Vec xx,Vec zz, Vec yy)
144da3a660dSBarry Smith {
14544a69424SLois Curfman McInnes   Mat_Dense  *mat = (Mat_Dense *) matin->data;
1466abc6512SBarry Smith   int     one = 1, info,ierr;
1476abc6512SBarry Smith   Scalar  *x, *y, sone = 1.0;
148da3a660dSBarry Smith   Vec     tmp;
149da3a660dSBarry Smith   VecGetArray(xx,&x); VecGetArray(yy,&y);
150da3a660dSBarry Smith   if (yy == zz) {
151da3a660dSBarry Smith     ierr = VecCreate(yy,&tmp); CHKERR(ierr);
152da3a660dSBarry Smith     ierr = VecCopy(yy,tmp); CHKERR(ierr);
153da3a660dSBarry Smith   }
154da3a660dSBarry Smith   MEMCPY(y,x,mat->m*sizeof(Scalar));
155da3a660dSBarry Smith   /* assume if pivots exist then LU else Cholesky */
156da3a660dSBarry Smith   if (mat->pivots) {
157da3a660dSBarry Smith     LAgetrs_( "T", &mat->m, &one, mat->v, &mat->m, mat->pivots,
158da3a660dSBarry Smith               y, &mat->m, &info );
159da3a660dSBarry Smith   }
160da3a660dSBarry Smith   else {
161da3a660dSBarry Smith     LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,
162da3a660dSBarry Smith               y, &mat->m, &info );
163da3a660dSBarry Smith   }
164da3a660dSBarry Smith   if (info) SETERR(1,"Bad solve");
165da3a660dSBarry Smith   if (tmp) {VecAXPY(&sone,tmp,yy); VecDestroy(tmp);}
166da3a660dSBarry Smith   else VecAXPY(&sone,zz,yy);
167da3a660dSBarry Smith   return 0;
168da3a660dSBarry Smith }
169289bc588SBarry Smith /* ------------------------------------------------------------------*/
17044a69424SLois Curfman McInnes static int MatRelax_Dense(Mat matin,Vec bb,double omega,int flag,double shift,
171289bc588SBarry Smith                        int its,Vec xx)
172289bc588SBarry Smith {
17344a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
174289bc588SBarry Smith   Scalar *x, *b, *v = mat->v, zero = 0.0, xt;
1756abc6512SBarry Smith   int    o = 1,ierr, m = mat->m, i;
176289bc588SBarry Smith 
177289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
178289bc588SBarry Smith     /* this is a hack fix, should have another version without
179289bc588SBarry Smith        the second BLdot */
1806abc6512SBarry Smith     if ((ierr = VecSet(&zero,xx))) SETERR(ierr,0);
181289bc588SBarry Smith   }
182289bc588SBarry Smith   VecGetArray(xx,&x); VecGetArray(bb,&b);
183289bc588SBarry Smith   while (its--) {
184289bc588SBarry Smith     if (flag & SOR_FORWARD_SWEEP){
185289bc588SBarry Smith       for ( i=0; i<m; i++ ) {
186289bc588SBarry Smith         xt = b[i]-BLdot_(&m,v+i,&m,x,&o);
187d6dfbf8fSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt/(v[i + i*m]+shift) + x[i]);
188289bc588SBarry Smith       }
189289bc588SBarry Smith     }
190289bc588SBarry Smith     if (flag & SOR_BACKWARD_SWEEP) {
191289bc588SBarry Smith       for ( i=m-1; i>=0; i-- ) {
192289bc588SBarry Smith         xt = b[i]-BLdot_(&m,v+i,&m,x,&o);
193d6dfbf8fSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt/(v[i + i*m]+shift) + x[i]);
194289bc588SBarry Smith       }
195289bc588SBarry Smith     }
196289bc588SBarry Smith   }
197289bc588SBarry Smith   return 0;
198289bc588SBarry Smith }
199289bc588SBarry Smith 
200289bc588SBarry Smith /* -----------------------------------------------------------------*/
20144a69424SLois Curfman McInnes static int MatMultTrans_Dense(Mat matin,Vec xx,Vec yy)
202289bc588SBarry Smith {
20344a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
204289bc588SBarry Smith   Scalar *v = mat->v, *x, *y;
205289bc588SBarry Smith   int _One=1;Scalar _DOne=1.0, _DZero=0.0;
206289bc588SBarry Smith   VecGetArray(xx,&x), VecGetArray(yy,&y);
207289bc588SBarry Smith   LAgemv_( "T", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),
208289bc588SBarry Smith          x, &_One, &_DZero, y, &_One );
209289bc588SBarry Smith   return 0;
210289bc588SBarry Smith }
21144a69424SLois Curfman McInnes static int MatMult_Dense(Mat matin,Vec xx,Vec yy)
212289bc588SBarry Smith {
21344a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
214289bc588SBarry Smith   Scalar *v = mat->v, *x, *y;
215289bc588SBarry Smith   int _One=1;Scalar _DOne=1.0, _DZero=0.0;
216289bc588SBarry Smith   VecGetArray(xx,&x); VecGetArray(yy,&y);
217289bc588SBarry Smith   LAgemv_( "N", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),
218289bc588SBarry Smith          x, &_One, &_DZero, y, &_One );
219289bc588SBarry Smith   return 0;
220289bc588SBarry Smith }
22144a69424SLois Curfman McInnes static int MatMultAdd_Dense(Mat matin,Vec xx,Vec zz,Vec yy)
222289bc588SBarry Smith {
22344a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
224289bc588SBarry Smith   Scalar *v = mat->v, *x, *y, *z;
2256abc6512SBarry Smith   int    _One=1; Scalar _DOne=1.0;
226289bc588SBarry Smith   VecGetArray(xx,&x); VecGetArray(yy,&y); VecGetArray(zz,&z);
227289bc588SBarry Smith   if (zz != yy) MEMCPY(y,z,mat->m*sizeof(Scalar));
228289bc588SBarry Smith   LAgemv_( "N", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),
229289bc588SBarry Smith          x, &_One, &_DOne, y, &_One );
230289bc588SBarry Smith   return 0;
231289bc588SBarry Smith }
23244a69424SLois Curfman McInnes static int MatMultTransAdd_Dense(Mat matin,Vec xx,Vec zz,Vec yy)
233289bc588SBarry Smith {
23444a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
235289bc588SBarry Smith   Scalar *v = mat->v, *x, *y, *z;
236289bc588SBarry Smith   int    _One=1;
2376abc6512SBarry Smith   Scalar _DOne=1.0;
238289bc588SBarry Smith   VecGetArray(xx,&x); VecGetArray(yy,&y);
239289bc588SBarry Smith   VecGetArray(zz,&z);
240289bc588SBarry Smith   if (zz != yy) MEMCPY(y,z,mat->m*sizeof(Scalar));
241289bc588SBarry Smith   LAgemv_( "T", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),
242289bc588SBarry Smith          x, &_One, &_DOne, y, &_One );
243289bc588SBarry Smith   return 0;
244289bc588SBarry Smith }
245289bc588SBarry Smith 
246289bc588SBarry Smith /* -----------------------------------------------------------------*/
24744a69424SLois Curfman McInnes static int MatGetRow_Dense(Mat matin,int row,int *ncols,int **cols,
248289bc588SBarry Smith                         Scalar **vals)
249289bc588SBarry Smith {
25044a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
251289bc588SBarry Smith   Scalar *v;
252289bc588SBarry Smith   int    i;
253289bc588SBarry Smith   *ncols = mat->n;
254289bc588SBarry Smith   if (cols) {
255289bc588SBarry Smith     *cols = (int *) MALLOC(mat->n*sizeof(int)); CHKPTR(*cols);
256289bc588SBarry Smith     for ( i=0; i<mat->n; i++ ) *cols[i] = i;
257289bc588SBarry Smith   }
258289bc588SBarry Smith   if (vals) {
259289bc588SBarry Smith     *vals = (Scalar *) MALLOC(mat->n*sizeof(Scalar)); CHKPTR(*vals);
260289bc588SBarry Smith     v = mat->v + row;
261289bc588SBarry Smith     for ( i=0; i<mat->n; i++ ) {*vals[i] = *v; v += mat->m;}
262289bc588SBarry Smith   }
263289bc588SBarry Smith   return 0;
264289bc588SBarry Smith }
26544a69424SLois Curfman McInnes static int MatRestoreRow_Dense(Mat matin,int row,int *ncols,int **cols,
266289bc588SBarry Smith                             Scalar **vals)
267289bc588SBarry Smith {
268289bc588SBarry Smith   if (cols) { FREE(*cols); }
269289bc588SBarry Smith   if (vals) { FREE(*vals); }
270289bc588SBarry Smith   return 0;
271289bc588SBarry Smith }
272289bc588SBarry Smith /* ----------------------------------------------------------------*/
27344a69424SLois Curfman McInnes static int MatInsert_Dense(Mat matin,int m,int *indexm,int n,
274e8d4e0b9SBarry Smith                         int *indexn,Scalar *v,InsertMode addv)
275289bc588SBarry Smith {
27644a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
277289bc588SBarry Smith   int    i,j;
278d6dfbf8fSBarry Smith 
279289bc588SBarry Smith   if (!mat->roworiented) {
280e8d4e0b9SBarry Smith     if (addv == InsertValues) {
281289bc588SBarry Smith       for ( j=0; j<n; j++ ) {
282d6dfbf8fSBarry Smith         if (indexn[j] < 0) {*v += m; continue;}
283289bc588SBarry Smith         for ( i=0; i<m; i++ ) {
284d6dfbf8fSBarry Smith           if (indexm[i] < 0) {*v++; continue;}
285289bc588SBarry Smith           mat->v[indexn[j]*mat->m + indexm[i]] = *v++;
286289bc588SBarry Smith         }
287289bc588SBarry Smith       }
288289bc588SBarry Smith     }
289289bc588SBarry Smith     else {
290289bc588SBarry Smith       for ( j=0; j<n; j++ ) {
291d6dfbf8fSBarry Smith         if (indexn[j] < 0) {*v += m; continue;}
292289bc588SBarry Smith         for ( i=0; i<m; i++ ) {
293d6dfbf8fSBarry Smith           if (indexm[i] < 0) {*v++; continue;}
294289bc588SBarry Smith           mat->v[indexn[j]*mat->m + indexm[i]] += *v++;
295289bc588SBarry Smith         }
296289bc588SBarry Smith       }
297289bc588SBarry Smith     }
298e8d4e0b9SBarry Smith   }
299e8d4e0b9SBarry Smith   else {
300e8d4e0b9SBarry Smith     if (addv == InsertValues) {
301e8d4e0b9SBarry Smith       for ( i=0; i<m; i++ ) {
302d6dfbf8fSBarry Smith         if (indexm[i] < 0) {*v += n; continue;}
303e8d4e0b9SBarry Smith         for ( j=0; j<n; j++ ) {
304d6dfbf8fSBarry Smith           if (indexn[j] < 0) {*v++; continue;}
305e8d4e0b9SBarry Smith           mat->v[indexn[j]*mat->m + indexm[i]] = *v++;
306e8d4e0b9SBarry Smith         }
307e8d4e0b9SBarry Smith       }
308e8d4e0b9SBarry Smith     }
309289bc588SBarry Smith     else {
310289bc588SBarry Smith       for ( i=0; i<m; i++ ) {
311d6dfbf8fSBarry Smith         if (indexm[i] < 0) {*v += n; continue;}
312289bc588SBarry Smith         for ( j=0; j<n; j++ ) {
313d6dfbf8fSBarry Smith           if (indexn[j] < 0) {*v++; continue;}
314289bc588SBarry Smith           mat->v[indexn[j]*mat->m + indexm[i]] += *v++;
315289bc588SBarry Smith         }
316289bc588SBarry Smith       }
317289bc588SBarry Smith     }
318e8d4e0b9SBarry Smith   }
319289bc588SBarry Smith   return 0;
320289bc588SBarry Smith }
321e8d4e0b9SBarry Smith 
322289bc588SBarry Smith /* -----------------------------------------------------------------*/
32344a69424SLois Curfman McInnes static int MatCopy_Dense(Mat matin,Mat *newmat)
324289bc588SBarry Smith {
32544a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
326289bc588SBarry Smith   int ierr;
327289bc588SBarry Smith   Mat newi;
32844a69424SLois Curfman McInnes   Mat_Dense *l;
3296b5873e3SBarry Smith   if ((ierr = MatCreateSequentialDense(matin->comm,mat->m,mat->n,&newi)))
3306b5873e3SBarry Smith                                                           SETERR(ierr,0);
33144a69424SLois Curfman McInnes   l = (Mat_Dense *) newi->data;
332289bc588SBarry Smith   MEMCPY(l->v,mat->v,mat->m*mat->n*sizeof(Scalar));
333289bc588SBarry Smith   *newmat = newi;
334289bc588SBarry Smith   return 0;
335289bc588SBarry Smith }
336da3a660dSBarry Smith #include "viewer.h"
337289bc588SBarry Smith 
33844a69424SLois Curfman McInnes int MatView_Dense(PetscObject obj,Viewer ptr)
339289bc588SBarry Smith {
340289bc588SBarry Smith   Mat         matin = (Mat) obj;
34144a69424SLois Curfman McInnes   Mat_Dense      *mat = (Mat_Dense *) matin->data;
342289bc588SBarry Smith   Scalar      *v;
343289bc588SBarry Smith   int         i,j;
344da3a660dSBarry Smith   PetscObject ojb = (PetscObject) ptr;
345da3a660dSBarry Smith 
3466abc6512SBarry Smith   if (ojb && ojb->cookie == VIEWER_COOKIE && ojb->type == MATLAB_VIEWER) {
347da3a660dSBarry Smith     return ViewerMatlabPutArray(ptr,mat->m,mat->n,mat->v);
348da3a660dSBarry Smith   }
349da3a660dSBarry Smith   else {
3508e37dc09SBarry Smith     FILE *fd = ViewerFileGetPointer(ptr);
351289bc588SBarry Smith     for ( i=0; i<mat->m; i++ ) {
352289bc588SBarry Smith       v = mat->v + i;
353289bc588SBarry Smith       for ( j=0; j<mat->n; j++ ) {
354289bc588SBarry Smith #if defined(PETSC_COMPLEX)
3558e37dc09SBarry Smith         fprintf(fd,"%6.4e + %6.4e i ",real(*v),imag(*v)); v += mat->m;
356289bc588SBarry Smith #else
3578e37dc09SBarry Smith         fprintf(fd,"%6.4e ",*v); v += mat->m;
358289bc588SBarry Smith #endif
359289bc588SBarry Smith       }
3608e37dc09SBarry Smith       fprintf(fd,"\n");
361289bc588SBarry Smith     }
362da3a660dSBarry Smith   }
363289bc588SBarry Smith   return 0;
364289bc588SBarry Smith }
365289bc588SBarry Smith 
366289bc588SBarry Smith 
36744a69424SLois Curfman McInnes static int MatDestroy_Dense(PetscObject obj)
368289bc588SBarry Smith {
369289bc588SBarry Smith   Mat    mat = (Mat) obj;
37044a69424SLois Curfman McInnes   Mat_Dense *l = (Mat_Dense *) mat->data;
371a5a9c739SBarry Smith #if defined(PETSC_LOG)
372a5a9c739SBarry Smith   PLogObjectState(obj,"Rows %d Cols %d",l->m,l->n);
373a5a9c739SBarry Smith #endif
374289bc588SBarry Smith   if (l->pivots) FREE(l->pivots);
375289bc588SBarry Smith   FREE(l);
376a5a9c739SBarry Smith   PLogObjectDestroy(mat);
3779e25ed09SBarry Smith   PETSCHEADERDESTROY(mat);
378289bc588SBarry Smith   return 0;
379289bc588SBarry Smith }
380289bc588SBarry Smith 
38144a69424SLois Curfman McInnes static int MatTrans_Dense(Mat matin)
382289bc588SBarry Smith {
38344a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
384289bc588SBarry Smith   int    k,j;
385289bc588SBarry Smith   Scalar *v = mat->v, tmp;
386289bc588SBarry Smith   if (mat->m != mat->n) {
387289bc588SBarry Smith     SETERR(1,"Cannot transpose rectangular dense matrix");
388289bc588SBarry Smith   }
389289bc588SBarry Smith   for ( j=0; j<mat->m; j++ ) {
390289bc588SBarry Smith     for ( k=0; k<j; k++ ) {
391289bc588SBarry Smith       tmp = v[j + k*mat->n];
392289bc588SBarry Smith       v[j + k*mat->n] = v[k + j*mat->n];
393289bc588SBarry Smith       v[k + j*mat->n] = tmp;
394289bc588SBarry Smith     }
395289bc588SBarry Smith   }
396289bc588SBarry Smith   return 0;
397289bc588SBarry Smith }
398289bc588SBarry Smith 
39944a69424SLois Curfman McInnes static int MatEqual_Dense(Mat matin1,Mat matin2)
400289bc588SBarry Smith {
40144a69424SLois Curfman McInnes   Mat_Dense *mat1 = (Mat_Dense *) matin1->data;
40244a69424SLois Curfman McInnes   Mat_Dense *mat2 = (Mat_Dense *) matin2->data;
403289bc588SBarry Smith   int    i;
404289bc588SBarry Smith   Scalar *v1 = mat1->v, *v2 = mat2->v;
405289bc588SBarry Smith   if (mat1->m != mat2->m) return 0;
406289bc588SBarry Smith   if (mat1->n != mat2->n) return 0;
407289bc588SBarry Smith   for ( i=0; i<mat1->m*mat1->n; i++ ) {
408289bc588SBarry Smith     if (*v1 != *v2) return 0;
409289bc588SBarry Smith     v1++; v2++;
410289bc588SBarry Smith   }
411289bc588SBarry Smith   return 1;
412289bc588SBarry Smith }
413289bc588SBarry Smith 
41444a69424SLois Curfman McInnes static int MatGetDiag_Dense(Mat matin,Vec v)
415289bc588SBarry Smith {
41644a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
4176abc6512SBarry Smith   int    i, n;
4186abc6512SBarry Smith   Scalar *x;
419289bc588SBarry Smith   CHKTYPE(v,SEQVECTOR);
420289bc588SBarry Smith   VecGetArray(v,&x); VecGetSize(v,&n);
421289bc588SBarry Smith   if (n != mat->m) SETERR(1,"Nonconforming matrix and vector");
422289bc588SBarry Smith   for ( i=0; i<mat->m; i++ ) {
423289bc588SBarry Smith     x[i] = mat->v[i*mat->m + i];
424289bc588SBarry Smith   }
425289bc588SBarry Smith   return 0;
426289bc588SBarry Smith }
427289bc588SBarry Smith 
42844a69424SLois Curfman McInnes static int MatScale_Dense(Mat matin,Vec ll,Vec rr)
429289bc588SBarry Smith {
43044a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
431da3a660dSBarry Smith   Scalar *l,*r,x,*v;
432da3a660dSBarry Smith   int    i,j,m = mat->m, n = mat->n;
43328988994SBarry Smith   if (ll) {
434da3a660dSBarry Smith     VecGetArray(ll,&l); VecGetSize(ll,&m);
435da3a660dSBarry Smith     if (m != mat->m) SETERR(1,"Left scaling vector wrong length");
436da3a660dSBarry Smith     for ( i=0; i<m; i++ ) {
437da3a660dSBarry Smith       x = l[i];
438da3a660dSBarry Smith       v = mat->v + i;
439da3a660dSBarry Smith       for ( j=0; j<n; j++ ) { (*v) *= x; v+= m;}
440da3a660dSBarry Smith     }
441da3a660dSBarry Smith   }
44228988994SBarry Smith   if (rr) {
443da3a660dSBarry Smith     VecGetArray(rr,&r); VecGetSize(rr,&n);
444da3a660dSBarry Smith     if (n != mat->n) SETERR(1,"Right scaling vector wrong length");
445da3a660dSBarry Smith     for ( i=0; i<n; i++ ) {
446da3a660dSBarry Smith       x = r[i];
447da3a660dSBarry Smith       v = mat->v + i*m;
448da3a660dSBarry Smith       for ( j=0; j<m; j++ ) { (*v++) *= x;}
449da3a660dSBarry Smith     }
450da3a660dSBarry Smith   }
451289bc588SBarry Smith   return 0;
452289bc588SBarry Smith }
453289bc588SBarry Smith 
454da3a660dSBarry Smith 
45544a69424SLois Curfman McInnes static int MatNorm_Dense(Mat matin,int type,double *norm)
456289bc588SBarry Smith {
45744a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
458289bc588SBarry Smith   Scalar *v = mat->v;
459289bc588SBarry Smith   double sum = 0.0;
460289bc588SBarry Smith   int    i, j;
461289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
462289bc588SBarry Smith     for (i=0; i<mat->n*mat->m; i++ ) {
463289bc588SBarry Smith #if defined(PETSC_COMPLEX)
464289bc588SBarry Smith       sum += real(conj(*v)*(*v)); v++;
465289bc588SBarry Smith #else
466289bc588SBarry Smith       sum += (*v)*(*v); v++;
467289bc588SBarry Smith #endif
468289bc588SBarry Smith     }
469289bc588SBarry Smith     *norm = sqrt(sum);
470289bc588SBarry Smith   }
471289bc588SBarry Smith   else if (type == NORM_1) {
472289bc588SBarry Smith     *norm = 0.0;
473289bc588SBarry Smith     for ( j=0; j<mat->n; j++ ) {
474289bc588SBarry Smith       sum = 0.0;
475289bc588SBarry Smith       for ( i=0; i<mat->m; i++ ) {
476289bc588SBarry Smith #if defined(PETSC_COMPLEX)
477289bc588SBarry Smith         sum += abs(*v++);
478289bc588SBarry Smith #else
479289bc588SBarry Smith         sum += fabs(*v++);
480289bc588SBarry Smith #endif
481289bc588SBarry Smith       }
482289bc588SBarry Smith       if (sum > *norm) *norm = sum;
483289bc588SBarry Smith     }
484289bc588SBarry Smith   }
485289bc588SBarry Smith   else if (type == NORM_INFINITY) {
486289bc588SBarry Smith     *norm = 0.0;
487289bc588SBarry Smith     for ( j=0; j<mat->m; j++ ) {
488289bc588SBarry Smith       v = mat->v + j;
489289bc588SBarry Smith       sum = 0.0;
490289bc588SBarry Smith       for ( i=0; i<mat->n; i++ ) {
491289bc588SBarry Smith #if defined(PETSC_COMPLEX)
492289bc588SBarry Smith         sum += abs(*v); v += mat->m;
493289bc588SBarry Smith #else
494289bc588SBarry Smith         sum += fabs(*v); v += mat->m;
495289bc588SBarry Smith #endif
496289bc588SBarry Smith       }
497289bc588SBarry Smith       if (sum > *norm) *norm = sum;
498289bc588SBarry Smith     }
499289bc588SBarry Smith   }
500289bc588SBarry Smith   else {
501289bc588SBarry Smith     SETERR(1,"No support for the two norm yet");
502289bc588SBarry Smith   }
503289bc588SBarry Smith   return 0;
504289bc588SBarry Smith }
505289bc588SBarry Smith 
50644a69424SLois Curfman McInnes static int MatInsOpt_Dense(Mat aijin,int op)
507289bc588SBarry Smith {
50844a69424SLois Curfman McInnes   Mat_Dense *aij = (Mat_Dense *) aijin->data;
509289bc588SBarry Smith   if (op == ROW_ORIENTED)            aij->roworiented = 1;
510289bc588SBarry Smith   else if (op == COLUMN_ORIENTED)    aij->roworiented = 0;
511289bc588SBarry Smith   /* doesn't care about sorted rows or columns */
512289bc588SBarry Smith   return 0;
513289bc588SBarry Smith }
514289bc588SBarry Smith 
51544a69424SLois Curfman McInnes static int MatZero_Dense(Mat A)
5166f0a148fSBarry Smith {
51744a69424SLois Curfman McInnes   Mat_Dense *l = (Mat_Dense *) A->data;
5186f0a148fSBarry Smith   MEMSET(l->v,0,l->m*l->n*sizeof(Scalar));
5196f0a148fSBarry Smith   return 0;
5206f0a148fSBarry Smith }
5216f0a148fSBarry Smith 
52244a69424SLois Curfman McInnes static int MatZeroRows_Dense(Mat A,IS is,Scalar *diag)
5236f0a148fSBarry Smith {
52444a69424SLois Curfman McInnes   Mat_Dense *l = (Mat_Dense *) A->data;
5256abc6512SBarry Smith   int    n = l->n, i, j,ierr,N, *rows;
5266f0a148fSBarry Smith   Scalar *slot;
527260925b8SBarry Smith   ierr = ISGetLocalSize(is,&N); CHKERR(ierr);
528260925b8SBarry Smith   ierr = ISGetIndices(is,&rows); CHKERR(ierr);
5296f0a148fSBarry Smith   for ( i=0; i<N; i++ ) {
5306f0a148fSBarry Smith     slot = l->v + rows[i];
5316f0a148fSBarry Smith     for ( j=0; j<n; j++ ) { *slot = 0.0; slot += n;}
5326f0a148fSBarry Smith   }
5336f0a148fSBarry Smith   if (diag) {
5346f0a148fSBarry Smith     for ( i=0; i<N; i++ ) {
5356f0a148fSBarry Smith       slot = l->v + (n+1)*rows[i];
536260925b8SBarry Smith       *slot = *diag;
5376f0a148fSBarry Smith     }
5386f0a148fSBarry Smith   }
539260925b8SBarry Smith   ISRestoreIndices(is,&rows);
5406f0a148fSBarry Smith   return 0;
5416f0a148fSBarry Smith }
542557bce09SLois Curfman McInnes 
543fa9ec3f1SLois Curfman McInnes static int MatGetSize_Dense(Mat matin,int *m,int *n)
544557bce09SLois Curfman McInnes {
54544a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
546557bce09SLois Curfman McInnes   *m = mat->m; *n = mat->n;
547557bce09SLois Curfman McInnes   return 0;
548557bce09SLois Curfman McInnes }
549557bce09SLois Curfman McInnes 
55044a69424SLois Curfman McInnes static int MatGetArray_Dense(Mat matin,Scalar **array)
55164e87e97SBarry Smith {
55244a69424SLois Curfman McInnes   Mat_Dense *mat = (Mat_Dense *) matin->data;
55364e87e97SBarry Smith   *array = mat->v;
55464e87e97SBarry Smith   return 0;
55564e87e97SBarry Smith }
556289bc588SBarry Smith /* -------------------------------------------------------------------*/
55744a69424SLois Curfman McInnes static struct _MatOps MatOps = {MatInsert_Dense,
55844a69424SLois Curfman McInnes        MatGetRow_Dense, MatRestoreRow_Dense,
55944a69424SLois Curfman McInnes        MatMult_Dense, MatMultAdd_Dense,
56044a69424SLois Curfman McInnes        MatMultTrans_Dense, MatMultTransAdd_Dense,
56144a69424SLois Curfman McInnes        MatSolve_Dense,MatSolveAdd_Dense,
56244a69424SLois Curfman McInnes        MatSolveTrans_Dense,MatSolveTransAdd_Dense,
56344a69424SLois Curfman McInnes        MatLUFactor_Dense,MatChFactor_Dense,
56444a69424SLois Curfman McInnes        MatRelax_Dense,
56544a69424SLois Curfman McInnes        MatTrans_Dense,
566fa9ec3f1SLois Curfman McInnes        MatGetInfo_Dense,MatEqual_Dense,
56744a69424SLois Curfman McInnes        MatCopy_Dense,
56844a69424SLois Curfman McInnes        MatGetDiag_Dense,MatScale_Dense,MatNorm_Dense,
569289bc588SBarry Smith        0,0,
57044a69424SLois Curfman McInnes        0, MatInsOpt_Dense,MatZero_Dense,MatZeroRows_Dense,0,
57144a69424SLois Curfman McInnes        MatLUFactorSymbolic_Dense,MatLUFactorNumeric_Dense,
57244a69424SLois Curfman McInnes        MatChFactorSymbolic_Dense,MatChFactorNumeric_Dense,
573fa9ec3f1SLois Curfman McInnes        MatGetSize_Dense,MatGetSize_Dense,0,
57444a69424SLois Curfman McInnes        0,0,MatGetArray_Dense
575289bc588SBarry Smith };
57620563c6bSBarry Smith /*@
57720563c6bSBarry Smith    MatCreateSequentialDense - Creates a sequential dense matrix that
578*d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
579*d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
580289bc588SBarry Smith 
58120563c6bSBarry Smith    Input Parameters:
5820c775827SLois Curfman McInnes .  comm - MPI communicator, set to MPI_COMM_SELF
5830c775827SLois Curfman McInnes .  m - number of rows
5840c775827SLois Curfman McInnes .  n - number of column
58520563c6bSBarry Smith 
58620563c6bSBarry Smith    Output Parameter:
5870c775827SLois Curfman McInnes .  newmat - the matrix
58820563c6bSBarry Smith 
589*d65003e9SLois Curfman McInnes .keywords: Mat, dense, matrix, LAPACK, BLAS
590*d65003e9SLois Curfman McInnes 
591*d65003e9SLois Curfman McInnes .seealso: MatCreateSequentialAIJ()
59220563c6bSBarry Smith @*/
5936b5873e3SBarry Smith int MatCreateSequentialDense(MPI_Comm comm,int m,int n,Mat *newmat)
594289bc588SBarry Smith {
59544a69424SLois Curfman McInnes   int       size = sizeof(Mat_Dense) + m*n*sizeof(Scalar);
596289bc588SBarry Smith   Mat mat;
59744a69424SLois Curfman McInnes   Mat_Dense    *l;
598289bc588SBarry Smith   *newmat        = 0;
5996b5873e3SBarry Smith   PETSCHEADERCREATE(mat,_Mat,MAT_COOKIE,MATDENSE,comm);
600a5a9c739SBarry Smith   PLogObjectCreate(mat);
60144a69424SLois Curfman McInnes   l              = (Mat_Dense *) MALLOC(size); CHKPTR(l);
602289bc588SBarry Smith   mat->ops       = &MatOps;
60344a69424SLois Curfman McInnes   mat->destroy   = MatDestroy_Dense;
60444a69424SLois Curfman McInnes   mat->view      = MatView_Dense;
605289bc588SBarry Smith   mat->data      = (void *) l;
606289bc588SBarry Smith   mat->factor    = 0;
607289bc588SBarry Smith   mat->col       = 0;
608289bc588SBarry Smith   mat->row       = 0;
609d6dfbf8fSBarry Smith 
610289bc588SBarry Smith   l->m           = m;
611289bc588SBarry Smith   l->n           = n;
612289bc588SBarry Smith   l->v           = (Scalar *) (l + 1);
613289bc588SBarry Smith   l->pivots      = 0;
614289bc588SBarry Smith   l->roworiented = 1;
615d6dfbf8fSBarry Smith 
616289bc588SBarry Smith   MEMSET(l->v,0,m*n*sizeof(Scalar));
617289bc588SBarry Smith   *newmat = mat;
618289bc588SBarry Smith   return 0;
619289bc588SBarry Smith }
620289bc588SBarry Smith 
62144a69424SLois Curfman McInnes int MatCreate_Dense(Mat matin,Mat *newmat)
622289bc588SBarry Smith {
62344a69424SLois Curfman McInnes   Mat_Dense *m = (Mat_Dense *) matin->data;
6246b5873e3SBarry Smith   return MatCreateSequentialDense(matin->comm,m->m,m->n,newmat);
625289bc588SBarry Smith }
626