1cb512458SBarry Smith #ifndef lint 2*88e32edaSLois Curfman McInnes static char vcid[] = "$Id: dense.c,v 1.69 1995/10/23 23:13:48 curfman Exp curfman $"; 3cb512458SBarry Smith #endif 4289bc588SBarry Smith 517699dbbSLois Curfman McInnes #include "dense.h" 6b16a3bb1SBarry Smith #include "pinclude/plapack.h" 7b16a3bb1SBarry Smith #include "pinclude/pviewer.h" 8289bc588SBarry Smith 91987afe7SBarry Smith int MatAXPY_SeqDense(Scalar *alpha,Mat X,Mat Y) 101987afe7SBarry Smith { 111987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense*) X->data,*y = (Mat_SeqDense*) Y->data; 121987afe7SBarry Smith int N = x->m*x->n, one = 1; 131987afe7SBarry Smith BLaxpy_( &N, alpha, x->v, &one, y->v, &one ); 141987afe7SBarry Smith PLogFlops(2*N-1); 151987afe7SBarry Smith return 0; 161987afe7SBarry Smith } 171987afe7SBarry Smith 18c0bbcb79SLois Curfman McInnes static int MatGetInfo_SeqDense(Mat A,MatInfoType flag,int *nz,int *nzalloc,int *mem) 19289bc588SBarry Smith { 20c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 21289bc588SBarry Smith int i,N = mat->m*mat->n,count = 0; 22289bc588SBarry Smith Scalar *v = mat->v; 23289bc588SBarry Smith for ( i=0; i<N; i++ ) {if (*v != 0.0) count++; v++;} 24c0bbcb79SLois Curfman McInnes *nz = count; *nzalloc = N; *mem = (int)A->mem; 25fa9ec3f1SLois Curfman McInnes return 0; 26289bc588SBarry Smith } 27289bc588SBarry Smith 28289bc588SBarry Smith /* ---------------------------------------------------------------*/ 29289bc588SBarry Smith /* COMMENT: I have chosen to hide column permutation in the pivots, 30289bc588SBarry Smith rather than put it in the Mat->col slot.*/ 31c0bbcb79SLois Curfman McInnes static int MatLUFactor_SeqDense(Mat A,IS row,IS col,double f) 32289bc588SBarry Smith { 33c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 346abc6512SBarry Smith int info; 3555659b69SBarry Smith 36289bc588SBarry Smith if (!mat->pivots) { 3748d91487SBarry Smith mat->pivots = (int *) PETSCMALLOC(mat->m*sizeof(int));CHKPTRQ(mat->pivots); 38c0bbcb79SLois Curfman McInnes PLogObjectMemory(A,mat->m*sizeof(int)); 39289bc588SBarry Smith } 40289bc588SBarry Smith LAgetrf_(&mat->m,&mat->n,mat->v,&mat->m,mat->pivots,&info); 41ec8511deSBarry Smith if (info) SETERRQ(1,"MatLUFactor_SeqDense:Bad LU factorization"); 42c0bbcb79SLois Curfman McInnes A->factor = FACTOR_LU; 4355659b69SBarry Smith PLogFlops((2*mat->n*mat->n*mat->n)/3); 44289bc588SBarry Smith return 0; 45289bc588SBarry Smith } 46c0bbcb79SLois Curfman McInnes static int MatLUFactorSymbolic_SeqDense(Mat A,IS row,IS col,double f,Mat *fact) 47289bc588SBarry Smith { 48289bc588SBarry Smith int ierr; 49c0bbcb79SLois Curfman McInnes ierr = MatConvert(A,MATSAME,fact); CHKERRQ(ierr); 50289bc588SBarry Smith return 0; 51289bc588SBarry Smith } 52c0bbcb79SLois Curfman McInnes static int MatLUFactorNumeric_SeqDense(Mat A,Mat *fact) 53289bc588SBarry Smith { 5449d8b64dSBarry Smith return MatLUFactor(*fact,0,0,1.0); 55289bc588SBarry Smith } 56c0bbcb79SLois Curfman McInnes static int MatCholeskyFactorSymbolic_SeqDense(Mat A,IS row,double f,Mat *fact) 57289bc588SBarry Smith { 58289bc588SBarry Smith int ierr; 59c0bbcb79SLois Curfman McInnes ierr = MatConvert(A,MATSAME,fact); CHKERRQ(ierr); 60289bc588SBarry Smith return 0; 61289bc588SBarry Smith } 62c0bbcb79SLois Curfman McInnes static int MatCholeskyFactorNumeric_SeqDense(Mat A,Mat *fact) 63289bc588SBarry Smith { 6449d8b64dSBarry Smith return MatCholeskyFactor(*fact,0,1.0); 65289bc588SBarry Smith } 66c0bbcb79SLois Curfman McInnes static int MatCholeskyFactor_SeqDense(Mat A,IS perm,double f) 67289bc588SBarry Smith { 68c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 696abc6512SBarry Smith int info; 7055659b69SBarry Smith 71752f5567SLois Curfman McInnes if (mat->pivots) { 72752f5567SLois Curfman McInnes PETSCFREE(mat->pivots); 73c0bbcb79SLois Curfman McInnes PLogObjectMemory(A,-mat->m*sizeof(int)); 74752f5567SLois Curfman McInnes mat->pivots = 0; 75752f5567SLois Curfman McInnes } 76289bc588SBarry Smith LApotrf_("L",&mat->n,mat->v,&mat->m,&info); 77ec8511deSBarry Smith if (info) SETERRQ(1,"MatCholeskyFactor_SeqDense:Bad factorization"); 78c0bbcb79SLois Curfman McInnes A->factor = FACTOR_CHOLESKY; 7955659b69SBarry Smith PLogFlops((mat->n*mat->n*mat->n)/3); 80289bc588SBarry Smith return 0; 81289bc588SBarry Smith } 82289bc588SBarry Smith 83c0bbcb79SLois Curfman McInnes static int MatSolve_SeqDense(Mat A,Vec xx,Vec yy) 84289bc588SBarry Smith { 85c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 866abc6512SBarry Smith int one = 1, info; 876abc6512SBarry Smith Scalar *x, *y; 88289bc588SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 89416022c9SBarry Smith PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 90c0bbcb79SLois Curfman McInnes if (A->factor == FACTOR_LU) { 9148d91487SBarry Smith LAgetrs_( "N", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 92289bc588SBarry Smith } 93c0bbcb79SLois Curfman McInnes else if (A->factor == FACTOR_CHOLESKY){ 9448d91487SBarry Smith LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 95289bc588SBarry Smith } 96ec8511deSBarry Smith else SETERRQ(1,"MatSolve_SeqDense:Matrix must be factored to solve"); 97ec8511deSBarry Smith if (info) SETERRQ(1,"MatSolve_SeqDense:Bad solve"); 9855659b69SBarry Smith PLogFlops(mat->n*mat->n - mat->n); 99289bc588SBarry Smith return 0; 100289bc588SBarry Smith } 101c0bbcb79SLois Curfman McInnes static int MatSolveTrans_SeqDense(Mat A,Vec xx,Vec yy) 102da3a660dSBarry Smith { 103c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1046abc6512SBarry Smith int one = 1, info; 1056abc6512SBarry Smith Scalar *x, *y; 106da3a660dSBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 107416022c9SBarry Smith PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 108752f5567SLois Curfman McInnes /* assume if pivots exist then use LU; else Cholesky */ 109da3a660dSBarry Smith if (mat->pivots) { 11048d91487SBarry Smith LAgetrs_( "T", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 111da3a660dSBarry Smith } 112da3a660dSBarry Smith else { 11348d91487SBarry Smith LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 114da3a660dSBarry Smith } 115ec8511deSBarry Smith if (info) SETERRQ(1,"MatSolveTrans_SeqDense:Bad solve"); 11655659b69SBarry Smith PLogFlops(mat->n*mat->n - mat->n); 117da3a660dSBarry Smith return 0; 118da3a660dSBarry Smith } 119c0bbcb79SLois Curfman McInnes static int MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 120da3a660dSBarry Smith { 121c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1226abc6512SBarry Smith int one = 1, info,ierr; 1236abc6512SBarry Smith Scalar *x, *y, sone = 1.0; 124da3a660dSBarry Smith Vec tmp = 0; 125da3a660dSBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 126da3a660dSBarry Smith if (yy == zz) { 12778b31e54SBarry Smith ierr = VecDuplicate(yy,&tmp); CHKERRQ(ierr); 128c0bbcb79SLois Curfman McInnes PLogObjectParent(A,tmp); 12978b31e54SBarry Smith ierr = VecCopy(yy,tmp); CHKERRQ(ierr); 130da3a660dSBarry Smith } 131416022c9SBarry Smith PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 132752f5567SLois Curfman McInnes /* assume if pivots exist then use LU; else Cholesky */ 133da3a660dSBarry Smith if (mat->pivots) { 13448d91487SBarry Smith LAgetrs_( "N", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 135da3a660dSBarry Smith } 136da3a660dSBarry Smith else { 13748d91487SBarry Smith LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 138da3a660dSBarry Smith } 139ec8511deSBarry Smith if (info) SETERRQ(1,"MatSolveAdd_SeqDense:Bad solve"); 140da3a660dSBarry Smith if (tmp) {VecAXPY(&sone,tmp,yy); VecDestroy(tmp);} 141da3a660dSBarry Smith else VecAXPY(&sone,zz,yy); 14255659b69SBarry Smith PLogFlops(mat->n*mat->n - mat->n); 143da3a660dSBarry Smith return 0; 144da3a660dSBarry Smith } 145c0bbcb79SLois Curfman McInnes static int MatSolveTransAdd_SeqDense(Mat A,Vec xx,Vec zz, Vec yy) 146da3a660dSBarry Smith { 147c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1486abc6512SBarry Smith int one = 1, info,ierr; 1496abc6512SBarry Smith Scalar *x, *y, sone = 1.0; 150da3a660dSBarry Smith Vec tmp; 151da3a660dSBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 152da3a660dSBarry Smith if (yy == zz) { 15378b31e54SBarry Smith ierr = VecDuplicate(yy,&tmp); CHKERRQ(ierr); 154c0bbcb79SLois Curfman McInnes PLogObjectParent(A,tmp); 15578b31e54SBarry Smith ierr = VecCopy(yy,tmp); CHKERRQ(ierr); 156da3a660dSBarry Smith } 157416022c9SBarry Smith PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 158752f5567SLois Curfman McInnes /* assume if pivots exist then use LU; else Cholesky */ 159da3a660dSBarry Smith if (mat->pivots) { 16048d91487SBarry Smith LAgetrs_( "T", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 161da3a660dSBarry Smith } 162da3a660dSBarry Smith else { 16348d91487SBarry Smith LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 164da3a660dSBarry Smith } 165ec8511deSBarry Smith if (info) SETERRQ(1,"MatSolveTransAdd_SeqDense:Bad solve"); 166da3a660dSBarry Smith if (tmp) {VecAXPY(&sone,tmp,yy); VecDestroy(tmp);} 167da3a660dSBarry Smith else VecAXPY(&sone,zz,yy); 16855659b69SBarry Smith PLogFlops(mat->n*mat->n - mat->n); 169da3a660dSBarry Smith return 0; 170da3a660dSBarry Smith } 171289bc588SBarry Smith /* ------------------------------------------------------------------*/ 172c0bbcb79SLois Curfman McInnes static int MatRelax_SeqDense(Mat A,Vec bb,double omega,MatSORType flag, 17320e1a0d4SLois Curfman McInnes double shift,int its,Vec xx) 174289bc588SBarry Smith { 175c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 176289bc588SBarry Smith Scalar *x, *b, *v = mat->v, zero = 0.0, xt; 1776abc6512SBarry Smith int o = 1,ierr, m = mat->m, i; 178289bc588SBarry Smith 179289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 180289bc588SBarry Smith /* this is a hack fix, should have another version without 181289bc588SBarry Smith the second BLdot */ 182bbb6d6a8SBarry Smith ierr = VecSet(&zero,xx); CHKERRQ(ierr); 183289bc588SBarry Smith } 184289bc588SBarry Smith VecGetArray(xx,&x); VecGetArray(bb,&b); 185289bc588SBarry Smith while (its--) { 186289bc588SBarry Smith if (flag & SOR_FORWARD_SWEEP){ 187289bc588SBarry Smith for ( i=0; i<m; i++ ) { 188f1747703SBarry Smith #if defined(PETSC_COMPLEX) 189f1747703SBarry Smith /* cannot use BLAS dot for complex because compiler/linker is 190f1747703SBarry Smith not happy about returning a double complex */ 191f1747703SBarry Smith int _i; 192f1747703SBarry Smith Scalar sum = b[i]; 193f1747703SBarry Smith for ( _i=0; _i<m; _i++ ) { 194f1747703SBarry Smith sum -= conj(v[i+_i*m])*x[_i]; 195f1747703SBarry Smith } 196f1747703SBarry Smith xt = sum; 197f1747703SBarry Smith #else 198289bc588SBarry Smith xt = b[i]-BLdot_(&m,v+i,&m,x,&o); 199f1747703SBarry Smith #endif 200d6dfbf8fSBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt/(v[i + i*m]+shift) + x[i]); 201289bc588SBarry Smith } 202289bc588SBarry Smith } 203289bc588SBarry Smith if (flag & SOR_BACKWARD_SWEEP) { 204289bc588SBarry Smith for ( i=m-1; i>=0; i-- ) { 205f1747703SBarry Smith #if defined(PETSC_COMPLEX) 206f1747703SBarry Smith /* cannot use BLAS dot for complex because compiler/linker is 207f1747703SBarry Smith not happy about returning a double complex */ 208f1747703SBarry Smith int _i; 209f1747703SBarry Smith Scalar sum = b[i]; 210f1747703SBarry Smith for ( _i=0; _i<m; _i++ ) { 211f1747703SBarry Smith sum -= conj(v[i+_i*m])*x[_i]; 212f1747703SBarry Smith } 213f1747703SBarry Smith xt = sum; 214f1747703SBarry Smith #else 215289bc588SBarry Smith xt = b[i]-BLdot_(&m,v+i,&m,x,&o); 216f1747703SBarry Smith #endif 217d6dfbf8fSBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt/(v[i + i*m]+shift) + x[i]); 218289bc588SBarry Smith } 219289bc588SBarry Smith } 220289bc588SBarry Smith } 221289bc588SBarry Smith return 0; 222289bc588SBarry Smith } 223289bc588SBarry Smith 224289bc588SBarry Smith /* -----------------------------------------------------------------*/ 225c0bbcb79SLois Curfman McInnes static int MatMultTrans_SeqDense(Mat A,Vec xx,Vec yy) 226289bc588SBarry Smith { 227c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 228289bc588SBarry Smith Scalar *v = mat->v, *x, *y; 229289bc588SBarry Smith int _One=1;Scalar _DOne=1.0, _DZero=0.0; 230289bc588SBarry Smith VecGetArray(xx,&x), VecGetArray(yy,&y); 23148d91487SBarry Smith LAgemv_("T",&(mat->m),&(mat->n),&_DOne,v,&(mat->m),x,&_One,&_DZero,y,&_One); 23255659b69SBarry Smith PLogFlops(2*mat->m*mat->n - mat->n); 233289bc588SBarry Smith return 0; 234289bc588SBarry Smith } 235c0bbcb79SLois Curfman McInnes static int MatMult_SeqDense(Mat A,Vec xx,Vec yy) 236289bc588SBarry Smith { 237c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 238289bc588SBarry Smith Scalar *v = mat->v, *x, *y; 239289bc588SBarry Smith int _One=1;Scalar _DOne=1.0, _DZero=0.0; 240289bc588SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 24148d91487SBarry Smith LAgemv_( "N", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),x,&_One,&_DZero,y,&_One); 24255659b69SBarry Smith PLogFlops(2*mat->m*mat->n - mat->m); 243289bc588SBarry Smith return 0; 244289bc588SBarry Smith } 245c0bbcb79SLois Curfman McInnes static int MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 246289bc588SBarry Smith { 247c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 248289bc588SBarry Smith Scalar *v = mat->v, *x, *y, *z; 2496abc6512SBarry Smith int _One=1; Scalar _DOne=1.0; 250289bc588SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); VecGetArray(zz,&z); 251416022c9SBarry Smith if (zz != yy) PetscMemcpy(y,z,mat->m*sizeof(Scalar)); 25248d91487SBarry Smith LAgemv_( "N", &(mat->m), &(mat->n),&_DOne,v,&(mat->m),x,&_One,&_DOne,y,&_One); 25355659b69SBarry Smith PLogFlops(2*mat->m*mat->n); 254289bc588SBarry Smith return 0; 255289bc588SBarry Smith } 256c0bbcb79SLois Curfman McInnes static int MatMultTransAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 257289bc588SBarry Smith { 258c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 259289bc588SBarry Smith Scalar *v = mat->v, *x, *y, *z; 260289bc588SBarry Smith int _One=1; 2616abc6512SBarry Smith Scalar _DOne=1.0; 262289bc588SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 263289bc588SBarry Smith VecGetArray(zz,&z); 264416022c9SBarry Smith if (zz != yy) PetscMemcpy(y,z,mat->m*sizeof(Scalar)); 26548d91487SBarry Smith LAgemv_( "T", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),x,&_One,&_DOne,y,&_One); 26655659b69SBarry Smith PLogFlops(2*mat->m*mat->n); 267289bc588SBarry Smith return 0; 268289bc588SBarry Smith } 269289bc588SBarry Smith 270289bc588SBarry Smith /* -----------------------------------------------------------------*/ 271c0bbcb79SLois Curfman McInnes static int MatGetRow_SeqDense(Mat A,int row,int *ncols,int **cols,Scalar **vals) 272289bc588SBarry Smith { 273c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 274289bc588SBarry Smith Scalar *v; 275289bc588SBarry Smith int i; 276289bc588SBarry Smith *ncols = mat->n; 277289bc588SBarry Smith if (cols) { 27878b31e54SBarry Smith *cols = (int *) PETSCMALLOC(mat->n*sizeof(int)); CHKPTRQ(*cols); 27973c3ce57SBarry Smith for ( i=0; i<mat->n; i++ ) (*cols)[i] = i; 280289bc588SBarry Smith } 281289bc588SBarry Smith if (vals) { 28278b31e54SBarry Smith *vals = (Scalar *) PETSCMALLOC(mat->n*sizeof(Scalar)); CHKPTRQ(*vals); 283289bc588SBarry Smith v = mat->v + row; 28473c3ce57SBarry Smith for ( i=0; i<mat->n; i++ ) {(*vals)[i] = *v; v += mat->m;} 285289bc588SBarry Smith } 286289bc588SBarry Smith return 0; 287289bc588SBarry Smith } 288c0bbcb79SLois Curfman McInnes static int MatRestoreRow_SeqDense(Mat A,int row,int *ncols,int **cols,Scalar **vals) 289289bc588SBarry Smith { 29078b31e54SBarry Smith if (cols) { PETSCFREE(*cols); } 29178b31e54SBarry Smith if (vals) { PETSCFREE(*vals); } 292289bc588SBarry Smith return 0; 293289bc588SBarry Smith } 294289bc588SBarry Smith /* ----------------------------------------------------------------*/ 295c0bbcb79SLois Curfman McInnes static int MatInsert_SeqDense(Mat A,int m,int *indexm,int n, 296e8d4e0b9SBarry Smith int *indexn,Scalar *v,InsertMode addv) 297289bc588SBarry Smith { 298c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 299289bc588SBarry Smith int i,j; 300d6dfbf8fSBarry Smith 301289bc588SBarry Smith if (!mat->roworiented) { 302dbb450caSBarry Smith if (addv == INSERT_VALUES) { 303289bc588SBarry Smith for ( j=0; j<n; j++ ) { 304289bc588SBarry Smith for ( i=0; i<m; i++ ) { 305289bc588SBarry Smith mat->v[indexn[j]*mat->m + indexm[i]] = *v++; 306289bc588SBarry Smith } 307289bc588SBarry Smith } 308289bc588SBarry Smith } 309289bc588SBarry Smith else { 310289bc588SBarry Smith for ( j=0; j<n; j++ ) { 311289bc588SBarry Smith for ( i=0; i<m; i++ ) { 312289bc588SBarry Smith mat->v[indexn[j]*mat->m + indexm[i]] += *v++; 313289bc588SBarry Smith } 314289bc588SBarry Smith } 315289bc588SBarry Smith } 316e8d4e0b9SBarry Smith } 317e8d4e0b9SBarry Smith else { 318dbb450caSBarry Smith if (addv == INSERT_VALUES) { 319e8d4e0b9SBarry Smith for ( i=0; i<m; i++ ) { 320e8d4e0b9SBarry Smith for ( j=0; j<n; j++ ) { 321e8d4e0b9SBarry Smith mat->v[indexn[j]*mat->m + indexm[i]] = *v++; 322e8d4e0b9SBarry Smith } 323e8d4e0b9SBarry Smith } 324e8d4e0b9SBarry Smith } 325289bc588SBarry Smith else { 326289bc588SBarry Smith for ( i=0; i<m; i++ ) { 327289bc588SBarry Smith for ( j=0; j<n; j++ ) { 328289bc588SBarry Smith mat->v[indexn[j]*mat->m + indexm[i]] += *v++; 329289bc588SBarry Smith } 330289bc588SBarry Smith } 331289bc588SBarry Smith } 332e8d4e0b9SBarry Smith } 333289bc588SBarry Smith return 0; 334289bc588SBarry Smith } 335e8d4e0b9SBarry Smith 336289bc588SBarry Smith /* -----------------------------------------------------------------*/ 33755659b69SBarry Smith static int MatCopyPrivate_SeqDense(Mat A,Mat *newmat,int cpvalues) 338289bc588SBarry Smith { 339c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data, *l; 340289bc588SBarry Smith int ierr; 341289bc588SBarry Smith Mat newi; 34248d91487SBarry Smith 343c0bbcb79SLois Curfman McInnes ierr = MatCreateSeqDense(A->comm,mat->m,mat->n,&newi); CHKERRQ(ierr); 344ec8511deSBarry Smith l = (Mat_SeqDense *) newi->data; 34555659b69SBarry Smith if (cpvalues == COPY_VALUES) { 346416022c9SBarry Smith PetscMemcpy(l->v,mat->v,mat->m*mat->n*sizeof(Scalar)); 34755659b69SBarry Smith } 348289bc588SBarry Smith *newmat = newi; 349289bc588SBarry Smith return 0; 350289bc588SBarry Smith } 351289bc588SBarry Smith 352*88e32edaSLois Curfman McInnes #include "sysio.h" 353*88e32edaSLois Curfman McInnes 354*88e32edaSLois Curfman McInnes int MatLoad_SeqDense(Viewer bview,MatType type,Mat *A) 355*88e32edaSLois Curfman McInnes { 356*88e32edaSLois Curfman McInnes Mat_SeqDense *a; 357*88e32edaSLois Curfman McInnes Mat B; 358*88e32edaSLois Curfman McInnes int *scols, i, j, nz, ierr, fd, header[4], size; 359*88e32edaSLois Curfman McInnes int *rowlengths = 0, M, N, *cols; 360*88e32edaSLois Curfman McInnes Scalar *vals, *svals, *v; 361*88e32edaSLois Curfman McInnes PetscObject vobj = (PetscObject) bview; 362*88e32edaSLois Curfman McInnes MPI_Comm comm = vobj->comm; 363*88e32edaSLois Curfman McInnes 364*88e32edaSLois Curfman McInnes MPI_Comm_size(comm,&size); 365*88e32edaSLois Curfman McInnes if (size > 1) SETERRQ(1,"MatLoad_SeqDense: view must have one processor"); 366*88e32edaSLois Curfman McInnes ierr = ViewerFileGetDescriptor_Private(bview,&fd); CHKERRQ(ierr); 367*88e32edaSLois Curfman McInnes ierr = SYRead(fd,header,4,SYINT); CHKERRQ(ierr); 368*88e32edaSLois Curfman McInnes if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqDense:Not matrix object"); 369*88e32edaSLois Curfman McInnes M = header[1]; N = header[2]; nz = header[3]; 370*88e32edaSLois Curfman McInnes 371*88e32edaSLois Curfman McInnes /* read row lengths */ 372*88e32edaSLois Curfman McInnes rowlengths = (int*) PETSCMALLOC( M*sizeof(int) ); CHKPTRQ(rowlengths); 373*88e32edaSLois Curfman McInnes ierr = SYRead(fd,rowlengths,M,SYINT); CHKERRQ(ierr); 374*88e32edaSLois Curfman McInnes 375*88e32edaSLois Curfman McInnes /* create our matrix */ 376*88e32edaSLois Curfman McInnes ierr = MatCreateSeqDense(comm,M,N,A); CHKERRQ(ierr); 377*88e32edaSLois Curfman McInnes B = *A; 378*88e32edaSLois Curfman McInnes a = (Mat_SeqDense *) B->data; 379*88e32edaSLois Curfman McInnes v = a->v; 380*88e32edaSLois Curfman McInnes 381*88e32edaSLois Curfman McInnes /* read column indices and nonzeros */ 382*88e32edaSLois Curfman McInnes cols = scols = (int *) PETSCMALLOC( nz*sizeof(int) ); CHKPTRQ(cols); 383*88e32edaSLois Curfman McInnes ierr = SYRead(fd,cols,nz,SYINT); CHKERRQ(ierr); 384*88e32edaSLois Curfman McInnes vals = svals = (Scalar *) PETSCMALLOC( nz*sizeof(Scalar) ); CHKPTRQ(vals); 385*88e32edaSLois Curfman McInnes ierr = SYRead(fd,vals,nz,SYSCALAR); CHKERRQ(ierr); 386*88e32edaSLois Curfman McInnes 387*88e32edaSLois Curfman McInnes /* insert into matrix */ 388*88e32edaSLois Curfman McInnes for ( i=0; i<M; i++ ) { 389*88e32edaSLois Curfman McInnes for ( j=0; j<rowlengths[i]; j++ ) v[i+M*scols[j]] = svals[j]; 390*88e32edaSLois Curfman McInnes svals += rowlengths[i]; scols += rowlengths[i]; 391*88e32edaSLois Curfman McInnes } 392*88e32edaSLois Curfman McInnes PETSCFREE(vals); PETSCFREE(cols); PETSCFREE(rowlengths); 393*88e32edaSLois Curfman McInnes 394*88e32edaSLois Curfman McInnes ierr = MatAssemblyBegin(B,FINAL_ASSEMBLY); CHKERRQ(ierr); 395*88e32edaSLois Curfman McInnes ierr = MatAssemblyEnd(B,FINAL_ASSEMBLY); CHKERRQ(ierr); 396*88e32edaSLois Curfman McInnes return 0; 397*88e32edaSLois Curfman McInnes } 398*88e32edaSLois Curfman McInnes 399932b0c3eSLois Curfman McInnes #include "pinclude/pviewer.h" 400932b0c3eSLois Curfman McInnes #include "sysio.h" 401932b0c3eSLois Curfman McInnes 402932b0c3eSLois Curfman McInnes static int MatView_SeqDense_ASCII(Mat A,Viewer viewer) 403289bc588SBarry Smith { 404932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *) A->data; 405932b0c3eSLois Curfman McInnes int ierr, i, j, format; 406d636dbe3SBarry Smith FILE *fd; 407932b0c3eSLois Curfman McInnes char *outputname; 408932b0c3eSLois Curfman McInnes Scalar *v; 409932b0c3eSLois Curfman McInnes 410932b0c3eSLois Curfman McInnes ierr = ViewerFileGetPointer_Private(viewer,&fd); CHKERRQ(ierr); 411932b0c3eSLois Curfman McInnes ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr); 412932b0c3eSLois Curfman McInnes ierr = ViewerFileGetFormat_Private(viewer,&format); 413f72585f2SLois Curfman McInnes if (format == FILE_FORMAT_INFO) { 414932b0c3eSLois Curfman McInnes ; /* do nothing for now */ 415f72585f2SLois Curfman McInnes } 416f72585f2SLois Curfman McInnes else { 417932b0c3eSLois Curfman McInnes for ( i=0; i<a->m; i++ ) { 418932b0c3eSLois Curfman McInnes v = a->v + i; 419932b0c3eSLois Curfman McInnes for ( j=0; j<a->n; j++ ) { 420289bc588SBarry Smith #if defined(PETSC_COMPLEX) 421932b0c3eSLois Curfman McInnes fprintf(fd,"%6.4e + %6.4e i ",real(*v),imag(*v)); v += a->m; 422289bc588SBarry Smith #else 423932b0c3eSLois Curfman McInnes fprintf(fd,"%6.4e ",*v); v += a->m; 424289bc588SBarry Smith #endif 425289bc588SBarry Smith } 4268e37dc09SBarry Smith fprintf(fd,"\n"); 427289bc588SBarry Smith } 428da3a660dSBarry Smith } 429932b0c3eSLois Curfman McInnes fflush(fd); 430289bc588SBarry Smith return 0; 431289bc588SBarry Smith } 432289bc588SBarry Smith 433932b0c3eSLois Curfman McInnes static int MatView_SeqDense_Binary(Mat A,Viewer viewer) 434932b0c3eSLois Curfman McInnes { 435932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *) A->data; 436932b0c3eSLois Curfman McInnes int ict, j, n = a->n, m = a->m, i, fd, *col_lens, ierr, nz = m*n; 437932b0c3eSLois Curfman McInnes Scalar *v, *anonz; 438932b0c3eSLois Curfman McInnes 439932b0c3eSLois Curfman McInnes ierr = ViewerFileGetDescriptor_Private(viewer,&fd); CHKERRQ(ierr); 440932b0c3eSLois Curfman McInnes col_lens = (int *) PETSCMALLOC( (4+nz)*sizeof(int) ); CHKPTRQ(col_lens); 441932b0c3eSLois Curfman McInnes col_lens[0] = MAT_COOKIE; 442932b0c3eSLois Curfman McInnes col_lens[1] = m; 443932b0c3eSLois Curfman McInnes col_lens[2] = n; 444932b0c3eSLois Curfman McInnes col_lens[3] = nz; 445932b0c3eSLois Curfman McInnes 446932b0c3eSLois Curfman McInnes /* store lengths of each row and write (including header) to file */ 447932b0c3eSLois Curfman McInnes for ( i=0; i<m; i++ ) col_lens[4+i] = n; 448932b0c3eSLois Curfman McInnes ierr = SYWrite(fd,col_lens,4+m,SYINT,1); CHKERRQ(ierr); 449932b0c3eSLois Curfman McInnes 450932b0c3eSLois Curfman McInnes /* Possibly should write in smaller increments, not whole matrix at once? */ 451932b0c3eSLois Curfman McInnes /* store column indices (zero start index) */ 452932b0c3eSLois Curfman McInnes ict = 0; 453932b0c3eSLois Curfman McInnes for ( i=0; i<m; i++ ) { 454932b0c3eSLois Curfman McInnes for ( j=0; j<n; j++ ) col_lens[ict++] = j; 455932b0c3eSLois Curfman McInnes } 456932b0c3eSLois Curfman McInnes ierr = SYWrite(fd,col_lens,nz,SYINT,0); CHKERRQ(ierr); 457932b0c3eSLois Curfman McInnes PETSCFREE(col_lens); 458932b0c3eSLois Curfman McInnes 459932b0c3eSLois Curfman McInnes /* store nonzero values */ 460932b0c3eSLois Curfman McInnes anonz = (Scalar *) PETSCMALLOC((nz)*sizeof(Scalar)); CHKPTRQ(anonz); 461932b0c3eSLois Curfman McInnes ict = 0; 462932b0c3eSLois Curfman McInnes for ( i=0; i<m; i++ ) { 463932b0c3eSLois Curfman McInnes v = a->v + i; 464932b0c3eSLois Curfman McInnes for ( j=0; j<n; j++ ) { 465932b0c3eSLois Curfman McInnes anonz[ict++] = *v; v += a->m; 466932b0c3eSLois Curfman McInnes } 467932b0c3eSLois Curfman McInnes } 468932b0c3eSLois Curfman McInnes ierr = SYWrite(fd,anonz,nz,SYSCALAR,0); CHKERRQ(ierr); 469932b0c3eSLois Curfman McInnes PETSCFREE(anonz); 470932b0c3eSLois Curfman McInnes return 0; 471932b0c3eSLois Curfman McInnes } 472932b0c3eSLois Curfman McInnes 473932b0c3eSLois Curfman McInnes static int MatView_SeqDense(PetscObject obj,Viewer viewer) 474932b0c3eSLois Curfman McInnes { 475932b0c3eSLois Curfman McInnes Mat A = (Mat) obj; 476932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense*) A->data; 477932b0c3eSLois Curfman McInnes PetscObject vobj = (PetscObject) viewer; 478932b0c3eSLois Curfman McInnes 479932b0c3eSLois Curfman McInnes if (!viewer) { 480932b0c3eSLois Curfman McInnes viewer = STDOUT_VIEWER_SELF; vobj = (PetscObject) viewer; 481932b0c3eSLois Curfman McInnes } 482932b0c3eSLois Curfman McInnes if (vobj->cookie == VIEWER_COOKIE) { 483932b0c3eSLois Curfman McInnes if (vobj->type == MATLAB_VIEWER) { 484932b0c3eSLois Curfman McInnes return ViewerMatlabPutArray_Private(viewer,a->m,a->n,a->v); 485932b0c3eSLois Curfman McInnes } 486932b0c3eSLois Curfman McInnes else if (vobj->type == ASCII_FILE_VIEWER || vobj->type == ASCII_FILES_VIEWER) { 487932b0c3eSLois Curfman McInnes return MatView_SeqDense_ASCII(A,viewer); 488932b0c3eSLois Curfman McInnes } 489932b0c3eSLois Curfman McInnes else if (vobj->type == BINARY_FILE_VIEWER) { 490932b0c3eSLois Curfman McInnes return MatView_SeqDense_Binary(A,viewer); 491932b0c3eSLois Curfman McInnes } 492932b0c3eSLois Curfman McInnes } 493932b0c3eSLois Curfman McInnes return 0; 494932b0c3eSLois Curfman McInnes } 495289bc588SBarry Smith 496ec8511deSBarry Smith static int MatDestroy_SeqDense(PetscObject obj) 497289bc588SBarry Smith { 498289bc588SBarry Smith Mat mat = (Mat) obj; 499ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *) mat->data; 500a5a9c739SBarry Smith #if defined(PETSC_LOG) 501a5a9c739SBarry Smith PLogObjectState(obj,"Rows %d Cols %d",l->m,l->n); 502a5a9c739SBarry Smith #endif 50378b31e54SBarry Smith if (l->pivots) PETSCFREE(l->pivots); 50478b31e54SBarry Smith PETSCFREE(l); 505a5a9c739SBarry Smith PLogObjectDestroy(mat); 5069e25ed09SBarry Smith PETSCHEADERDESTROY(mat); 507289bc588SBarry Smith return 0; 508289bc588SBarry Smith } 509289bc588SBarry Smith 510c0bbcb79SLois Curfman McInnes static int MatTranspose_SeqDense(Mat A,Mat *matout) 511289bc588SBarry Smith { 512c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 513d3e5ee88SLois Curfman McInnes int k, j, m, n; 514d3e5ee88SLois Curfman McInnes Scalar *v, tmp; 51548b35521SBarry Smith 516d3e5ee88SLois Curfman McInnes v = mat->v; m = mat->m; n = mat->n; 51748b35521SBarry Smith if (!matout) { /* in place transpose */ 518d9f96c7cSLois Curfman McInnes if (m != n) SETERRQ(1,"MatTranspose_SeqDense:Supports square matrix only in-place"); 519d3e5ee88SLois Curfman McInnes for ( j=0; j<m; j++ ) { 520289bc588SBarry Smith for ( k=0; k<j; k++ ) { 521d3e5ee88SLois Curfman McInnes tmp = v[j + k*n]; 522d3e5ee88SLois Curfman McInnes v[j + k*n] = v[k + j*n]; 523d3e5ee88SLois Curfman McInnes v[k + j*n] = tmp; 524289bc588SBarry Smith } 525289bc588SBarry Smith } 52648b35521SBarry Smith } 527d3e5ee88SLois Curfman McInnes else { /* out-of-place transpose */ 528d3e5ee88SLois Curfman McInnes int ierr; 529d3e5ee88SLois Curfman McInnes Mat tmat; 530ec8511deSBarry Smith Mat_SeqDense *tmatd; 531d3e5ee88SLois Curfman McInnes Scalar *v2; 532c0bbcb79SLois Curfman McInnes ierr = MatCreateSeqDense(A->comm,mat->n,mat->m,&tmat); CHKERRQ(ierr); 533ec8511deSBarry Smith tmatd = (Mat_SeqDense *) tmat->data; 5340de55854SLois Curfman McInnes v = mat->v; v2 = tmatd->v; 535d3e5ee88SLois Curfman McInnes for ( j=0; j<n; j++ ) { 5360de55854SLois Curfman McInnes for ( k=0; k<m; k++ ) v2[j + k*n] = v[k + j*m]; 537d3e5ee88SLois Curfman McInnes } 538d3e5ee88SLois Curfman McInnes ierr = MatAssemblyBegin(tmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 539d3e5ee88SLois Curfman McInnes ierr = MatAssemblyEnd(tmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 540d3e5ee88SLois Curfman McInnes *matout = tmat; 54148b35521SBarry Smith } 542289bc588SBarry Smith return 0; 543289bc588SBarry Smith } 544289bc588SBarry Smith 545c0bbcb79SLois Curfman McInnes static int MatEqual_SeqDense(Mat A1,Mat A2) 546289bc588SBarry Smith { 547c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *) A1->data; 548c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *) A2->data; 549289bc588SBarry Smith int i; 550289bc588SBarry Smith Scalar *v1 = mat1->v, *v2 = mat2->v; 551289bc588SBarry Smith if (mat1->m != mat2->m) return 0; 552289bc588SBarry Smith if (mat1->n != mat2->n) return 0; 553289bc588SBarry Smith for ( i=0; i<mat1->m*mat1->n; i++ ) { 554289bc588SBarry Smith if (*v1 != *v2) return 0; 555289bc588SBarry Smith v1++; v2++; 556289bc588SBarry Smith } 557289bc588SBarry Smith return 1; 558289bc588SBarry Smith } 559289bc588SBarry Smith 560c0bbcb79SLois Curfman McInnes static int MatGetDiagonal_SeqDense(Mat A,Vec v) 561289bc588SBarry Smith { 562c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 5636abc6512SBarry Smith int i, n; 5646abc6512SBarry Smith Scalar *x; 565289bc588SBarry Smith VecGetArray(v,&x); VecGetSize(v,&n); 566ec8511deSBarry Smith if (n != mat->m) SETERRQ(1,"MatGetDiagonal_SeqDense:Nonconforming mat and vec"); 567289bc588SBarry Smith for ( i=0; i<mat->m; i++ ) { 568289bc588SBarry Smith x[i] = mat->v[i*mat->m + i]; 569289bc588SBarry Smith } 570289bc588SBarry Smith return 0; 571289bc588SBarry Smith } 572289bc588SBarry Smith 573c0bbcb79SLois Curfman McInnes static int MatScale_SeqDense(Mat A,Vec ll,Vec rr) 574289bc588SBarry Smith { 575c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 576da3a660dSBarry Smith Scalar *l,*r,x,*v; 577da3a660dSBarry Smith int i,j,m = mat->m, n = mat->n; 57855659b69SBarry Smith 57928988994SBarry Smith if (ll) { 580da3a660dSBarry Smith VecGetArray(ll,&l); VecGetSize(ll,&m); 581ec8511deSBarry Smith if (m != mat->m) SETERRQ(1,"MatScale_SeqDense:Left scaling vec wrong size"); 58255659b69SBarry Smith PLogFlops(n*m); 583da3a660dSBarry Smith for ( i=0; i<m; i++ ) { 584da3a660dSBarry Smith x = l[i]; 585da3a660dSBarry Smith v = mat->v + i; 586da3a660dSBarry Smith for ( j=0; j<n; j++ ) { (*v) *= x; v+= m;} 587da3a660dSBarry Smith } 588da3a660dSBarry Smith } 58928988994SBarry Smith if (rr) { 590da3a660dSBarry Smith VecGetArray(rr,&r); VecGetSize(rr,&n); 591ec8511deSBarry Smith if (n != mat->n) SETERRQ(1,"MatScale_SeqDense:Right scaling vec wrong size"); 59255659b69SBarry Smith PLogFlops(n*m); 593da3a660dSBarry Smith for ( i=0; i<n; i++ ) { 594da3a660dSBarry Smith x = r[i]; 595da3a660dSBarry Smith v = mat->v + i*m; 596da3a660dSBarry Smith for ( j=0; j<m; j++ ) { (*v++) *= x;} 597da3a660dSBarry Smith } 598da3a660dSBarry Smith } 599289bc588SBarry Smith return 0; 600289bc588SBarry Smith } 601289bc588SBarry Smith 602c0bbcb79SLois Curfman McInnes static int MatNorm_SeqDense(Mat A,MatNormType type,double *norm) 603289bc588SBarry Smith { 604c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 605289bc588SBarry Smith Scalar *v = mat->v; 606289bc588SBarry Smith double sum = 0.0; 607289bc588SBarry Smith int i, j; 60855659b69SBarry Smith 609289bc588SBarry Smith if (type == NORM_FROBENIUS) { 610289bc588SBarry Smith for (i=0; i<mat->n*mat->m; i++ ) { 611289bc588SBarry Smith #if defined(PETSC_COMPLEX) 612289bc588SBarry Smith sum += real(conj(*v)*(*v)); v++; 613289bc588SBarry Smith #else 614289bc588SBarry Smith sum += (*v)*(*v); v++; 615289bc588SBarry Smith #endif 616289bc588SBarry Smith } 617289bc588SBarry Smith *norm = sqrt(sum); 61855659b69SBarry Smith PLogFlops(2*mat->n*mat->m); 619289bc588SBarry Smith } 620289bc588SBarry Smith else if (type == NORM_1) { 621289bc588SBarry Smith *norm = 0.0; 622289bc588SBarry Smith for ( j=0; j<mat->n; j++ ) { 623289bc588SBarry Smith sum = 0.0; 624289bc588SBarry Smith for ( i=0; i<mat->m; i++ ) { 625289bc588SBarry Smith #if defined(PETSC_COMPLEX) 626289bc588SBarry Smith sum += abs(*v++); 627289bc588SBarry Smith #else 628289bc588SBarry Smith sum += fabs(*v++); 629289bc588SBarry Smith #endif 630289bc588SBarry Smith } 631289bc588SBarry Smith if (sum > *norm) *norm = sum; 632289bc588SBarry Smith } 63355659b69SBarry Smith PLogFlops(mat->n*mat->m); 634289bc588SBarry Smith } 635289bc588SBarry Smith else if (type == NORM_INFINITY) { 636289bc588SBarry Smith *norm = 0.0; 637289bc588SBarry Smith for ( j=0; j<mat->m; j++ ) { 638289bc588SBarry Smith v = mat->v + j; 639289bc588SBarry Smith sum = 0.0; 640289bc588SBarry Smith for ( i=0; i<mat->n; i++ ) { 641289bc588SBarry Smith #if defined(PETSC_COMPLEX) 642289bc588SBarry Smith sum += abs(*v); v += mat->m; 643289bc588SBarry Smith #else 644289bc588SBarry Smith sum += fabs(*v); v += mat->m; 645289bc588SBarry Smith #endif 646289bc588SBarry Smith } 647289bc588SBarry Smith if (sum > *norm) *norm = sum; 648289bc588SBarry Smith } 64955659b69SBarry Smith PLogFlops(mat->n*mat->m); 650289bc588SBarry Smith } 651289bc588SBarry Smith else { 65248d91487SBarry Smith SETERRQ(1,"MatNorm_SeqDense:No two norm"); 653289bc588SBarry Smith } 654289bc588SBarry Smith return 0; 655289bc588SBarry Smith } 656289bc588SBarry Smith 657c0bbcb79SLois Curfman McInnes static int MatSetOption_SeqDense(Mat A,MatOption op) 658289bc588SBarry Smith { 659c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *) A->data; 660289bc588SBarry Smith if (op == ROW_ORIENTED) aij->roworiented = 1; 661289bc588SBarry Smith else if (op == COLUMN_ORIENTED) aij->roworiented = 0; 662c0bbcb79SLois Curfman McInnes else if (op == ROWS_SORTED || 663*88e32edaSLois Curfman McInnes op == COLUMNS_SORTED || 664c0bbcb79SLois Curfman McInnes op == SYMMETRIC_MATRIX || 665c0bbcb79SLois Curfman McInnes op == STRUCTURALLY_SYMMETRIC_MATRIX || 666c0bbcb79SLois Curfman McInnes op == NO_NEW_NONZERO_LOCATIONS || 667c0bbcb79SLois Curfman McInnes op == YES_NEW_NONZERO_LOCATIONS || 668c0bbcb79SLois Curfman McInnes op == NO_NEW_DIAGONALS || 669c0bbcb79SLois Curfman McInnes op == YES_NEW_DIAGONALS) 670c0bbcb79SLois Curfman McInnes PLogInfo((PetscObject)A,"Info:MatSetOption_SeqDense:Option ignored\n"); 671c0bbcb79SLois Curfman McInnes else 6724d39ef84SLois Curfman McInnes {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqDense:unknown option");} 673289bc588SBarry Smith return 0; 674289bc588SBarry Smith } 675289bc588SBarry Smith 676ec8511deSBarry Smith static int MatZeroEntries_SeqDense(Mat A) 6776f0a148fSBarry Smith { 678ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *) A->data; 679416022c9SBarry Smith PetscZero(l->v,l->m*l->n*sizeof(Scalar)); 6806f0a148fSBarry Smith return 0; 6816f0a148fSBarry Smith } 6826f0a148fSBarry Smith 683ec8511deSBarry Smith static int MatZeroRows_SeqDense(Mat A,IS is,Scalar *diag) 6846f0a148fSBarry Smith { 685ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *) A->data; 6866abc6512SBarry Smith int n = l->n, i, j,ierr,N, *rows; 6876f0a148fSBarry Smith Scalar *slot; 68855659b69SBarry Smith 68978b31e54SBarry Smith ierr = ISGetLocalSize(is,&N); CHKERRQ(ierr); 69078b31e54SBarry Smith ierr = ISGetIndices(is,&rows); CHKERRQ(ierr); 6916f0a148fSBarry Smith for ( i=0; i<N; i++ ) { 6926f0a148fSBarry Smith slot = l->v + rows[i]; 6936f0a148fSBarry Smith for ( j=0; j<n; j++ ) { *slot = 0.0; slot += n;} 6946f0a148fSBarry Smith } 6956f0a148fSBarry Smith if (diag) { 6966f0a148fSBarry Smith for ( i=0; i<N; i++ ) { 6976f0a148fSBarry Smith slot = l->v + (n+1)*rows[i]; 698260925b8SBarry Smith *slot = *diag; 6996f0a148fSBarry Smith } 7006f0a148fSBarry Smith } 701260925b8SBarry Smith ISRestoreIndices(is,&rows); 7026f0a148fSBarry Smith return 0; 7036f0a148fSBarry Smith } 704557bce09SLois Curfman McInnes 705c0bbcb79SLois Curfman McInnes static int MatGetSize_SeqDense(Mat A,int *m,int *n) 706557bce09SLois Curfman McInnes { 707c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 708557bce09SLois Curfman McInnes *m = mat->m; *n = mat->n; 709557bce09SLois Curfman McInnes return 0; 710557bce09SLois Curfman McInnes } 711557bce09SLois Curfman McInnes 712c0bbcb79SLois Curfman McInnes static int MatGetOwnershipRange_SeqDense(Mat A,int *m,int *n) 713d3e5ee88SLois Curfman McInnes { 714c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 715d3e5ee88SLois Curfman McInnes *m = 0; *n = mat->m; 716d3e5ee88SLois Curfman McInnes return 0; 717d3e5ee88SLois Curfman McInnes } 718d3e5ee88SLois Curfman McInnes 719c0bbcb79SLois Curfman McInnes static int MatGetArray_SeqDense(Mat A,Scalar **array) 72064e87e97SBarry Smith { 721c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 72264e87e97SBarry Smith *array = mat->v; 72364e87e97SBarry Smith return 0; 72464e87e97SBarry Smith } 7250754003eSLois Curfman McInnes 7260754003eSLois Curfman McInnes 727c0bbcb79SLois Curfman McInnes static int MatGetSubMatrixInPlace_SeqDense(Mat A,IS isrow,IS iscol) 7280754003eSLois Curfman McInnes { 729ec8511deSBarry Smith SETERRQ(1,"MatGetSubMatrixInPlace_SeqDense:not done"); 7300754003eSLois Curfman McInnes } 7310754003eSLois Curfman McInnes 732c0bbcb79SLois Curfman McInnes static int MatGetSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,Mat *submat) 7330754003eSLois Curfman McInnes { 734c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 7350754003eSLois Curfman McInnes int nznew, *smap, i, j, ierr, oldcols = mat->n; 736160018dcSBarry Smith int *irow, *icol, nrows, ncols, *cwork; 7370754003eSLois Curfman McInnes Scalar *vwork, *val; 7380754003eSLois Curfman McInnes Mat newmat; 7390754003eSLois Curfman McInnes 74078b31e54SBarry Smith ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 74178b31e54SBarry Smith ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 74278b31e54SBarry Smith ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 74378b31e54SBarry Smith ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 7440754003eSLois Curfman McInnes 74578b31e54SBarry Smith smap = (int *) PETSCMALLOC(oldcols*sizeof(int)); CHKPTRQ(smap); 74678b31e54SBarry Smith cwork = (int *) PETSCMALLOC(ncols*sizeof(int)); CHKPTRQ(cwork); 74778b31e54SBarry Smith vwork = (Scalar *) PETSCMALLOC(ncols*sizeof(Scalar)); CHKPTRQ(vwork); 748416022c9SBarry Smith PetscZero((char*)smap,oldcols*sizeof(int)); 7490754003eSLois Curfman McInnes for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 7500754003eSLois Curfman McInnes 7510754003eSLois Curfman McInnes /* Create and fill new matrix */ 752c0bbcb79SLois Curfman McInnes ierr = MatCreateSeqDense(A->comm,nrows,ncols,&newmat);CHKERRQ(ierr); 7530754003eSLois Curfman McInnes for (i=0; i<nrows; i++) { 7540754003eSLois Curfman McInnes nznew = 0; 7550754003eSLois Curfman McInnes val = mat->v + irow[i]; 7560754003eSLois Curfman McInnes for (j=0; j<oldcols; j++) { 7570754003eSLois Curfman McInnes if (smap[j]) { 7580754003eSLois Curfman McInnes cwork[nznew] = smap[j] - 1; 7590754003eSLois Curfman McInnes vwork[nznew++] = val[j * mat->m]; 7600754003eSLois Curfman McInnes } 7610754003eSLois Curfman McInnes } 762dbb450caSBarry Smith ierr = MatSetValues(newmat,1,&i,nznew,cwork,vwork,INSERT_VALUES); 76378b31e54SBarry Smith CHKERRQ(ierr); 7640754003eSLois Curfman McInnes } 76578b31e54SBarry Smith ierr = MatAssemblyBegin(newmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 76678b31e54SBarry Smith ierr = MatAssemblyEnd(newmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 7670754003eSLois Curfman McInnes 7680754003eSLois Curfman McInnes /* Free work space */ 76978b31e54SBarry Smith PETSCFREE(smap); PETSCFREE(cwork); PETSCFREE(vwork); 77078b31e54SBarry Smith ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 77178b31e54SBarry Smith ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 7720754003eSLois Curfman McInnes *submat = newmat; 7730754003eSLois Curfman McInnes return 0; 7740754003eSLois Curfman McInnes } 7750754003eSLois Curfman McInnes 776289bc588SBarry Smith /* -------------------------------------------------------------------*/ 777ec8511deSBarry Smith static struct _MatOps MatOps = {MatInsert_SeqDense, 778ec8511deSBarry Smith MatGetRow_SeqDense, MatRestoreRow_SeqDense, 779ec8511deSBarry Smith MatMult_SeqDense, MatMultAdd_SeqDense, 780ec8511deSBarry Smith MatMultTrans_SeqDense, MatMultTransAdd_SeqDense, 781ec8511deSBarry Smith MatSolve_SeqDense,MatSolveAdd_SeqDense, 782ec8511deSBarry Smith MatSolveTrans_SeqDense,MatSolveTransAdd_SeqDense, 783ec8511deSBarry Smith MatLUFactor_SeqDense,MatCholeskyFactor_SeqDense, 784ec8511deSBarry Smith MatRelax_SeqDense, 785ec8511deSBarry Smith MatTranspose_SeqDense, 786ec8511deSBarry Smith MatGetInfo_SeqDense,MatEqual_SeqDense, 787ec8511deSBarry Smith MatGetDiagonal_SeqDense,MatScale_SeqDense,MatNorm_SeqDense, 788289bc588SBarry Smith 0,0, 789ec8511deSBarry Smith 0, MatSetOption_SeqDense,MatZeroEntries_SeqDense,MatZeroRows_SeqDense,0, 790ec8511deSBarry Smith MatLUFactorSymbolic_SeqDense,MatLUFactorNumeric_SeqDense, 791ec8511deSBarry Smith MatCholeskyFactorSymbolic_SeqDense,MatCholeskyFactorNumeric_SeqDense, 792ec8511deSBarry Smith MatGetSize_SeqDense,MatGetSize_SeqDense,MatGetOwnershipRange_SeqDense, 793ec8511deSBarry Smith 0,0,MatGetArray_SeqDense,0,0, 794ec8511deSBarry Smith MatGetSubMatrix_SeqDense,MatGetSubMatrixInPlace_SeqDense, 7951987afe7SBarry Smith MatCopyPrivate_SeqDense,0,0,0,0, 7961987afe7SBarry Smith MatAXPY_SeqDense}; 7970754003eSLois Curfman McInnes 7984b828684SBarry Smith /*@C 799fafbff53SBarry Smith MatCreateSeqDense - Creates a sequential dense matrix that 800d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 801d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 802289bc588SBarry Smith 80320563c6bSBarry Smith Input Parameters: 8040c775827SLois Curfman McInnes . comm - MPI communicator, set to MPI_COMM_SELF 8050c775827SLois Curfman McInnes . m - number of rows 8060c775827SLois Curfman McInnes . n - number of column 80720563c6bSBarry Smith 80820563c6bSBarry Smith Output Parameter: 8090c775827SLois Curfman McInnes . newmat - the matrix 81020563c6bSBarry Smith 811dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS 812d65003e9SLois Curfman McInnes 813dbd7a890SLois Curfman McInnes .seealso: MatCreate(), MatSetValues() 81420563c6bSBarry Smith @*/ 815fafbff53SBarry Smith int MatCreateSeqDense(MPI_Comm comm,int m,int n,Mat *newmat) 816289bc588SBarry Smith { 817ec8511deSBarry Smith int size = sizeof(Mat_SeqDense) + m*n*sizeof(Scalar); 818289bc588SBarry Smith Mat mat; 819ec8511deSBarry Smith Mat_SeqDense *l; 82055659b69SBarry Smith 821289bc588SBarry Smith *newmat = 0; 822ec8511deSBarry Smith PETSCHEADERCREATE(mat,_Mat,MAT_COOKIE,MATSEQDENSE,comm); 823a5a9c739SBarry Smith PLogObjectCreate(mat); 824ec8511deSBarry Smith l = (Mat_SeqDense *) PETSCMALLOC(size); CHKPTRQ(l); 825416022c9SBarry Smith PetscMemcpy(&mat->ops,&MatOps,sizeof(struct _MatOps)); 826ec8511deSBarry Smith mat->destroy = MatDestroy_SeqDense; 827ec8511deSBarry Smith mat->view = MatView_SeqDense; 828289bc588SBarry Smith mat->data = (void *) l; 829289bc588SBarry Smith mat->factor = 0; 830752f5567SLois Curfman McInnes PLogObjectMemory(mat,sizeof(struct _Mat) + size); 831d6dfbf8fSBarry Smith 832289bc588SBarry Smith l->m = m; 833289bc588SBarry Smith l->n = n; 834289bc588SBarry Smith l->v = (Scalar *) (l + 1); 835289bc588SBarry Smith l->pivots = 0; 836289bc588SBarry Smith l->roworiented = 1; 837d6dfbf8fSBarry Smith 838416022c9SBarry Smith PetscZero(l->v,m*n*sizeof(Scalar)); 839289bc588SBarry Smith *newmat = mat; 840289bc588SBarry Smith return 0; 841289bc588SBarry Smith } 842289bc588SBarry Smith 843c0bbcb79SLois Curfman McInnes int MatCreate_SeqDense(Mat A,Mat *newmat) 844289bc588SBarry Smith { 845c0bbcb79SLois Curfman McInnes Mat_SeqDense *m = (Mat_SeqDense *) A->data; 846c0bbcb79SLois Curfman McInnes return MatCreateSeqDense(A->comm,m->m,m->n,newmat); 847289bc588SBarry Smith } 848