1cb512458SBarry Smith #ifndef lint 2*23242f5aSBarry Smith static char vcid[] = "$Id: dense.c,v 1.29 1995/04/28 15:06:38 curfman Exp bsmith $"; 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 } 5846fc4a8fSLois Curfman McInnes static int MatCholeskyFactorSymbolic_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 } 6446fc4a8fSLois Curfman McInnes static int MatCholeskyFactorNumeric_Dense(Mat matin,Mat *fact) 65289bc588SBarry Smith { 6620563c6bSBarry Smith return MatCholeskyFactor(*fact,0); 67289bc588SBarry Smith } 6846fc4a8fSLois Curfman McInnes static int MatCholeskyFactor_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; 344*23242f5aSBarry Smith PetscObject vobj = (PetscObject) ptr; 345da3a660dSBarry Smith 346*23242f5aSBarry Smith if (ptr == 0) { 347*23242f5aSBarry Smith ptr = STDOUT_VIEWER; vobj = (PetscObject) ptr; 348*23242f5aSBarry Smith } 349*23242f5aSBarry Smith if (vobj->cookie == VIEWER_COOKIE && vobj->type == MATLAB_VIEWER) { 3506f75cfa4SBarry Smith return ViewerMatlabPutArray_Private(ptr,mat->m,mat->n,mat->v); 351da3a660dSBarry Smith } 352da3a660dSBarry Smith else { 3534a0ce102SLois Curfman McInnes FILE *fd = ViewerFileGetPointer_Private(ptr); 354289bc588SBarry Smith for ( i=0; i<mat->m; i++ ) { 355289bc588SBarry Smith v = mat->v + i; 356289bc588SBarry Smith for ( j=0; j<mat->n; j++ ) { 357289bc588SBarry Smith #if defined(PETSC_COMPLEX) 3588e37dc09SBarry Smith fprintf(fd,"%6.4e + %6.4e i ",real(*v),imag(*v)); v += mat->m; 359289bc588SBarry Smith #else 3608e37dc09SBarry Smith fprintf(fd,"%6.4e ",*v); v += mat->m; 361289bc588SBarry Smith #endif 362289bc588SBarry Smith } 3638e37dc09SBarry Smith fprintf(fd,"\n"); 364289bc588SBarry Smith } 365da3a660dSBarry Smith } 366289bc588SBarry Smith return 0; 367289bc588SBarry Smith } 368289bc588SBarry Smith 369289bc588SBarry Smith 37044a69424SLois Curfman McInnes static int MatDestroy_Dense(PetscObject obj) 371289bc588SBarry Smith { 372289bc588SBarry Smith Mat mat = (Mat) obj; 37344a69424SLois Curfman McInnes Mat_Dense *l = (Mat_Dense *) mat->data; 374a5a9c739SBarry Smith #if defined(PETSC_LOG) 375a5a9c739SBarry Smith PLogObjectState(obj,"Rows %d Cols %d",l->m,l->n); 376a5a9c739SBarry Smith #endif 377289bc588SBarry Smith if (l->pivots) FREE(l->pivots); 378289bc588SBarry Smith FREE(l); 379a5a9c739SBarry Smith PLogObjectDestroy(mat); 3809e25ed09SBarry Smith PETSCHEADERDESTROY(mat); 381289bc588SBarry Smith return 0; 382289bc588SBarry Smith } 383289bc588SBarry Smith 38444a69424SLois Curfman McInnes static int MatTrans_Dense(Mat matin) 385289bc588SBarry Smith { 38644a69424SLois Curfman McInnes Mat_Dense *mat = (Mat_Dense *) matin->data; 387289bc588SBarry Smith int k,j; 388289bc588SBarry Smith Scalar *v = mat->v, tmp; 389289bc588SBarry Smith if (mat->m != mat->n) { 390289bc588SBarry Smith SETERR(1,"Cannot transpose rectangular dense matrix"); 391289bc588SBarry Smith } 392289bc588SBarry Smith for ( j=0; j<mat->m; j++ ) { 393289bc588SBarry Smith for ( k=0; k<j; k++ ) { 394289bc588SBarry Smith tmp = v[j + k*mat->n]; 395289bc588SBarry Smith v[j + k*mat->n] = v[k + j*mat->n]; 396289bc588SBarry Smith v[k + j*mat->n] = tmp; 397289bc588SBarry Smith } 398289bc588SBarry Smith } 399289bc588SBarry Smith return 0; 400289bc588SBarry Smith } 401289bc588SBarry Smith 40244a69424SLois Curfman McInnes static int MatEqual_Dense(Mat matin1,Mat matin2) 403289bc588SBarry Smith { 40444a69424SLois Curfman McInnes Mat_Dense *mat1 = (Mat_Dense *) matin1->data; 40544a69424SLois Curfman McInnes Mat_Dense *mat2 = (Mat_Dense *) matin2->data; 406289bc588SBarry Smith int i; 407289bc588SBarry Smith Scalar *v1 = mat1->v, *v2 = mat2->v; 408289bc588SBarry Smith if (mat1->m != mat2->m) return 0; 409289bc588SBarry Smith if (mat1->n != mat2->n) return 0; 410289bc588SBarry Smith for ( i=0; i<mat1->m*mat1->n; i++ ) { 411289bc588SBarry Smith if (*v1 != *v2) return 0; 412289bc588SBarry Smith v1++; v2++; 413289bc588SBarry Smith } 414289bc588SBarry Smith return 1; 415289bc588SBarry Smith } 416289bc588SBarry Smith 41746fc4a8fSLois Curfman McInnes static int MatGetDiagonal_Dense(Mat matin,Vec v) 418289bc588SBarry Smith { 41944a69424SLois Curfman McInnes Mat_Dense *mat = (Mat_Dense *) matin->data; 4206abc6512SBarry Smith int i, n; 4216abc6512SBarry Smith Scalar *x; 422289bc588SBarry Smith CHKTYPE(v,SEQVECTOR); 423289bc588SBarry Smith VecGetArray(v,&x); VecGetSize(v,&n); 424289bc588SBarry Smith if (n != mat->m) SETERR(1,"Nonconforming matrix and vector"); 425289bc588SBarry Smith for ( i=0; i<mat->m; i++ ) { 426289bc588SBarry Smith x[i] = mat->v[i*mat->m + i]; 427289bc588SBarry Smith } 428289bc588SBarry Smith return 0; 429289bc588SBarry Smith } 430289bc588SBarry Smith 43144a69424SLois Curfman McInnes static int MatScale_Dense(Mat matin,Vec ll,Vec rr) 432289bc588SBarry Smith { 43344a69424SLois Curfman McInnes Mat_Dense *mat = (Mat_Dense *) matin->data; 434da3a660dSBarry Smith Scalar *l,*r,x,*v; 435da3a660dSBarry Smith int i,j,m = mat->m, n = mat->n; 43628988994SBarry Smith if (ll) { 437da3a660dSBarry Smith VecGetArray(ll,&l); VecGetSize(ll,&m); 438da3a660dSBarry Smith if (m != mat->m) SETERR(1,"Left scaling vector wrong length"); 439da3a660dSBarry Smith for ( i=0; i<m; i++ ) { 440da3a660dSBarry Smith x = l[i]; 441da3a660dSBarry Smith v = mat->v + i; 442da3a660dSBarry Smith for ( j=0; j<n; j++ ) { (*v) *= x; v+= m;} 443da3a660dSBarry Smith } 444da3a660dSBarry Smith } 44528988994SBarry Smith if (rr) { 446da3a660dSBarry Smith VecGetArray(rr,&r); VecGetSize(rr,&n); 447da3a660dSBarry Smith if (n != mat->n) SETERR(1,"Right scaling vector wrong length"); 448da3a660dSBarry Smith for ( i=0; i<n; i++ ) { 449da3a660dSBarry Smith x = r[i]; 450da3a660dSBarry Smith v = mat->v + i*m; 451da3a660dSBarry Smith for ( j=0; j<m; j++ ) { (*v++) *= x;} 452da3a660dSBarry Smith } 453da3a660dSBarry Smith } 454289bc588SBarry Smith return 0; 455289bc588SBarry Smith } 456289bc588SBarry Smith 457da3a660dSBarry Smith 45844a69424SLois Curfman McInnes static int MatNorm_Dense(Mat matin,int type,double *norm) 459289bc588SBarry Smith { 46044a69424SLois Curfman McInnes Mat_Dense *mat = (Mat_Dense *) matin->data; 461289bc588SBarry Smith Scalar *v = mat->v; 462289bc588SBarry Smith double sum = 0.0; 463289bc588SBarry Smith int i, j; 464289bc588SBarry Smith if (type == NORM_FROBENIUS) { 465289bc588SBarry Smith for (i=0; i<mat->n*mat->m; i++ ) { 466289bc588SBarry Smith #if defined(PETSC_COMPLEX) 467289bc588SBarry Smith sum += real(conj(*v)*(*v)); v++; 468289bc588SBarry Smith #else 469289bc588SBarry Smith sum += (*v)*(*v); v++; 470289bc588SBarry Smith #endif 471289bc588SBarry Smith } 472289bc588SBarry Smith *norm = sqrt(sum); 473289bc588SBarry Smith } 474289bc588SBarry Smith else if (type == NORM_1) { 475289bc588SBarry Smith *norm = 0.0; 476289bc588SBarry Smith for ( j=0; j<mat->n; j++ ) { 477289bc588SBarry Smith sum = 0.0; 478289bc588SBarry Smith for ( i=0; i<mat->m; i++ ) { 479289bc588SBarry Smith #if defined(PETSC_COMPLEX) 480289bc588SBarry Smith sum += abs(*v++); 481289bc588SBarry Smith #else 482289bc588SBarry Smith sum += fabs(*v++); 483289bc588SBarry Smith #endif 484289bc588SBarry Smith } 485289bc588SBarry Smith if (sum > *norm) *norm = sum; 486289bc588SBarry Smith } 487289bc588SBarry Smith } 488289bc588SBarry Smith else if (type == NORM_INFINITY) { 489289bc588SBarry Smith *norm = 0.0; 490289bc588SBarry Smith for ( j=0; j<mat->m; j++ ) { 491289bc588SBarry Smith v = mat->v + j; 492289bc588SBarry Smith sum = 0.0; 493289bc588SBarry Smith for ( i=0; i<mat->n; i++ ) { 494289bc588SBarry Smith #if defined(PETSC_COMPLEX) 495289bc588SBarry Smith sum += abs(*v); v += mat->m; 496289bc588SBarry Smith #else 497289bc588SBarry Smith sum += fabs(*v); v += mat->m; 498289bc588SBarry Smith #endif 499289bc588SBarry Smith } 500289bc588SBarry Smith if (sum > *norm) *norm = sum; 501289bc588SBarry Smith } 502289bc588SBarry Smith } 503289bc588SBarry Smith else { 504289bc588SBarry Smith SETERR(1,"No support for the two norm yet"); 505289bc588SBarry Smith } 506289bc588SBarry Smith return 0; 507289bc588SBarry Smith } 508289bc588SBarry Smith 509681d1451SLois Curfman McInnes static int MatSetOption_Dense(Mat aijin,int op) 510289bc588SBarry Smith { 51144a69424SLois Curfman McInnes Mat_Dense *aij = (Mat_Dense *) aijin->data; 512289bc588SBarry Smith if (op == ROW_ORIENTED) aij->roworiented = 1; 513289bc588SBarry Smith else if (op == COLUMN_ORIENTED) aij->roworiented = 0; 514289bc588SBarry Smith /* doesn't care about sorted rows or columns */ 515289bc588SBarry Smith return 0; 516289bc588SBarry Smith } 517289bc588SBarry Smith 51844a69424SLois Curfman McInnes static int MatZero_Dense(Mat A) 5196f0a148fSBarry Smith { 52044a69424SLois Curfman McInnes Mat_Dense *l = (Mat_Dense *) A->data; 5216f0a148fSBarry Smith MEMSET(l->v,0,l->m*l->n*sizeof(Scalar)); 5226f0a148fSBarry Smith return 0; 5236f0a148fSBarry Smith } 5246f0a148fSBarry Smith 52544a69424SLois Curfman McInnes static int MatZeroRows_Dense(Mat A,IS is,Scalar *diag) 5266f0a148fSBarry Smith { 52744a69424SLois Curfman McInnes Mat_Dense *l = (Mat_Dense *) A->data; 5286abc6512SBarry Smith int n = l->n, i, j,ierr,N, *rows; 5296f0a148fSBarry Smith Scalar *slot; 530260925b8SBarry Smith ierr = ISGetLocalSize(is,&N); CHKERR(ierr); 531260925b8SBarry Smith ierr = ISGetIndices(is,&rows); CHKERR(ierr); 5326f0a148fSBarry Smith for ( i=0; i<N; i++ ) { 5336f0a148fSBarry Smith slot = l->v + rows[i]; 5346f0a148fSBarry Smith for ( j=0; j<n; j++ ) { *slot = 0.0; slot += n;} 5356f0a148fSBarry Smith } 5366f0a148fSBarry Smith if (diag) { 5376f0a148fSBarry Smith for ( i=0; i<N; i++ ) { 5386f0a148fSBarry Smith slot = l->v + (n+1)*rows[i]; 539260925b8SBarry Smith *slot = *diag; 5406f0a148fSBarry Smith } 5416f0a148fSBarry Smith } 542260925b8SBarry Smith ISRestoreIndices(is,&rows); 5436f0a148fSBarry Smith return 0; 5446f0a148fSBarry Smith } 545557bce09SLois Curfman McInnes 546fa9ec3f1SLois Curfman McInnes static int MatGetSize_Dense(Mat matin,int *m,int *n) 547557bce09SLois Curfman McInnes { 54844a69424SLois Curfman McInnes Mat_Dense *mat = (Mat_Dense *) matin->data; 549557bce09SLois Curfman McInnes *m = mat->m; *n = mat->n; 550557bce09SLois Curfman McInnes return 0; 551557bce09SLois Curfman McInnes } 552557bce09SLois Curfman McInnes 55344a69424SLois Curfman McInnes static int MatGetArray_Dense(Mat matin,Scalar **array) 55464e87e97SBarry Smith { 55544a69424SLois Curfman McInnes Mat_Dense *mat = (Mat_Dense *) matin->data; 55664e87e97SBarry Smith *array = mat->v; 55764e87e97SBarry Smith return 0; 55864e87e97SBarry Smith } 5590754003eSLois Curfman McInnes 5600754003eSLois Curfman McInnes 5610754003eSLois Curfman McInnes static int MatGetSubMatrixInPlace_Dense(Mat matin,IS isrow,IS iscol) 5620754003eSLois Curfman McInnes { 5630754003eSLois Curfman McInnes SETERR(1,"MatGetSubMatrixInPlace_Dense not yet done."); 5640754003eSLois Curfman McInnes } 5650754003eSLois Curfman McInnes 5660754003eSLois Curfman McInnes static int MatGetSubMatrix_Dense(Mat matin,IS isrow,IS iscol,Mat *submat) 5670754003eSLois Curfman McInnes { 5680754003eSLois Curfman McInnes Mat_Dense *mat = (Mat_Dense *) matin->data; 5690754003eSLois Curfman McInnes int nznew, *smap, i, j, ierr, oldcols = mat->n; 5700754003eSLois Curfman McInnes int *irow, *icol, nrows, ncols, *cwork, jstart; 5710754003eSLois Curfman McInnes Scalar *vwork, *val; 5720754003eSLois Curfman McInnes Mat newmat; 5730754003eSLois Curfman McInnes 5740754003eSLois Curfman McInnes ierr = ISGetIndices(isrow,&irow); CHKERR(ierr); 5750754003eSLois Curfman McInnes ierr = ISGetIndices(iscol,&icol); CHKERR(ierr); 5760754003eSLois Curfman McInnes ierr = ISGetSize(isrow,&nrows); CHKERR(ierr); 5770754003eSLois Curfman McInnes ierr = ISGetSize(iscol,&ncols); CHKERR(ierr); 5780754003eSLois Curfman McInnes 5790754003eSLois Curfman McInnes smap = (int *) MALLOC(oldcols*sizeof(int)); CHKPTR(smap); 5800754003eSLois Curfman McInnes cwork = (int *) MALLOC(ncols*sizeof(int)); CHKPTR(cwork); 5810754003eSLois Curfman McInnes vwork = (Scalar *) MALLOC(ncols*sizeof(Scalar)); CHKPTR(vwork); 5820754003eSLois Curfman McInnes memset((char*)smap,0,oldcols*sizeof(int)); 5830754003eSLois Curfman McInnes for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 5840754003eSLois Curfman McInnes 5850754003eSLois Curfman McInnes /* Create and fill new matrix */ 5860754003eSLois Curfman McInnes ierr = MatCreateSequentialDense(matin->comm,nrows,ncols,&newmat); 5870754003eSLois Curfman McInnes CHKERR(ierr); 5880754003eSLois Curfman McInnes for (i=0; i<nrows; i++) { 5890754003eSLois Curfman McInnes nznew = 0; 5900754003eSLois Curfman McInnes val = mat->v + irow[i]; 5910754003eSLois Curfman McInnes for (j=0; j<oldcols; j++) { 5920754003eSLois Curfman McInnes if (smap[j]) { 5930754003eSLois Curfman McInnes cwork[nznew] = smap[j] - 1; 5940754003eSLois Curfman McInnes vwork[nznew++] = val[j * mat->m]; 5950754003eSLois Curfman McInnes } 5960754003eSLois Curfman McInnes } 5970754003eSLois Curfman McInnes ierr = MatSetValues(newmat,1,&i,nznew,cwork,vwork,InsertValues); 5980754003eSLois Curfman McInnes CHKERR(ierr); 5990754003eSLois Curfman McInnes } 6000754003eSLois Curfman McInnes ierr = MatBeginAssembly(newmat,FINAL_ASSEMBLY); CHKERR(ierr); 6010754003eSLois Curfman McInnes ierr = MatEndAssembly(newmat,FINAL_ASSEMBLY); CHKERR(ierr); 6020754003eSLois Curfman McInnes 6030754003eSLois Curfman McInnes /* Free work space */ 6040754003eSLois Curfman McInnes FREE(smap); FREE(cwork); FREE(vwork); 6050754003eSLois Curfman McInnes ierr = ISRestoreIndices(isrow,&irow); CHKERR(ierr); 6060754003eSLois Curfman McInnes ierr = ISRestoreIndices(iscol,&icol); CHKERR(ierr); 6070754003eSLois Curfman McInnes *submat = newmat; 6080754003eSLois Curfman McInnes return 0; 6090754003eSLois Curfman McInnes } 6100754003eSLois Curfman McInnes 611289bc588SBarry Smith /* -------------------------------------------------------------------*/ 61244a69424SLois Curfman McInnes static struct _MatOps MatOps = {MatInsert_Dense, 61344a69424SLois Curfman McInnes MatGetRow_Dense, MatRestoreRow_Dense, 61444a69424SLois Curfman McInnes MatMult_Dense, MatMultAdd_Dense, 61544a69424SLois Curfman McInnes MatMultTrans_Dense, MatMultTransAdd_Dense, 61644a69424SLois Curfman McInnes MatSolve_Dense,MatSolveAdd_Dense, 61744a69424SLois Curfman McInnes MatSolveTrans_Dense,MatSolveTransAdd_Dense, 61846fc4a8fSLois Curfman McInnes MatLUFactor_Dense,MatCholeskyFactor_Dense, 61944a69424SLois Curfman McInnes MatRelax_Dense, 62044a69424SLois Curfman McInnes MatTrans_Dense, 621fa9ec3f1SLois Curfman McInnes MatGetInfo_Dense,MatEqual_Dense, 62244a69424SLois Curfman McInnes MatCopy_Dense, 62346fc4a8fSLois Curfman McInnes MatGetDiagonal_Dense,MatScale_Dense,MatNorm_Dense, 624289bc588SBarry Smith 0,0, 625681d1451SLois Curfman McInnes 0, MatSetOption_Dense,MatZero_Dense,MatZeroRows_Dense,0, 62644a69424SLois Curfman McInnes MatLUFactorSymbolic_Dense,MatLUFactorNumeric_Dense, 62746fc4a8fSLois Curfman McInnes MatCholeskyFactorSymbolic_Dense,MatCholeskyFactorNumeric_Dense, 628fa9ec3f1SLois Curfman McInnes MatGetSize_Dense,MatGetSize_Dense,0, 6290754003eSLois Curfman McInnes 0,0,MatGetArray_Dense,0, 6300754003eSLois Curfman McInnes MatGetSubMatrix_Dense,MatGetSubMatrixInPlace_Dense}; 6310754003eSLois Curfman McInnes 63220563c6bSBarry Smith /*@ 63320563c6bSBarry Smith MatCreateSequentialDense - Creates a sequential dense matrix that 634d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 635d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 636289bc588SBarry Smith 63720563c6bSBarry Smith Input Parameters: 6380c775827SLois Curfman McInnes . comm - MPI communicator, set to MPI_COMM_SELF 6390c775827SLois Curfman McInnes . m - number of rows 6400c775827SLois Curfman McInnes . n - number of column 64120563c6bSBarry Smith 64220563c6bSBarry Smith Output Parameter: 6430c775827SLois Curfman McInnes . newmat - the matrix 64420563c6bSBarry Smith 645d65003e9SLois Curfman McInnes .keywords: Mat, dense, matrix, LAPACK, BLAS 646d65003e9SLois Curfman McInnes 647d65003e9SLois Curfman McInnes .seealso: MatCreateSequentialAIJ() 64820563c6bSBarry Smith @*/ 6496b5873e3SBarry Smith int MatCreateSequentialDense(MPI_Comm comm,int m,int n,Mat *newmat) 650289bc588SBarry Smith { 65144a69424SLois Curfman McInnes int size = sizeof(Mat_Dense) + m*n*sizeof(Scalar); 652289bc588SBarry Smith Mat mat; 65344a69424SLois Curfman McInnes Mat_Dense *l; 654289bc588SBarry Smith *newmat = 0; 6556b5873e3SBarry Smith PETSCHEADERCREATE(mat,_Mat,MAT_COOKIE,MATDENSE,comm); 656a5a9c739SBarry Smith PLogObjectCreate(mat); 65744a69424SLois Curfman McInnes l = (Mat_Dense *) MALLOC(size); CHKPTR(l); 658289bc588SBarry Smith mat->ops = &MatOps; 65944a69424SLois Curfman McInnes mat->destroy = MatDestroy_Dense; 66044a69424SLois Curfman McInnes mat->view = MatView_Dense; 661289bc588SBarry Smith mat->data = (void *) l; 662289bc588SBarry Smith mat->factor = 0; 663d6dfbf8fSBarry Smith 664289bc588SBarry Smith l->m = m; 665289bc588SBarry Smith l->n = n; 666289bc588SBarry Smith l->v = (Scalar *) (l + 1); 667289bc588SBarry Smith l->pivots = 0; 668289bc588SBarry Smith l->roworiented = 1; 669d6dfbf8fSBarry Smith 670289bc588SBarry Smith MEMSET(l->v,0,m*n*sizeof(Scalar)); 671289bc588SBarry Smith *newmat = mat; 672289bc588SBarry Smith return 0; 673289bc588SBarry Smith } 674289bc588SBarry Smith 67544a69424SLois Curfman McInnes int MatCreate_Dense(Mat matin,Mat *newmat) 676289bc588SBarry Smith { 67744a69424SLois Curfman McInnes Mat_Dense *m = (Mat_Dense *) matin->data; 6786b5873e3SBarry Smith return MatCreateSequentialDense(matin->comm,m->m,m->n,newmat); 679289bc588SBarry Smith } 680