1 #ifdef PETSC_RCS_HEADER 2 static char vcid[] = "$Id: dense.c,v 1.174 1999/10/01 21:21:11 bsmith Exp bsmith $"; 3 #endif 4 /* 5 Defines the basic matrix operations for sequential dense. 6 */ 7 8 #include "src/mat/impls/dense/seq/dense.h" 9 #include "pinclude/blaslapack.h" 10 11 #undef __FUNC__ 12 #define __FUNC__ "MatAXPY_SeqDense" 13 int MatAXPY_SeqDense(Scalar *alpha,Mat X,Mat Y) 14 { 15 Mat_SeqDense *x = (Mat_SeqDense*) X->data,*y = (Mat_SeqDense*) Y->data; 16 int N = x->m*x->n, one = 1; 17 18 PetscFunctionBegin; 19 BLaxpy_( &N, alpha, x->v, &one, y->v, &one ); 20 PLogFlops(2*N-1); 21 PetscFunctionReturn(0); 22 } 23 24 #undef __FUNC__ 25 #define __FUNC__ "MatGetInfo_SeqDense" 26 int MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info) 27 { 28 Mat_SeqDense *a = (Mat_SeqDense *) A->data; 29 int i,N = a->m*a->n,count = 0; 30 Scalar *v = a->v; 31 32 PetscFunctionBegin; 33 for ( i=0; i<N; i++ ) {if (*v != 0.0) count++; v++;} 34 35 info->rows_global = (double)a->m; 36 info->columns_global = (double)a->n; 37 info->rows_local = (double)a->m; 38 info->columns_local = (double)a->n; 39 info->block_size = 1.0; 40 info->nz_allocated = (double)N; 41 info->nz_used = (double)count; 42 info->nz_unneeded = (double)(N-count); 43 info->assemblies = (double)A->num_ass; 44 info->mallocs = 0; 45 info->memory = A->mem; 46 info->fill_ratio_given = 0; 47 info->fill_ratio_needed = 0; 48 info->factor_mallocs = 0; 49 50 PetscFunctionReturn(0); 51 } 52 53 #undef __FUNC__ 54 #define __FUNC__ "MatScale_SeqDense" 55 int MatScale_SeqDense(Scalar *alpha,Mat inA) 56 { 57 Mat_SeqDense *a = (Mat_SeqDense *) inA->data; 58 int one = 1, nz; 59 60 PetscFunctionBegin; 61 nz = a->m*a->n; 62 BLscal_( &nz, alpha, a->v, &one ); 63 PLogFlops(nz); 64 PetscFunctionReturn(0); 65 } 66 67 /* ---------------------------------------------------------------*/ 68 /* COMMENT: I have chosen to hide column permutation in the pivots, 69 rather than put it in the Mat->col slot.*/ 70 #undef __FUNC__ 71 #define __FUNC__ "MatLUFactor_SeqDense" 72 int MatLUFactor_SeqDense(Mat A,IS row,IS col,double f) 73 { 74 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 75 int info; 76 77 PetscFunctionBegin; 78 if (!mat->pivots) { 79 mat->pivots = (int *) PetscMalloc((mat->m+1)*sizeof(int));CHKPTRQ(mat->pivots); 80 PLogObjectMemory(A,mat->m*sizeof(int)); 81 } 82 if (!mat->m || !mat->n) PetscFunctionReturn(0); 83 LAgetrf_(&mat->m,&mat->n,mat->v,&mat->m,mat->pivots,&info); 84 if (info<0) SETERRQ(PETSC_ERR_LIB,0,"Bad argument to LU factorization"); 85 if (info>0) SETERRQ(PETSC_ERR_MAT_LU_ZRPVT,0,"Bad LU factorization"); 86 A->factor = FACTOR_LU; 87 PLogFlops((2*mat->n*mat->n*mat->n)/3); 88 PetscFunctionReturn(0); 89 } 90 91 #undef __FUNC__ 92 #define __FUNC__ "MatDuplicate_SeqDense" 93 int MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat) 94 { 95 Mat_SeqDense *mat = (Mat_SeqDense *) A->data, *l; 96 int ierr; 97 Mat newi; 98 99 PetscFunctionBegin; 100 ierr = MatCreateSeqDense(A->comm,mat->m,mat->n,PETSC_NULL,&newi);CHKERRQ(ierr); 101 l = (Mat_SeqDense *) newi->data; 102 if (cpvalues == MAT_COPY_VALUES) { 103 ierr = PetscMemcpy(l->v,mat->v,mat->m*mat->n*sizeof(Scalar));CHKERRQ(ierr); 104 } 105 newi->assembled = PETSC_TRUE; 106 *newmat = newi; 107 PetscFunctionReturn(0); 108 } 109 110 #undef __FUNC__ 111 #define __FUNC__ "MatLUFactorSymbolic_SeqDense" 112 int MatLUFactorSymbolic_SeqDense(Mat A,IS row,IS col,double f,Mat *fact) 113 { 114 int ierr; 115 116 PetscFunctionBegin; 117 ierr = MatDuplicate_SeqDense(A,MAT_DO_NOT_COPY_VALUES,fact);CHKERRQ(ierr); 118 PetscFunctionReturn(0); 119 } 120 121 #undef __FUNC__ 122 #define __FUNC__ "MatLUFactorNumeric_SeqDense" 123 int MatLUFactorNumeric_SeqDense(Mat A,Mat *fact) 124 { 125 Mat_SeqDense *mat = (Mat_SeqDense*) A->data, *l = (Mat_SeqDense*) (*fact)->data; 126 int ierr; 127 128 PetscFunctionBegin; 129 /* copy the numerical values */ 130 ierr = PetscMemcpy(l->v,mat->v,mat->m*mat->n*sizeof(Scalar));CHKERRQ(ierr); 131 (*fact)->factor = 0; 132 ierr = MatLUFactor(*fact,0,0,1.0);CHKERRQ(ierr); 133 PetscFunctionReturn(0); 134 } 135 136 #undef __FUNC__ 137 #define __FUNC__ "MatCholeskyFactorSymbolic_SeqDense" 138 int MatCholeskyFactorSymbolic_SeqDense(Mat A,IS row,double f,Mat *fact) 139 { 140 int ierr; 141 142 PetscFunctionBegin; 143 ierr = MatConvert(A,MATSAME,fact);CHKERRQ(ierr); 144 PetscFunctionReturn(0); 145 } 146 147 #undef __FUNC__ 148 #define __FUNC__ "MatCholeskyFactorNumeric_SeqDense" 149 int MatCholeskyFactorNumeric_SeqDense(Mat A,Mat *fact) 150 { 151 int ierr; 152 153 PetscFunctionBegin; 154 ierr = MatCholeskyFactor(*fact,0,1.0);CHKERRQ(ierr); 155 PetscFunctionReturn(0); 156 } 157 158 #undef __FUNC__ 159 #define __FUNC__ "MatCholeskyFactor_SeqDense" 160 int MatCholeskyFactor_SeqDense(Mat A,IS perm,double f) 161 { 162 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 163 int info,ierr; 164 165 PetscFunctionBegin; 166 if (mat->pivots) { 167 ierr = PetscFree(mat->pivots);CHKERRQ(ierr); 168 PLogObjectMemory(A,-mat->m*sizeof(int)); 169 mat->pivots = 0; 170 } 171 if (!mat->m || !mat->n) PetscFunctionReturn(0); 172 LApotrf_("L",&mat->n,mat->v,&mat->m,&info); 173 if (info) SETERRQ(PETSC_ERR_MAT_CH_ZRPVT,0,"Bad factorization"); 174 A->factor = FACTOR_CHOLESKY; 175 PLogFlops((mat->n*mat->n*mat->n)/3); 176 PetscFunctionReturn(0); 177 } 178 179 #undef __FUNC__ 180 #define __FUNC__ "MatSolve_SeqDense" 181 int MatSolve_SeqDense(Mat A,Vec xx,Vec yy) 182 { 183 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 184 int one = 1, info, ierr; 185 Scalar *x, *y; 186 187 PetscFunctionBegin; 188 if (!mat->m || !mat->n) PetscFunctionReturn(0); 189 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 190 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 191 ierr = PetscMemcpy(y,x,mat->m*sizeof(Scalar));CHKERRQ(ierr); 192 if (A->factor == FACTOR_LU) { 193 LAgetrs_( "N", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 194 } else if (A->factor == FACTOR_CHOLESKY){ 195 LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 196 } 197 else SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Matrix must be factored to solve"); 198 if (info) SETERRQ(PETSC_ERR_LIB,0,"MBad solve"); 199 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 200 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 201 PLogFlops(mat->n*mat->n - mat->n); 202 PetscFunctionReturn(0); 203 } 204 205 #undef __FUNC__ 206 #define __FUNC__ "MatSolveTrans_SeqDense" 207 int MatSolveTrans_SeqDense(Mat A,Vec xx,Vec yy) 208 { 209 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 210 int ierr,one = 1, info; 211 Scalar *x, *y; 212 213 PetscFunctionBegin; 214 if (!mat->m || !mat->n) PetscFunctionReturn(0); 215 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 216 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 217 ierr = PetscMemcpy(y,x,mat->m*sizeof(Scalar));CHKERRQ(ierr); 218 /* assume if pivots exist then use LU; else Cholesky */ 219 if (mat->pivots) { 220 LAgetrs_( "T", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 221 } else { 222 LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 223 } 224 if (info) SETERRQ(PETSC_ERR_LIB,0,"Bad solve"); 225 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 226 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 227 PLogFlops(mat->n*mat->n - mat->n); 228 PetscFunctionReturn(0); 229 } 230 231 #undef __FUNC__ 232 #define __FUNC__ "MatSolveAdd_SeqDense" 233 int MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 234 { 235 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 236 int ierr,one = 1, info; 237 Scalar *x, *y, sone = 1.0; 238 Vec tmp = 0; 239 240 PetscFunctionBegin; 241 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 242 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 243 if (!mat->m || !mat->n) PetscFunctionReturn(0); 244 if (yy == zz) { 245 ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 246 PLogObjectParent(A,tmp); 247 ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 248 } 249 ierr = PetscMemcpy(y,x,mat->m*sizeof(Scalar));CHKERRQ(ierr); 250 /* assume if pivots exist then use LU; else Cholesky */ 251 if (mat->pivots) { 252 LAgetrs_( "N", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 253 } else { 254 LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 255 } 256 if (info) SETERRQ(PETSC_ERR_LIB,0,"Bad solve"); 257 if (tmp) {ierr = VecAXPY(&sone,tmp,yy);CHKERRQ(ierr); ierr = VecDestroy(tmp);CHKERRQ(ierr);} 258 else {ierr = VecAXPY(&sone,zz,yy);CHKERRQ(ierr);} 259 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 260 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 261 PLogFlops(mat->n*mat->n - mat->n); 262 PetscFunctionReturn(0); 263 } 264 265 #undef __FUNC__ 266 #define __FUNC__ "MatSolveTransAdd_SeqDense" 267 int MatSolveTransAdd_SeqDense(Mat A,Vec xx,Vec zz, Vec yy) 268 { 269 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 270 int one = 1, info,ierr; 271 Scalar *x, *y, sone = 1.0; 272 Vec tmp; 273 274 PetscFunctionBegin; 275 if (!mat->m || !mat->n) PetscFunctionReturn(0); 276 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 277 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 278 if (yy == zz) { 279 ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 280 PLogObjectParent(A,tmp); 281 ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 282 } 283 ierr = PetscMemcpy(y,x,mat->m*sizeof(Scalar));CHKERRQ(ierr); 284 /* assume if pivots exist then use LU; else Cholesky */ 285 if (mat->pivots) { 286 LAgetrs_( "T", &mat->m, &one, mat->v, &mat->m, mat->pivots,y, &mat->m, &info ); 287 } else { 288 LApotrs_( "L", &mat->m, &one, mat->v, &mat->m,y, &mat->m, &info ); 289 } 290 if (info) SETERRQ(PETSC_ERR_LIB,0,"Bad solve"); 291 if (tmp) { 292 ierr = VecAXPY(&sone,tmp,yy);CHKERRQ(ierr); 293 ierr = VecDestroy(tmp);CHKERRQ(ierr); 294 } else { 295 ierr = VecAXPY(&sone,zz,yy);CHKERRQ(ierr); 296 } 297 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 298 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 299 PLogFlops(mat->n*mat->n - mat->n); 300 PetscFunctionReturn(0); 301 } 302 /* ------------------------------------------------------------------*/ 303 #undef __FUNC__ 304 #define __FUNC__ "MatRelax_SeqDense" 305 int MatRelax_SeqDense(Mat A,Vec bb,double omega,MatSORType flag, 306 double shift,int its,Vec xx) 307 { 308 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 309 Scalar *x, *b, *v = mat->v, zero = 0.0, xt; 310 int ierr, m = mat->m, i; 311 #if !defined(PETSC_USE_COMPLEX) 312 int o = 1; 313 #endif 314 315 PetscFunctionBegin; 316 if (flag & SOR_ZERO_INITIAL_GUESS) { 317 /* this is a hack fix, should have another version without the second BLdot */ 318 ierr = VecSet(&zero,xx);CHKERRQ(ierr); 319 } 320 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 321 ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 322 while (its--) { 323 if (flag & SOR_FORWARD_SWEEP){ 324 for ( i=0; i<m; i++ ) { 325 #if defined(PETSC_USE_COMPLEX) 326 /* cannot use BLAS dot for complex because compiler/linker is 327 not happy about returning a double complex */ 328 int _i; 329 Scalar sum = b[i]; 330 for ( _i=0; _i<m; _i++ ) { 331 sum -= PetscConj(v[i+_i*m])*x[_i]; 332 } 333 xt = sum; 334 #else 335 xt = b[i]-BLdot_(&m,v+i,&m,x,&o); 336 #endif 337 x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 338 } 339 } 340 if (flag & SOR_BACKWARD_SWEEP) { 341 for ( i=m-1; i>=0; i-- ) { 342 #if defined(PETSC_USE_COMPLEX) 343 /* cannot use BLAS dot for complex because compiler/linker is 344 not happy about returning a double complex */ 345 int _i; 346 Scalar sum = b[i]; 347 for ( _i=0; _i<m; _i++ ) { 348 sum -= PetscConj(v[i+_i*m])*x[_i]; 349 } 350 xt = sum; 351 #else 352 xt = b[i]-BLdot_(&m,v+i,&m,x,&o); 353 #endif 354 x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 355 } 356 } 357 } 358 ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr); 359 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 360 PetscFunctionReturn(0); 361 } 362 363 /* -----------------------------------------------------------------*/ 364 #undef __FUNC__ 365 #define __FUNC__ "MatMultTrans_SeqDense" 366 int MatMultTrans_SeqDense(Mat A,Vec xx,Vec yy) 367 { 368 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 369 Scalar *v = mat->v, *x, *y; 370 int ierr,_One=1;Scalar _DOne=1.0, _DZero=0.0; 371 372 PetscFunctionBegin; 373 if (!mat->m || !mat->n) PetscFunctionReturn(0); 374 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 375 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 376 LAgemv_("T",&(mat->m),&(mat->n),&_DOne,v,&(mat->m),x,&_One,&_DZero,y,&_One); 377 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 378 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 379 PLogFlops(2*mat->m*mat->n - mat->n); 380 PetscFunctionReturn(0); 381 } 382 383 #undef __FUNC__ 384 #define __FUNC__ "MatMult_SeqDense" 385 int MatMult_SeqDense(Mat A,Vec xx,Vec yy) 386 { 387 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 388 Scalar *v = mat->v, *x, *y; 389 int ierr,_One=1;Scalar _DOne=1.0, _DZero=0.0; 390 391 PetscFunctionBegin; 392 if (!mat->m || !mat->n) PetscFunctionReturn(0); 393 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 394 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 395 LAgemv_( "N", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),x,&_One,&_DZero,y,&_One); 396 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 397 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 398 PLogFlops(2*mat->m*mat->n - mat->m); 399 PetscFunctionReturn(0); 400 } 401 402 #undef __FUNC__ 403 #define __FUNC__ "MatMultAdd_SeqDense" 404 int MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 405 { 406 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 407 Scalar *v = mat->v, *x, *y; 408 int ierr,_One=1; Scalar _DOne=1.0; 409 410 PetscFunctionBegin; 411 if (!mat->m || !mat->n) PetscFunctionReturn(0); 412 if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 413 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 414 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 415 LAgemv_( "N", &(mat->m), &(mat->n),&_DOne,v,&(mat->m),x,&_One,&_DOne,y,&_One); 416 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 417 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 418 PLogFlops(2*mat->m*mat->n); 419 PetscFunctionReturn(0); 420 } 421 422 #undef __FUNC__ 423 #define __FUNC__ "MatMultTransAdd_SeqDense" 424 int MatMultTransAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 425 { 426 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 427 Scalar *v = mat->v, *x, *y; 428 int ierr,_One=1; 429 Scalar _DOne=1.0; 430 431 PetscFunctionBegin; 432 if (!mat->m || !mat->n) PetscFunctionReturn(0); 433 if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 434 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 435 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 436 LAgemv_( "T", &(mat->m), &(mat->n), &_DOne, v, &(mat->m),x,&_One,&_DOne,y,&_One); 437 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 438 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 439 PLogFlops(2*mat->m*mat->n); 440 PetscFunctionReturn(0); 441 } 442 443 /* -----------------------------------------------------------------*/ 444 #undef __FUNC__ 445 #define __FUNC__ "MatGetRow_SeqDense" 446 int MatGetRow_SeqDense(Mat A,int row,int *ncols,int **cols,Scalar **vals) 447 { 448 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 449 Scalar *v; 450 int i; 451 452 PetscFunctionBegin; 453 *ncols = mat->n; 454 if (cols) { 455 *cols = (int *) PetscMalloc((mat->n+1)*sizeof(int));CHKPTRQ(*cols); 456 for ( i=0; i<mat->n; i++ ) (*cols)[i] = i; 457 } 458 if (vals) { 459 *vals = (Scalar *) PetscMalloc((mat->n+1)*sizeof(Scalar));CHKPTRQ(*vals); 460 v = mat->v + row; 461 for ( i=0; i<mat->n; i++ ) {(*vals)[i] = *v; v += mat->m;} 462 } 463 PetscFunctionReturn(0); 464 } 465 466 #undef __FUNC__ 467 #define __FUNC__ "MatRestoreRow_SeqDense" 468 int MatRestoreRow_SeqDense(Mat A,int row,int *ncols,int **cols,Scalar **vals) 469 { 470 int ierr; 471 PetscFunctionBegin; 472 if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);} 473 if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); } 474 PetscFunctionReturn(0); 475 } 476 /* ----------------------------------------------------------------*/ 477 #undef __FUNC__ 478 #define __FUNC__ "MatSetValues_SeqDense" 479 int MatSetValues_SeqDense(Mat A,int m,int *indexm,int n, 480 int *indexn,Scalar *v,InsertMode addv) 481 { 482 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 483 int i,j; 484 485 PetscFunctionBegin; 486 if (!mat->roworiented) { 487 if (addv == INSERT_VALUES) { 488 for ( j=0; j<n; j++ ) { 489 if (indexn[j] < 0) {v += m; continue;} 490 #if defined(PETSC_USE_BOPT_g) 491 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 492 #endif 493 for ( i=0; i<m; i++ ) { 494 if (indexm[i] < 0) {v++; continue;} 495 #if defined(PETSC_USE_BOPT_g) 496 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 497 #endif 498 mat->v[indexn[j]*mat->m + indexm[i]] = *v++; 499 } 500 } 501 } else { 502 for ( j=0; j<n; j++ ) { 503 if (indexn[j] < 0) {v += m; continue;} 504 #if defined(PETSC_USE_BOPT_g) 505 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 506 #endif 507 for ( i=0; i<m; i++ ) { 508 if (indexm[i] < 0) {v++; continue;} 509 #if defined(PETSC_USE_BOPT_g) 510 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 511 #endif 512 mat->v[indexn[j]*mat->m + indexm[i]] += *v++; 513 } 514 } 515 } 516 } else { 517 if (addv == INSERT_VALUES) { 518 for ( i=0; i<m; i++ ) { 519 if (indexm[i] < 0) { v += n; continue;} 520 #if defined(PETSC_USE_BOPT_g) 521 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 522 #endif 523 for ( j=0; j<n; j++ ) { 524 if (indexn[j] < 0) { v++; continue;} 525 #if defined(PETSC_USE_BOPT_g) 526 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 527 #endif 528 mat->v[indexn[j]*mat->m + indexm[i]] = *v++; 529 } 530 } 531 } else { 532 for ( i=0; i<m; i++ ) { 533 if (indexm[i] < 0) { v += n; continue;} 534 #if defined(PETSC_USE_BOPT_g) 535 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 536 #endif 537 for ( j=0; j<n; j++ ) { 538 if (indexn[j] < 0) { v++; continue;} 539 #if defined(PETSC_USE_BOPT_g) 540 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 541 #endif 542 mat->v[indexn[j]*mat->m + indexm[i]] += *v++; 543 } 544 } 545 } 546 } 547 PetscFunctionReturn(0); 548 } 549 550 #undef __FUNC__ 551 #define __FUNC__ "MatGetValues_SeqDense" 552 int MatGetValues_SeqDense(Mat A,int m,int *indexm,int n,int *indexn,Scalar *v) 553 { 554 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 555 int i, j; 556 Scalar *vpt = v; 557 558 PetscFunctionBegin; 559 /* row-oriented output */ 560 for ( i=0; i<m; i++ ) { 561 for ( j=0; j<n; j++ ) { 562 *vpt++ = mat->v[indexn[j]*mat->m + indexm[i]]; 563 } 564 } 565 PetscFunctionReturn(0); 566 } 567 568 /* -----------------------------------------------------------------*/ 569 570 #include "sys.h" 571 572 #undef __FUNC__ 573 #define __FUNC__ "MatLoad_SeqDense" 574 int MatLoad_SeqDense(Viewer viewer,MatType type,Mat *A) 575 { 576 Mat_SeqDense *a; 577 Mat B; 578 int *scols, i, j, nz, ierr, fd, header[4], size; 579 int *rowlengths = 0, M, N, *cols; 580 Scalar *vals, *svals, *v,*w; 581 MPI_Comm comm = ((PetscObject)viewer)->comm; 582 583 PetscFunctionBegin; 584 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 585 if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 586 ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 587 ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 588 if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Not matrix object"); 589 M = header[1]; N = header[2]; nz = header[3]; 590 591 if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */ 592 ierr = MatCreateSeqDense(comm,M,N,PETSC_NULL,A);CHKERRQ(ierr); 593 B = *A; 594 a = (Mat_SeqDense *) B->data; 595 v = a->v; 596 /* Allocate some temp space to read in the values and then flip them 597 from row major to column major */ 598 w = (Scalar *) PetscMalloc((M*N+1)*sizeof(Scalar));CHKPTRQ(w); 599 /* read in nonzero values */ 600 ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr); 601 /* now flip the values and store them in the matrix*/ 602 for ( j=0; j<N; j++ ) { 603 for ( i=0; i<M; i++ ) { 604 *v++ =w[i*N+j]; 605 } 606 } 607 ierr = PetscFree(w);CHKERRQ(ierr); 608 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 609 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 610 } else { 611 /* read row lengths */ 612 rowlengths = (int*) PetscMalloc( (M+1)*sizeof(int) );CHKPTRQ(rowlengths); 613 ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 614 615 /* create our matrix */ 616 ierr = MatCreateSeqDense(comm,M,N,PETSC_NULL,A);CHKERRQ(ierr); 617 B = *A; 618 a = (Mat_SeqDense *) B->data; 619 v = a->v; 620 621 /* read column indices and nonzeros */ 622 cols = scols = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(cols); 623 ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr); 624 vals = svals = (Scalar *) PetscMalloc( (nz+1)*sizeof(Scalar) );CHKPTRQ(vals); 625 ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr); 626 627 /* insert into matrix */ 628 for ( i=0; i<M; i++ ) { 629 for ( j=0; j<rowlengths[i]; j++ ) v[i+M*scols[j]] = svals[j]; 630 svals += rowlengths[i]; scols += rowlengths[i]; 631 } 632 ierr = PetscFree(vals);CHKERRQ(ierr); 633 ierr = PetscFree(cols);CHKERRQ(ierr); 634 ierr = PetscFree(rowlengths);CHKERRQ(ierr); 635 636 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 637 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 638 } 639 PetscFunctionReturn(0); 640 } 641 642 #include "sys.h" 643 644 #undef __FUNC__ 645 #define __FUNC__ "MatView_SeqDense_ASCII" 646 static int MatView_SeqDense_ASCII(Mat A,Viewer viewer) 647 { 648 Mat_SeqDense *a = (Mat_SeqDense *) A->data; 649 int ierr, i, j, format; 650 FILE *fd; 651 char *outputname; 652 Scalar *v; 653 654 PetscFunctionBegin; 655 ierr = ViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr); 656 ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 657 ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 658 if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 659 PetscFunctionReturn(0); /* do nothing for now */ 660 } 661 else if (format == VIEWER_FORMAT_ASCII_COMMON) { 662 for ( i=0; i<a->m; i++ ) { 663 v = a->v + i; 664 fprintf(fd,"row %d:",i); 665 for ( j=0; j<a->n; j++ ) { 666 #if defined(PETSC_USE_COMPLEX) 667 if (PetscReal(*v) != 0.0 && PetscImaginary(*v) != 0.0) fprintf(fd," %d %g + %g i",j,PetscReal(*v),PetscImaginary(*v)); 668 else if (PetscReal(*v)) fprintf(fd," %d %g ",j,PetscReal(*v)); 669 #else 670 if (*v) fprintf(fd," %d %g ",j,*v); 671 #endif 672 v += a->m; 673 } 674 fprintf(fd,"\n"); 675 } 676 } else { 677 #if defined(PETSC_USE_COMPLEX) 678 int allreal = 1; 679 /* determine if matrix has all real values */ 680 v = a->v; 681 for ( i=0; i<a->m*a->n; i++ ) { 682 if (PetscImaginary(v[i])) { allreal = 0; break ;} 683 } 684 #endif 685 for ( i=0; i<a->m; i++ ) { 686 v = a->v + i; 687 for ( j=0; j<a->n; j++ ) { 688 #if defined(PETSC_USE_COMPLEX) 689 if (allreal) { 690 fprintf(fd,"%6.4e ",PetscReal(*v)); v += a->m; 691 } else { 692 fprintf(fd,"%6.4e + %6.4e i ",PetscReal(*v),PetscImaginary(*v)); v += a->m; 693 } 694 #else 695 fprintf(fd,"%6.4e ",*v); v += a->m; 696 #endif 697 } 698 fprintf(fd,"\n"); 699 } 700 } 701 fflush(fd); 702 PetscFunctionReturn(0); 703 } 704 705 #undef __FUNC__ 706 #define __FUNC__ "MatView_SeqDense_Binary" 707 static int MatView_SeqDense_Binary(Mat A,Viewer viewer) 708 { 709 Mat_SeqDense *a = (Mat_SeqDense *) A->data; 710 int ict, j, n = a->n, m = a->m, i, fd, *col_lens, ierr, nz = m*n; 711 int format; 712 Scalar *v, *anonz,*vals; 713 714 PetscFunctionBegin; 715 ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 716 717 ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 718 if (format == VIEWER_FORMAT_BINARY_NATIVE) { 719 /* store the matrix as a dense matrix */ 720 col_lens = (int *) PetscMalloc( 4*sizeof(int) );CHKPTRQ(col_lens); 721 col_lens[0] = MAT_COOKIE; 722 col_lens[1] = m; 723 col_lens[2] = n; 724 col_lens[3] = MATRIX_BINARY_FORMAT_DENSE; 725 ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,1);CHKERRQ(ierr); 726 ierr = PetscFree(col_lens);CHKERRQ(ierr); 727 728 /* write out matrix, by rows */ 729 vals = (Scalar *) PetscMalloc((m*n+1)*sizeof(Scalar));CHKPTRQ(vals); 730 v = a->v; 731 for ( i=0; i<m; i++ ) { 732 for ( j=0; j<n; j++ ) { 733 vals[i + j*m] = *v++; 734 } 735 } 736 ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,0);CHKERRQ(ierr); 737 ierr = PetscFree(vals);CHKERRQ(ierr); 738 } else { 739 col_lens = (int *) PetscMalloc( (4+nz)*sizeof(int) );CHKPTRQ(col_lens); 740 col_lens[0] = MAT_COOKIE; 741 col_lens[1] = m; 742 col_lens[2] = n; 743 col_lens[3] = nz; 744 745 /* store lengths of each row and write (including header) to file */ 746 for ( i=0; i<m; i++ ) col_lens[4+i] = n; 747 ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,1);CHKERRQ(ierr); 748 749 /* Possibly should write in smaller increments, not whole matrix at once? */ 750 /* store column indices (zero start index) */ 751 ict = 0; 752 for ( i=0; i<m; i++ ) { 753 for ( j=0; j<n; j++ ) col_lens[ict++] = j; 754 } 755 ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,0);CHKERRQ(ierr); 756 ierr = PetscFree(col_lens);CHKERRQ(ierr); 757 758 /* store nonzero values */ 759 anonz = (Scalar *) PetscMalloc((nz+1)*sizeof(Scalar));CHKPTRQ(anonz); 760 ict = 0; 761 for ( i=0; i<m; i++ ) { 762 v = a->v + i; 763 for ( j=0; j<n; j++ ) { 764 anonz[ict++] = *v; v += a->m; 765 } 766 } 767 ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,0);CHKERRQ(ierr); 768 ierr = PetscFree(anonz);CHKERRQ(ierr); 769 } 770 PetscFunctionReturn(0); 771 } 772 773 #undef __FUNC__ 774 #define __FUNC__ "MatView_SeqDense" 775 int MatView_SeqDense(Mat A,Viewer viewer) 776 { 777 Mat_SeqDense *a = (Mat_SeqDense*) A->data; 778 int ierr; 779 int issocket,isascii,isbinary; 780 781 PetscFunctionBegin; 782 issocket = PetscTypeCompare(viewer,SOCKET_VIEWER); 783 isascii = PetscTypeCompare(viewer,ASCII_VIEWER); 784 isbinary = PetscTypeCompare(viewer,BINARY_VIEWER); 785 786 if (issocket) { 787 ierr = ViewerSocketPutScalar_Private(viewer,a->m,a->n,a->v);CHKERRQ(ierr); 788 } else if (isascii) { 789 ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr); 790 } else if (isbinary) { 791 ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr); 792 } else { 793 SETERRQ1(1,1,"Viewer type %s not supported by dense matrix",((PetscObject)viewer)->type_name); 794 } 795 PetscFunctionReturn(0); 796 } 797 798 #undef __FUNC__ 799 #define __FUNC__ "MatDestroy_SeqDense" 800 int MatDestroy_SeqDense(Mat mat) 801 { 802 Mat_SeqDense *l = (Mat_SeqDense *) mat->data; 803 int ierr; 804 805 PetscFunctionBegin; 806 807 if (mat->mapping) { 808 ierr = ISLocalToGlobalMappingDestroy(mat->mapping);CHKERRQ(ierr); 809 } 810 if (mat->bmapping) { 811 ierr = ISLocalToGlobalMappingDestroy(mat->bmapping);CHKERRQ(ierr); 812 } 813 #if defined(PETSC_USE_LOG) 814 PLogObjectState((PetscObject)mat,"Rows %d Cols %d",l->m,l->n); 815 #endif 816 if (l->pivots) {ierr = PetscFree(l->pivots);CHKERRQ(ierr);} 817 if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);} 818 ierr = PetscFree(l);CHKERRQ(ierr); 819 if (mat->rmap) { 820 ierr = MapDestroy(mat->rmap);CHKERRQ(ierr); 821 } 822 if (mat->cmap) { 823 ierr = MapDestroy(mat->cmap);CHKERRQ(ierr); 824 } 825 PLogObjectDestroy(mat); 826 PetscHeaderDestroy(mat); 827 PetscFunctionReturn(0); 828 } 829 830 #undef __FUNC__ 831 #define __FUNC__ "MatTranspose_SeqDense" 832 int MatTranspose_SeqDense(Mat A,Mat *matout) 833 { 834 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 835 int k, j, m, n, ierr; 836 Scalar *v, tmp; 837 838 PetscFunctionBegin; 839 v = mat->v; m = mat->m; n = mat->n; 840 if (matout == PETSC_NULL) { /* in place transpose */ 841 if (m != n) { /* malloc temp to hold transpose */ 842 Scalar *w = (Scalar *) PetscMalloc((m+1)*(n+1)*sizeof(Scalar));CHKPTRQ(w); 843 for ( j=0; j<m; j++ ) { 844 for ( k=0; k<n; k++ ) { 845 w[k + j*n] = v[j + k*m]; 846 } 847 } 848 ierr = PetscMemcpy(v,w,m*n*sizeof(Scalar));CHKERRQ(ierr); 849 ierr = PetscFree(w);CHKERRQ(ierr); 850 } else { 851 for ( j=0; j<m; j++ ) { 852 for ( k=0; k<j; k++ ) { 853 tmp = v[j + k*n]; 854 v[j + k*n] = v[k + j*n]; 855 v[k + j*n] = tmp; 856 } 857 } 858 } 859 } else { /* out-of-place transpose */ 860 Mat tmat; 861 Mat_SeqDense *tmatd; 862 Scalar *v2; 863 ierr = MatCreateSeqDense(A->comm,mat->n,mat->m,PETSC_NULL,&tmat);CHKERRQ(ierr); 864 tmatd = (Mat_SeqDense *) tmat->data; 865 v = mat->v; v2 = tmatd->v; 866 for ( j=0; j<n; j++ ) { 867 for ( k=0; k<m; k++ ) v2[j + k*n] = v[k + j*m]; 868 } 869 ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 870 ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 871 *matout = tmat; 872 } 873 PetscFunctionReturn(0); 874 } 875 876 #undef __FUNC__ 877 #define __FUNC__ "MatEqual_SeqDense" 878 int MatEqual_SeqDense(Mat A1,Mat A2, PetscTruth *flg) 879 { 880 Mat_SeqDense *mat1 = (Mat_SeqDense *) A1->data; 881 Mat_SeqDense *mat2 = (Mat_SeqDense *) A2->data; 882 int i; 883 Scalar *v1 = mat1->v, *v2 = mat2->v; 884 885 PetscFunctionBegin; 886 if (A2->type != MATSEQDENSE) SETERRQ(PETSC_ERR_SUP,0,"Matrices should be of type MATSEQDENSE"); 887 if (mat1->m != mat2->m) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 888 if (mat1->n != mat2->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 889 for ( i=0; i<mat1->m*mat1->n; i++ ) { 890 if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 891 v1++; v2++; 892 } 893 *flg = PETSC_TRUE; 894 PetscFunctionReturn(0); 895 } 896 897 #undef __FUNC__ 898 #define __FUNC__ "MatGetDiagonal_SeqDense" 899 int MatGetDiagonal_SeqDense(Mat A,Vec v) 900 { 901 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 902 int ierr,i, n, len; 903 Scalar *x, zero = 0.0; 904 905 PetscFunctionBegin; 906 ierr = VecSet(&zero,v);CHKERRQ(ierr); 907 ierr = VecGetSize(v,&n);CHKERRQ(ierr); 908 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 909 len = PetscMin(mat->m,mat->n); 910 if (n != mat->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming mat and vec"); 911 for ( i=0; i<len; i++ ) { 912 x[i] = mat->v[i*mat->m + i]; 913 } 914 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 915 PetscFunctionReturn(0); 916 } 917 918 #undef __FUNC__ 919 #define __FUNC__ "MatDiagonalScale_SeqDense" 920 int MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr) 921 { 922 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 923 Scalar *l,*r,x,*v; 924 int ierr,i,j,m = mat->m, n = mat->n; 925 926 PetscFunctionBegin; 927 if (ll) { 928 ierr = VecGetSize(ll,&m);CHKERRQ(ierr); 929 ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 930 if (m != mat->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vec wrong size"); 931 for ( i=0; i<m; i++ ) { 932 x = l[i]; 933 v = mat->v + i; 934 for ( j=0; j<n; j++ ) { (*v) *= x; v+= m;} 935 } 936 ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 937 PLogFlops(n*m); 938 } 939 if (rr) { 940 ierr = VecGetSize(rr,&n);CHKERRQ(ierr); 941 ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 942 if (n != mat->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vec wrong size"); 943 for ( i=0; i<n; i++ ) { 944 x = r[i]; 945 v = mat->v + i*m; 946 for ( j=0; j<m; j++ ) { (*v++) *= x;} 947 } 948 ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 949 PLogFlops(n*m); 950 } 951 PetscFunctionReturn(0); 952 } 953 954 #undef __FUNC__ 955 #define __FUNC__ "MatNorm_SeqDense" 956 int MatNorm_SeqDense(Mat A,NormType type,double *norm) 957 { 958 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 959 Scalar *v = mat->v; 960 double sum = 0.0; 961 int i, j; 962 963 PetscFunctionBegin; 964 if (type == NORM_FROBENIUS) { 965 for (i=0; i<mat->n*mat->m; i++ ) { 966 #if defined(PETSC_USE_COMPLEX) 967 sum += PetscReal(PetscConj(*v)*(*v)); v++; 968 #else 969 sum += (*v)*(*v); v++; 970 #endif 971 } 972 *norm = sqrt(sum); 973 PLogFlops(2*mat->n*mat->m); 974 } else if (type == NORM_1) { 975 *norm = 0.0; 976 for ( j=0; j<mat->n; j++ ) { 977 sum = 0.0; 978 for ( i=0; i<mat->m; i++ ) { 979 sum += PetscAbsScalar(*v); v++; 980 } 981 if (sum > *norm) *norm = sum; 982 } 983 PLogFlops(mat->n*mat->m); 984 } else if (type == NORM_INFINITY) { 985 *norm = 0.0; 986 for ( j=0; j<mat->m; j++ ) { 987 v = mat->v + j; 988 sum = 0.0; 989 for ( i=0; i<mat->n; i++ ) { 990 sum += PetscAbsScalar(*v); v += mat->m; 991 } 992 if (sum > *norm) *norm = sum; 993 } 994 PLogFlops(mat->n*mat->m); 995 } else { 996 SETERRQ(PETSC_ERR_SUP,0,"No two norm"); 997 } 998 PetscFunctionReturn(0); 999 } 1000 1001 #undef __FUNC__ 1002 #define __FUNC__ "MatSetOption_SeqDense" 1003 int MatSetOption_SeqDense(Mat A,MatOption op) 1004 { 1005 Mat_SeqDense *aij = (Mat_SeqDense *) A->data; 1006 1007 PetscFunctionBegin; 1008 if (op == MAT_ROW_ORIENTED) aij->roworiented = 1; 1009 else if (op == MAT_COLUMN_ORIENTED) aij->roworiented = 0; 1010 else if (op == MAT_ROWS_SORTED || 1011 op == MAT_ROWS_UNSORTED || 1012 op == MAT_COLUMNS_SORTED || 1013 op == MAT_COLUMNS_UNSORTED || 1014 op == MAT_SYMMETRIC || 1015 op == MAT_STRUCTURALLY_SYMMETRIC || 1016 op == MAT_NO_NEW_NONZERO_LOCATIONS || 1017 op == MAT_YES_NEW_NONZERO_LOCATIONS || 1018 op == MAT_NEW_NONZERO_LOCATION_ERR || 1019 op == MAT_NO_NEW_DIAGONALS || 1020 op == MAT_YES_NEW_DIAGONALS || 1021 op == MAT_IGNORE_OFF_PROC_ENTRIES || 1022 op == MAT_USE_HASH_TABLE) 1023 PLogInfo(A,"MatSetOption_SeqDense:Option ignored\n"); 1024 else { 1025 SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1026 } 1027 PetscFunctionReturn(0); 1028 } 1029 1030 #undef __FUNC__ 1031 #define __FUNC__ "MatZeroEntries_SeqDense" 1032 int MatZeroEntries_SeqDense(Mat A) 1033 { 1034 Mat_SeqDense *l = (Mat_SeqDense *) A->data; 1035 int ierr; 1036 1037 PetscFunctionBegin; 1038 ierr = PetscMemzero(l->v,l->m*l->n*sizeof(Scalar));CHKERRQ(ierr); 1039 PetscFunctionReturn(0); 1040 } 1041 1042 #undef __FUNC__ 1043 #define __FUNC__ "MatGetBlockSize_SeqDense" 1044 int MatGetBlockSize_SeqDense(Mat A,int *bs) 1045 { 1046 PetscFunctionBegin; 1047 *bs = 1; 1048 PetscFunctionReturn(0); 1049 } 1050 1051 #undef __FUNC__ 1052 #define __FUNC__ "MatZeroRows_SeqDense" 1053 int MatZeroRows_SeqDense(Mat A,IS is,Scalar *diag) 1054 { 1055 Mat_SeqDense *l = (Mat_SeqDense *) A->data; 1056 int n = l->n, i, j,ierr,N, *rows; 1057 Scalar *slot; 1058 1059 PetscFunctionBegin; 1060 ierr = ISGetSize(is,&N);CHKERRQ(ierr); 1061 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1062 for ( i=0; i<N; i++ ) { 1063 slot = l->v + rows[i]; 1064 for ( j=0; j<n; j++ ) { *slot = 0.0; slot += n;} 1065 } 1066 if (diag) { 1067 for ( i=0; i<N; i++ ) { 1068 slot = l->v + (n+1)*rows[i]; 1069 *slot = *diag; 1070 } 1071 } 1072 ISRestoreIndices(is,&rows); 1073 PetscFunctionReturn(0); 1074 } 1075 1076 #undef __FUNC__ 1077 #define __FUNC__ "MatGetSize_SeqDense" 1078 int MatGetSize_SeqDense(Mat A,int *m,int *n) 1079 { 1080 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1081 1082 PetscFunctionBegin; 1083 *m = mat->m; *n = mat->n; 1084 PetscFunctionReturn(0); 1085 } 1086 1087 #undef __FUNC__ 1088 #define __FUNC__ "MatGetOwnershipRange_SeqDense" 1089 int MatGetOwnershipRange_SeqDense(Mat A,int *m,int *n) 1090 { 1091 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1092 1093 PetscFunctionBegin; 1094 *m = 0; *n = mat->m; 1095 PetscFunctionReturn(0); 1096 } 1097 1098 #undef __FUNC__ 1099 #define __FUNC__ "MatGetArray_SeqDense" 1100 int MatGetArray_SeqDense(Mat A,Scalar **array) 1101 { 1102 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1103 1104 PetscFunctionBegin; 1105 *array = mat->v; 1106 PetscFunctionReturn(0); 1107 } 1108 1109 #undef __FUNC__ 1110 #define __FUNC__ "MatRestoreArray_SeqDense" 1111 int MatRestoreArray_SeqDense(Mat A,Scalar **array) 1112 { 1113 PetscFunctionBegin; 1114 *array = 0; /* user cannot accidently use the array later */ 1115 PetscFunctionReturn(0); 1116 } 1117 1118 #undef __FUNC__ 1119 #define __FUNC__ "MatGetSubMatrix_SeqDense" 1120 static int MatGetSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,int cs,MatReuse scall,Mat *B) 1121 { 1122 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1123 int i, j, ierr, m = mat->m, *irow, *icol, nrows, ncols; 1124 Scalar *av, *bv, *v = mat->v; 1125 Mat newmat; 1126 1127 PetscFunctionBegin; 1128 ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1129 ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1130 ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr); 1131 ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr); 1132 1133 /* Check submatrixcall */ 1134 if (scall == MAT_REUSE_MATRIX) { 1135 int n_cols,n_rows; 1136 ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1137 if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1138 newmat = *B; 1139 } else { 1140 /* Create and fill new matrix */ 1141 ierr = MatCreateSeqDense(A->comm,nrows,ncols,PETSC_NULL,&newmat);CHKERRQ(ierr); 1142 } 1143 1144 /* Now extract the data pointers and do the copy, column at a time */ 1145 bv = ((Mat_SeqDense*)newmat->data)->v; 1146 1147 for ( i=0; i<ncols; i++ ) { 1148 av = v + m*icol[i]; 1149 for (j=0; j<nrows; j++ ) { 1150 *bv++ = av[irow[j]]; 1151 } 1152 } 1153 1154 /* Assemble the matrices so that the correct flags are set */ 1155 ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1156 ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1157 1158 /* Free work space */ 1159 ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1160 ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1161 *B = newmat; 1162 PetscFunctionReturn(0); 1163 } 1164 1165 #undef __FUNC__ 1166 #define __FUNC__ "MatGetSubMatrices_SeqDense" 1167 int MatGetSubMatrices_SeqDense(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B) 1168 { 1169 int ierr,i; 1170 1171 PetscFunctionBegin; 1172 if (scall == MAT_INITIAL_MATRIX) { 1173 *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) );CHKPTRQ(*B); 1174 } 1175 1176 for ( i=0; i<n; i++ ) { 1177 ierr = MatGetSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1178 } 1179 PetscFunctionReturn(0); 1180 } 1181 1182 #undef __FUNC__ 1183 #define __FUNC__ "MatCopy_SeqDense" 1184 int MatCopy_SeqDense(Mat A, Mat B,MatStructure str) 1185 { 1186 Mat_SeqDense *a = (Mat_SeqDense *) A->data, *b = (Mat_SeqDense *)B->data; 1187 int ierr; 1188 1189 PetscFunctionBegin; 1190 if (B->type != MATSEQDENSE) { 1191 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1192 PetscFunctionReturn(0); 1193 } 1194 if (a->m != b->m || a->n != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"size(B) != size(A)"); 1195 ierr = PetscMemcpy(b->v,a->v,a->m*a->n*sizeof(Scalar));CHKERRQ(ierr); 1196 PetscFunctionReturn(0); 1197 } 1198 1199 /* -------------------------------------------------------------------*/ 1200 static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 1201 MatGetRow_SeqDense, 1202 MatRestoreRow_SeqDense, 1203 MatMult_SeqDense, 1204 MatMultAdd_SeqDense, 1205 MatMultTrans_SeqDense, 1206 MatMultTransAdd_SeqDense, 1207 MatSolve_SeqDense, 1208 MatSolveAdd_SeqDense, 1209 MatSolveTrans_SeqDense, 1210 MatSolveTransAdd_SeqDense, 1211 MatLUFactor_SeqDense, 1212 MatCholeskyFactor_SeqDense, 1213 MatRelax_SeqDense, 1214 MatTranspose_SeqDense, 1215 MatGetInfo_SeqDense, 1216 MatEqual_SeqDense, 1217 MatGetDiagonal_SeqDense, 1218 MatDiagonalScale_SeqDense, 1219 MatNorm_SeqDense, 1220 0, 1221 0, 1222 0, 1223 MatSetOption_SeqDense, 1224 MatZeroEntries_SeqDense, 1225 MatZeroRows_SeqDense, 1226 MatLUFactorSymbolic_SeqDense, 1227 MatLUFactorNumeric_SeqDense, 1228 MatCholeskyFactorSymbolic_SeqDense, 1229 MatCholeskyFactorNumeric_SeqDense, 1230 MatGetSize_SeqDense, 1231 MatGetSize_SeqDense, 1232 MatGetOwnershipRange_SeqDense, 1233 0, 1234 0, 1235 MatGetArray_SeqDense, 1236 MatRestoreArray_SeqDense, 1237 MatDuplicate_SeqDense, 1238 0, 1239 0, 1240 0, 1241 0, 1242 MatAXPY_SeqDense, 1243 MatGetSubMatrices_SeqDense, 1244 0, 1245 MatGetValues_SeqDense, 1246 MatCopy_SeqDense, 1247 0, 1248 MatScale_SeqDense, 1249 0, 1250 0, 1251 0, 1252 MatGetBlockSize_SeqDense, 1253 0, 1254 0, 1255 0, 1256 0, 1257 0, 1258 0, 1259 0, 1260 0, 1261 0, 1262 0, 1263 0, 1264 0, 1265 MatGetMaps_Petsc}; 1266 1267 #undef __FUNC__ 1268 #define __FUNC__ "MatCreateSeqDense" 1269 /*@C 1270 MatCreateSeqDense - Creates a sequential dense matrix that 1271 is stored in column major order (the usual Fortran 77 manner). Many 1272 of the matrix operations use the BLAS and LAPACK routines. 1273 1274 Collective on MPI_Comm 1275 1276 Input Parameters: 1277 + comm - MPI communicator, set to PETSC_COMM_SELF 1278 . m - number of rows 1279 . n - number of columns 1280 - data - optional location of matrix data. Set data=PETSC_NULL for PETSc 1281 to control all matrix memory allocation. 1282 1283 Output Parameter: 1284 . A - the matrix 1285 1286 Notes: 1287 The data input variable is intended primarily for Fortran programmers 1288 who wish to allocate their own matrix memory space. Most users should 1289 set data=PETSC_NULL. 1290 1291 Level: intermediate 1292 1293 .keywords: dense, matrix, LAPACK, BLAS 1294 1295 .seealso: MatCreate(), MatCreateMPIDense(), MatSetValues() 1296 @*/ 1297 int MatCreateSeqDense(MPI_Comm comm,int m,int n,Scalar *data,Mat *A) 1298 { 1299 Mat B; 1300 Mat_SeqDense *b; 1301 int ierr,flg,size; 1302 1303 PetscFunctionBegin; 1304 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1305 if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1306 1307 *A = 0; 1308 PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQDENSE,"Mat",comm,MatDestroy,MatView); 1309 PLogObjectCreate(B); 1310 b = (Mat_SeqDense *) PetscMalloc(sizeof(Mat_SeqDense));CHKPTRQ(b); 1311 ierr = PetscMemzero(b,sizeof(Mat_SeqDense));CHKERRQ(ierr); 1312 ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 1313 B->ops->destroy = MatDestroy_SeqDense; 1314 B->ops->view = MatView_SeqDense; 1315 B->factor = 0; 1316 B->mapping = 0; 1317 PLogObjectMemory(B,sizeof(struct _p_Mat)); 1318 B->data = (void *) b; 1319 1320 b->m = m; B->m = m; B->M = m; 1321 b->n = n; B->n = n; B->N = n; 1322 1323 ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 1324 ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 1325 1326 b->pivots = 0; 1327 b->roworiented = 1; 1328 if (data == PETSC_NULL) { 1329 b->v = (Scalar*) PetscMalloc((m*n+1)*sizeof(Scalar));CHKPTRQ(b->v); 1330 ierr = PetscMemzero(b->v,m*n*sizeof(Scalar));CHKERRQ(ierr); 1331 b->user_alloc = 0; 1332 PLogObjectMemory(B,n*m*sizeof(Scalar)); 1333 } else { /* user-allocated storage */ 1334 b->v = data; 1335 b->user_alloc = 1; 1336 } 1337 ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 1338 if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr);} 1339 1340 *A = B; 1341 PetscFunctionReturn(0); 1342 } 1343 1344 1345 1346 1347 1348 1349