1 #ifdef PETSC_RCS_HEADER 2 static char vcid[] = "$Id: dense.c,v 1.160 1998/12/03 03:59:50 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 PetscMemcpy(l->v,mat->v,mat->m*mat->n*sizeof(Scalar)); 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 PetscMemcpy(l->v,mat->v,mat->m*mat->n*sizeof(Scalar)); 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; 164 165 PetscFunctionBegin; 166 if (mat->pivots) { 167 PetscFree(mat->pivots); 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 PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 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 PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 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 PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 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 PetscMemcpy(y,x,mat->m*sizeof(Scalar)); 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(USE_PETSC_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(USE_PETSC_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(USE_PETSC_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 if (cols) { PetscFree(*cols); } 471 if (vals) { PetscFree(*vals); } 472 PetscFunctionReturn(0); 473 } 474 /* ----------------------------------------------------------------*/ 475 #undef __FUNC__ 476 #define __FUNC__ "MatSetValues_SeqDense" 477 int MatSetValues_SeqDense(Mat A,int m,int *indexm,int n, 478 int *indexn,Scalar *v,InsertMode addv) 479 { 480 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 481 int i,j; 482 483 PetscFunctionBegin; 484 if (!mat->roworiented) { 485 if (addv == INSERT_VALUES) { 486 for ( j=0; j<n; j++ ) { 487 #if defined(USE_PETSC_BOPT_g) 488 if (indexn[j] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 489 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 490 #endif 491 for ( i=0; i<m; i++ ) { 492 #if defined(USE_PETSC_BOPT_g) 493 if (indexm[i] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 494 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 495 #endif 496 mat->v[indexn[j]*mat->m + indexm[i]] = *v++; 497 } 498 } 499 } else { 500 for ( j=0; j<n; j++ ) { 501 #if defined(USE_PETSC_BOPT_g) 502 if (indexn[j] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 503 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 504 #endif 505 for ( i=0; i<m; i++ ) { 506 #if defined(USE_PETSC_BOPT_g) 507 if (indexm[i] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 508 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 509 #endif 510 mat->v[indexn[j]*mat->m + indexm[i]] += *v++; 511 } 512 } 513 } 514 } else { 515 if (addv == INSERT_VALUES) { 516 for ( i=0; i<m; i++ ) { 517 #if defined(USE_PETSC_BOPT_g) 518 if (indexm[i] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 519 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 520 #endif 521 for ( j=0; j<n; j++ ) { 522 #if defined(USE_PETSC_BOPT_g) 523 if (indexn[j] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 524 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 525 #endif 526 mat->v[indexn[j]*mat->m + indexm[i]] = *v++; 527 } 528 } 529 } else { 530 for ( i=0; i<m; i++ ) { 531 #if defined(USE_PETSC_BOPT_g) 532 if (indexm[i] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 533 if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 534 #endif 535 for ( j=0; j<n; j++ ) { 536 #if defined(USE_PETSC_BOPT_g) 537 if (indexn[j] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 538 if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 539 #endif 540 mat->v[indexn[j]*mat->m + indexm[i]] += *v++; 541 } 542 } 543 } 544 } 545 PetscFunctionReturn(0); 546 } 547 548 #undef __FUNC__ 549 #define __FUNC__ "MatGetValues_SeqDense" 550 int MatGetValues_SeqDense(Mat A,int m,int *indexm,int n,int *indexn,Scalar *v) 551 { 552 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 553 int i, j; 554 Scalar *vpt = v; 555 556 PetscFunctionBegin; 557 /* row-oriented output */ 558 for ( i=0; i<m; i++ ) { 559 for ( j=0; j<n; j++ ) { 560 *vpt++ = mat->v[indexn[j]*mat->m + indexm[i]]; 561 } 562 } 563 PetscFunctionReturn(0); 564 } 565 566 /* -----------------------------------------------------------------*/ 567 568 #include "sys.h" 569 570 #undef __FUNC__ 571 #define __FUNC__ "MatLoad_SeqDense" 572 int MatLoad_SeqDense(Viewer viewer,MatType type,Mat *A) 573 { 574 Mat_SeqDense *a; 575 Mat B; 576 int *scols, i, j, nz, ierr, fd, header[4], size; 577 int *rowlengths = 0, M, N, *cols; 578 Scalar *vals, *svals, *v,*w; 579 MPI_Comm comm = ((PetscObject)viewer)->comm; 580 581 PetscFunctionBegin; 582 MPI_Comm_size(comm,&size); 583 if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 584 ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 585 ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 586 if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Not matrix object"); 587 M = header[1]; N = header[2]; nz = header[3]; 588 589 if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */ 590 ierr = MatCreateSeqDense(comm,M,N,PETSC_NULL,A); CHKERRQ(ierr); 591 B = *A; 592 a = (Mat_SeqDense *) B->data; 593 v = a->v; 594 /* Allocate some temp space to read in the values and then flip them 595 from row major to column major */ 596 w = (Scalar *) PetscMalloc((M*N+1)*sizeof(Scalar));CHKPTRQ(w); 597 /* read in nonzero values */ 598 ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR); CHKERRQ(ierr); 599 /* now flip the values and store them in the matrix*/ 600 for ( j=0; j<N; j++ ) { 601 for ( i=0; i<M; i++ ) { 602 *v++ =w[i*N+j]; 603 } 604 } 605 PetscFree(w); 606 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 607 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 608 } else { 609 /* read row lengths */ 610 rowlengths = (int*) PetscMalloc( (M+1)*sizeof(int) ); CHKPTRQ(rowlengths); 611 ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 612 613 /* create our matrix */ 614 ierr = MatCreateSeqDense(comm,M,N,PETSC_NULL,A); CHKERRQ(ierr); 615 B = *A; 616 a = (Mat_SeqDense *) B->data; 617 v = a->v; 618 619 /* read column indices and nonzeros */ 620 cols = scols = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(cols); 621 ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT); CHKERRQ(ierr); 622 vals = svals = (Scalar *) PetscMalloc( (nz+1)*sizeof(Scalar) ); CHKPTRQ(vals); 623 ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR); CHKERRQ(ierr); 624 625 /* insert into matrix */ 626 for ( i=0; i<M; i++ ) { 627 for ( j=0; j<rowlengths[i]; j++ ) v[i+M*scols[j]] = svals[j]; 628 svals += rowlengths[i]; scols += rowlengths[i]; 629 } 630 PetscFree(vals); PetscFree(cols); PetscFree(rowlengths); 631 632 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 633 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 634 } 635 PetscFunctionReturn(0); 636 } 637 638 #include "sys.h" 639 640 #undef __FUNC__ 641 #define __FUNC__ "MatView_SeqDense_ASCII" 642 static int MatView_SeqDense_ASCII(Mat A,Viewer viewer) 643 { 644 Mat_SeqDense *a = (Mat_SeqDense *) A->data; 645 int ierr, i, j, format; 646 FILE *fd; 647 char *outputname; 648 Scalar *v; 649 650 PetscFunctionBegin; 651 ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 652 ierr = ViewerGetOutputname(viewer,&outputname); CHKERRQ(ierr); 653 ierr = ViewerGetFormat(viewer,&format); 654 if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 655 PetscFunctionReturn(0); /* do nothing for now */ 656 } 657 else if (format == VIEWER_FORMAT_ASCII_COMMON) { 658 for ( i=0; i<a->m; i++ ) { 659 v = a->v + i; 660 fprintf(fd,"row %d:",i); 661 for ( j=0; j<a->n; j++ ) { 662 #if defined(USE_PETSC_COMPLEX) 663 if (PetscReal(*v) != 0.0 && PetscImaginary(*v) != 0.0) fprintf(fd," %d %g + %g i",j,PetscReal(*v),PetscImaginary(*v)); 664 else if (PetscReal(*v)) fprintf(fd," %d %g ",j,PetscReal(*v)); 665 #else 666 if (*v) fprintf(fd," %d %g ",j,*v); 667 #endif 668 v += a->m; 669 } 670 fprintf(fd,"\n"); 671 } 672 } else { 673 #if defined(USE_PETSC_COMPLEX) 674 int allreal = 1; 675 /* determine if matrix has all real values */ 676 v = a->v; 677 for ( i=0; i<a->m*a->n; i++ ) { 678 if (PetscImaginary(v[i])) { allreal = 0; break ;} 679 } 680 #endif 681 for ( i=0; i<a->m; i++ ) { 682 v = a->v + i; 683 for ( j=0; j<a->n; j++ ) { 684 #if defined(USE_PETSC_COMPLEX) 685 if (allreal) { 686 fprintf(fd,"%6.4e ",PetscReal(*v)); v += a->m; 687 } else { 688 fprintf(fd,"%6.4e + %6.4e i ",PetscReal(*v),PetscImaginary(*v)); v += a->m; 689 } 690 #else 691 fprintf(fd,"%6.4e ",*v); v += a->m; 692 #endif 693 } 694 fprintf(fd,"\n"); 695 } 696 } 697 fflush(fd); 698 PetscFunctionReturn(0); 699 } 700 701 #undef __FUNC__ 702 #define __FUNC__ "MatView_SeqDense_Binary" 703 static int MatView_SeqDense_Binary(Mat A,Viewer viewer) 704 { 705 Mat_SeqDense *a = (Mat_SeqDense *) A->data; 706 int ict, j, n = a->n, m = a->m, i, fd, *col_lens, ierr, nz = m*n; 707 int format; 708 Scalar *v, *anonz,*vals; 709 710 PetscFunctionBegin; 711 ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 712 713 ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr); 714 if (format == VIEWER_FORMAT_BINARY_NATIVE) { 715 /* store the matrix as a dense matrix */ 716 col_lens = (int *) PetscMalloc( 4*sizeof(int) ); CHKPTRQ(col_lens); 717 col_lens[0] = MAT_COOKIE; 718 col_lens[1] = m; 719 col_lens[2] = n; 720 col_lens[3] = MATRIX_BINARY_FORMAT_DENSE; 721 ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,1); CHKERRQ(ierr); 722 PetscFree(col_lens); 723 724 /* write out matrix, by rows */ 725 vals = (Scalar *) PetscMalloc((m*n+1)*sizeof(Scalar)); CHKPTRQ(vals); 726 v = a->v; 727 for ( i=0; i<m; i++ ) { 728 for ( j=0; j<n; j++ ) { 729 vals[i + j*m] = *v++; 730 } 731 } 732 ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,0); CHKERRQ(ierr); 733 PetscFree(vals); 734 } else { 735 col_lens = (int *) PetscMalloc( (4+nz)*sizeof(int) ); CHKPTRQ(col_lens); 736 col_lens[0] = MAT_COOKIE; 737 col_lens[1] = m; 738 col_lens[2] = n; 739 col_lens[3] = nz; 740 741 /* store lengths of each row and write (including header) to file */ 742 for ( i=0; i<m; i++ ) col_lens[4+i] = n; 743 ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,1); CHKERRQ(ierr); 744 745 /* Possibly should write in smaller increments, not whole matrix at once? */ 746 /* store column indices (zero start index) */ 747 ict = 0; 748 for ( i=0; i<m; i++ ) { 749 for ( j=0; j<n; j++ ) col_lens[ict++] = j; 750 } 751 ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,0); CHKERRQ(ierr); 752 PetscFree(col_lens); 753 754 /* store nonzero values */ 755 anonz = (Scalar *) PetscMalloc((nz+1)*sizeof(Scalar)); CHKPTRQ(anonz); 756 ict = 0; 757 for ( i=0; i<m; i++ ) { 758 v = a->v + i; 759 for ( j=0; j<n; j++ ) { 760 anonz[ict++] = *v; v += a->m; 761 } 762 } 763 ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,0); CHKERRQ(ierr); 764 PetscFree(anonz); 765 } 766 PetscFunctionReturn(0); 767 } 768 769 #undef __FUNC__ 770 #define __FUNC__ "MatView_SeqDense" 771 int MatView_SeqDense(Mat A,Viewer viewer) 772 { 773 Mat_SeqDense *a = (Mat_SeqDense*) A->data; 774 ViewerType vtype; 775 int ierr; 776 777 PetscFunctionBegin; 778 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 779 780 if (PetscTypeCompare(vtype,MATLAB_VIEWER)) { 781 ierr = ViewerMatlabPutScalar_Private(viewer,a->m,a->n,a->v); CHKERRQ(ierr); 782 } else if (PetscTypeCompare(vtype,ASCII_VIEWER)) { 783 ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr); 784 } else if (PetscTypeCompare(vtype,BINARY_VIEWER)) { 785 ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr); 786 } else { 787 SETERRQ(1,1,"Viewer type not supported by PETSc object"); 788 } 789 PetscFunctionReturn(0); 790 } 791 792 #undef __FUNC__ 793 #define __FUNC__ "MatDestroy_SeqDense" 794 int MatDestroy_SeqDense(Mat mat) 795 { 796 Mat_SeqDense *l = (Mat_SeqDense *) mat->data; 797 int ierr; 798 799 PetscFunctionBegin; 800 if (--mat->refct > 0) PetscFunctionReturn(0); 801 802 if (mat->mapping) { 803 ierr = ISLocalToGlobalMappingDestroy(mat->mapping); CHKERRQ(ierr); 804 } 805 if (mat->bmapping) { 806 ierr = ISLocalToGlobalMappingDestroy(mat->bmapping); CHKERRQ(ierr); 807 } 808 #if defined(USE_PETSC_LOG) 809 PLogObjectState((PetscObject)mat,"Rows %d Cols %d",l->m,l->n); 810 #endif 811 if (l->pivots) PetscFree(l->pivots); 812 if (!l->user_alloc) PetscFree(l->v); 813 PetscFree(l); 814 if (mat->rmap) { 815 ierr = MapDestroy(mat->rmap);CHKERRQ(ierr); 816 } 817 if (mat->cmap) { 818 ierr = MapDestroy(mat->cmap);CHKERRQ(ierr); 819 } 820 PLogObjectDestroy(mat); 821 PetscHeaderDestroy(mat); 822 PetscFunctionReturn(0); 823 } 824 825 #undef __FUNC__ 826 #define __FUNC__ "MatTranspose_SeqDense" 827 int MatTranspose_SeqDense(Mat A,Mat *matout) 828 { 829 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 830 int k, j, m, n; 831 Scalar *v, tmp; 832 833 PetscFunctionBegin; 834 v = mat->v; m = mat->m; n = mat->n; 835 if (matout == PETSC_NULL) { /* in place transpose */ 836 if (m != n) { /* malloc temp to hold transpose */ 837 Scalar *w = (Scalar *) PetscMalloc((m+1)*(n+1)*sizeof(Scalar));CHKPTRQ(w); 838 for ( j=0; j<m; j++ ) { 839 for ( k=0; k<n; k++ ) { 840 w[k + j*n] = v[j + k*m]; 841 } 842 } 843 PetscMemcpy(v,w,m*n*sizeof(Scalar)); 844 PetscFree(w); 845 } else { 846 for ( j=0; j<m; j++ ) { 847 for ( k=0; k<j; k++ ) { 848 tmp = v[j + k*n]; 849 v[j + k*n] = v[k + j*n]; 850 v[k + j*n] = tmp; 851 } 852 } 853 } 854 } else { /* out-of-place transpose */ 855 int ierr; 856 Mat tmat; 857 Mat_SeqDense *tmatd; 858 Scalar *v2; 859 ierr = MatCreateSeqDense(A->comm,mat->n,mat->m,PETSC_NULL,&tmat); CHKERRQ(ierr); 860 tmatd = (Mat_SeqDense *) tmat->data; 861 v = mat->v; v2 = tmatd->v; 862 for ( j=0; j<n; j++ ) { 863 for ( k=0; k<m; k++ ) v2[j + k*n] = v[k + j*m]; 864 } 865 ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 866 ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 867 *matout = tmat; 868 } 869 PetscFunctionReturn(0); 870 } 871 872 #undef __FUNC__ 873 #define __FUNC__ "MatEqual_SeqDense" 874 int MatEqual_SeqDense(Mat A1,Mat A2, PetscTruth *flg) 875 { 876 Mat_SeqDense *mat1 = (Mat_SeqDense *) A1->data; 877 Mat_SeqDense *mat2 = (Mat_SeqDense *) A2->data; 878 int i; 879 Scalar *v1 = mat1->v, *v2 = mat2->v; 880 881 PetscFunctionBegin; 882 if (A2->type != MATSEQDENSE) SETERRQ(PETSC_ERR_SUP,0,"Matrices should be of type MATSEQDENSE"); 883 if (mat1->m != mat2->m) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 884 if (mat1->n != mat2->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 885 for ( i=0; i<mat1->m*mat1->n; i++ ) { 886 if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 887 v1++; v2++; 888 } 889 *flg = PETSC_TRUE; 890 PetscFunctionReturn(0); 891 } 892 893 #undef __FUNC__ 894 #define __FUNC__ "MatGetDiagonal_SeqDense" 895 int MatGetDiagonal_SeqDense(Mat A,Vec v) 896 { 897 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 898 int ierr,i, n, len; 899 Scalar *x, zero = 0.0; 900 901 PetscFunctionBegin; 902 ierr = VecSet(&zero,v);CHKERRQ(ierr); 903 ierr = VecGetSize(v,&n);CHKERRQ(ierr); 904 ierr = VecGetArray(v,&x); CHKERRQ(ierr); 905 len = PetscMin(mat->m,mat->n); 906 if (n != mat->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming mat and vec"); 907 for ( i=0; i<len; i++ ) { 908 x[i] = mat->v[i*mat->m + i]; 909 } 910 ierr = VecRestoreArray(v,&x); CHKERRQ(ierr); 911 PetscFunctionReturn(0); 912 } 913 914 #undef __FUNC__ 915 #define __FUNC__ "MatDiagonalScale_SeqDense" 916 int MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr) 917 { 918 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 919 Scalar *l,*r,x,*v; 920 int ierr,i,j,m = mat->m, n = mat->n; 921 922 PetscFunctionBegin; 923 if (ll) { 924 ierr = VecGetSize(ll,&m);CHKERRQ(ierr); 925 ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 926 if (m != mat->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vec wrong size"); 927 for ( i=0; i<m; i++ ) { 928 x = l[i]; 929 v = mat->v + i; 930 for ( j=0; j<n; j++ ) { (*v) *= x; v+= m;} 931 } 932 ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 933 PLogFlops(n*m); 934 } 935 if (rr) { 936 ierr = VecGetSize(rr,&n);CHKERRQ(ierr); 937 ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 938 if (n != mat->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vec wrong size"); 939 for ( i=0; i<n; i++ ) { 940 x = r[i]; 941 v = mat->v + i*m; 942 for ( j=0; j<m; j++ ) { (*v++) *= x;} 943 } 944 ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 945 PLogFlops(n*m); 946 } 947 PetscFunctionReturn(0); 948 } 949 950 #undef __FUNC__ 951 #define __FUNC__ "MatNorm_SeqDense" 952 int MatNorm_SeqDense(Mat A,NormType type,double *norm) 953 { 954 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 955 Scalar *v = mat->v; 956 double sum = 0.0; 957 int i, j; 958 959 PetscFunctionBegin; 960 if (type == NORM_FROBENIUS) { 961 for (i=0; i<mat->n*mat->m; i++ ) { 962 #if defined(USE_PETSC_COMPLEX) 963 sum += PetscReal(PetscConj(*v)*(*v)); v++; 964 #else 965 sum += (*v)*(*v); v++; 966 #endif 967 } 968 *norm = sqrt(sum); 969 PLogFlops(2*mat->n*mat->m); 970 } else if (type == NORM_1) { 971 *norm = 0.0; 972 for ( j=0; j<mat->n; j++ ) { 973 sum = 0.0; 974 for ( i=0; i<mat->m; i++ ) { 975 sum += PetscAbsScalar(*v); v++; 976 } 977 if (sum > *norm) *norm = sum; 978 } 979 PLogFlops(mat->n*mat->m); 980 } else if (type == NORM_INFINITY) { 981 *norm = 0.0; 982 for ( j=0; j<mat->m; j++ ) { 983 v = mat->v + j; 984 sum = 0.0; 985 for ( i=0; i<mat->n; i++ ) { 986 sum += PetscAbsScalar(*v); v += mat->m; 987 } 988 if (sum > *norm) *norm = sum; 989 } 990 PLogFlops(mat->n*mat->m); 991 } else { 992 SETERRQ(PETSC_ERR_SUP,0,"No two norm"); 993 } 994 PetscFunctionReturn(0); 995 } 996 997 #undef __FUNC__ 998 #define __FUNC__ "MatSetOption_SeqDense" 999 int MatSetOption_SeqDense(Mat A,MatOption op) 1000 { 1001 Mat_SeqDense *aij = (Mat_SeqDense *) A->data; 1002 1003 PetscFunctionBegin; 1004 if (op == MAT_ROW_ORIENTED) aij->roworiented = 1; 1005 else if (op == MAT_COLUMN_ORIENTED) aij->roworiented = 0; 1006 else if (op == MAT_ROWS_SORTED || 1007 op == MAT_ROWS_UNSORTED || 1008 op == MAT_COLUMNS_SORTED || 1009 op == MAT_COLUMNS_UNSORTED || 1010 op == MAT_SYMMETRIC || 1011 op == MAT_STRUCTURALLY_SYMMETRIC || 1012 op == MAT_NO_NEW_NONZERO_LOCATIONS || 1013 op == MAT_YES_NEW_NONZERO_LOCATIONS || 1014 op == MAT_NEW_NONZERO_LOCATION_ERROR || 1015 op == MAT_NO_NEW_DIAGONALS || 1016 op == MAT_YES_NEW_DIAGONALS || 1017 op == MAT_IGNORE_OFF_PROC_ENTRIES || 1018 op == MAT_USE_HASH_TABLE) 1019 PLogInfo(A,"MatSetOption_SeqDense:Option ignored\n"); 1020 else { 1021 SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1022 } 1023 PetscFunctionReturn(0); 1024 } 1025 1026 #undef __FUNC__ 1027 #define __FUNC__ "MatZeroEntries_SeqDense" 1028 int MatZeroEntries_SeqDense(Mat A) 1029 { 1030 Mat_SeqDense *l = (Mat_SeqDense *) A->data; 1031 1032 PetscFunctionBegin; 1033 PetscMemzero(l->v,l->m*l->n*sizeof(Scalar)); 1034 PetscFunctionReturn(0); 1035 } 1036 1037 #undef __FUNC__ 1038 #define __FUNC__ "MatGetBlockSize_SeqDense" 1039 int MatGetBlockSize_SeqDense(Mat A,int *bs) 1040 { 1041 PetscFunctionBegin; 1042 *bs = 1; 1043 PetscFunctionReturn(0); 1044 } 1045 1046 #undef __FUNC__ 1047 #define __FUNC__ "MatZeroRows_SeqDense" 1048 int MatZeroRows_SeqDense(Mat A,IS is,Scalar *diag) 1049 { 1050 Mat_SeqDense *l = (Mat_SeqDense *) A->data; 1051 int n = l->n, i, j,ierr,N, *rows; 1052 Scalar *slot; 1053 1054 PetscFunctionBegin; 1055 ierr = ISGetSize(is,&N); CHKERRQ(ierr); 1056 ierr = ISGetIndices(is,&rows); CHKERRQ(ierr); 1057 for ( i=0; i<N; i++ ) { 1058 slot = l->v + rows[i]; 1059 for ( j=0; j<n; j++ ) { *slot = 0.0; slot += n;} 1060 } 1061 if (diag) { 1062 for ( i=0; i<N; i++ ) { 1063 slot = l->v + (n+1)*rows[i]; 1064 *slot = *diag; 1065 } 1066 } 1067 ISRestoreIndices(is,&rows); 1068 PetscFunctionReturn(0); 1069 } 1070 1071 #undef __FUNC__ 1072 #define __FUNC__ "MatGetSize_SeqDense" 1073 int MatGetSize_SeqDense(Mat A,int *m,int *n) 1074 { 1075 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1076 1077 PetscFunctionBegin; 1078 *m = mat->m; *n = mat->n; 1079 PetscFunctionReturn(0); 1080 } 1081 1082 #undef __FUNC__ 1083 #define __FUNC__ "MatGetOwnershipRange_SeqDense" 1084 int MatGetOwnershipRange_SeqDense(Mat A,int *m,int *n) 1085 { 1086 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1087 1088 PetscFunctionBegin; 1089 *m = 0; *n = mat->m; 1090 PetscFunctionReturn(0); 1091 } 1092 1093 #undef __FUNC__ 1094 #define __FUNC__ "MatGetArray_SeqDense" 1095 int MatGetArray_SeqDense(Mat A,Scalar **array) 1096 { 1097 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1098 1099 PetscFunctionBegin; 1100 *array = mat->v; 1101 PetscFunctionReturn(0); 1102 } 1103 1104 #undef __FUNC__ 1105 #define __FUNC__ "MatRestoreArray_SeqDense" 1106 int MatRestoreArray_SeqDense(Mat A,Scalar **array) 1107 { 1108 PetscFunctionBegin; 1109 PetscFunctionReturn(0); 1110 } 1111 1112 #undef __FUNC__ 1113 #define __FUNC__ "MatGetSubMatrix_SeqDense" 1114 static int MatGetSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,int cs,MatGetSubMatrixCall scall,Mat *B) 1115 { 1116 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1117 int i, j, ierr, m = mat->m, *irow, *icol, nrows, ncols; 1118 Scalar *av, *bv, *v = mat->v; 1119 Mat newmat; 1120 1121 PetscFunctionBegin; 1122 ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 1123 ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 1124 ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 1125 ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 1126 1127 /* Check submatrixcall */ 1128 if (scall == MAT_REUSE_MATRIX) { 1129 int n_cols,n_rows; 1130 ierr = MatGetSize(*B,&n_rows,&n_cols); CHKERRQ(ierr); 1131 if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1132 newmat = *B; 1133 } else { 1134 /* Create and fill new matrix */ 1135 ierr = MatCreateSeqDense(A->comm,nrows,ncols,PETSC_NULL,&newmat); CHKERRQ(ierr); 1136 } 1137 1138 /* Now extract the data pointers and do the copy, column at a time */ 1139 bv = ((Mat_SeqDense*)newmat->data)->v; 1140 1141 for ( i=0; i<ncols; i++ ) { 1142 av = v + m*icol[i]; 1143 for (j=0; j<nrows; j++ ) { 1144 *bv++ = av[irow[j]]; 1145 } 1146 } 1147 1148 /* Assemble the matrices so that the correct flags are set */ 1149 ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1150 ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1151 1152 /* Free work space */ 1153 ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 1154 ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 1155 *B = newmat; 1156 PetscFunctionReturn(0); 1157 } 1158 1159 #undef __FUNC__ 1160 #define __FUNC__ "MatGetSubMatrices_SeqDense" 1161 int MatGetSubMatrices_SeqDense(Mat A,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall,Mat **B) 1162 { 1163 int ierr,i; 1164 1165 PetscFunctionBegin; 1166 if (scall == MAT_INITIAL_MATRIX) { 1167 *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) ); CHKPTRQ(*B); 1168 } 1169 1170 for ( i=0; i<n; i++ ) { 1171 ierr = MatGetSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1172 } 1173 PetscFunctionReturn(0); 1174 } 1175 1176 #undef __FUNC__ 1177 #define __FUNC__ "MatCopy_SeqDense" 1178 int MatCopy_SeqDense(Mat A, Mat B,MatStructure str) 1179 { 1180 Mat_SeqDense *a = (Mat_SeqDense *) A->data, *b = (Mat_SeqDense *)B->data; 1181 int ierr; 1182 1183 PetscFunctionBegin; 1184 if (B->type != MATSEQDENSE) { 1185 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1186 PetscFunctionReturn(0); 1187 } 1188 if (a->m != b->m || a->n != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"size(B) != size(A)"); 1189 PetscMemcpy(b->v,a->v,a->m*a->n*sizeof(Scalar)); 1190 PetscFunctionReturn(0); 1191 } 1192 1193 /* -------------------------------------------------------------------*/ 1194 static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 1195 MatGetRow_SeqDense, 1196 MatRestoreRow_SeqDense, 1197 MatMult_SeqDense, 1198 MatMultAdd_SeqDense, 1199 MatMultTrans_SeqDense, 1200 MatMultTransAdd_SeqDense, 1201 MatSolve_SeqDense, 1202 MatSolveAdd_SeqDense, 1203 MatSolveTrans_SeqDense, 1204 MatSolveTransAdd_SeqDense, 1205 MatLUFactor_SeqDense, 1206 MatCholeskyFactor_SeqDense, 1207 MatRelax_SeqDense, 1208 MatTranspose_SeqDense, 1209 MatGetInfo_SeqDense, 1210 MatEqual_SeqDense, 1211 MatGetDiagonal_SeqDense, 1212 MatDiagonalScale_SeqDense, 1213 MatNorm_SeqDense, 1214 0, 1215 0, 1216 0, 1217 MatSetOption_SeqDense, 1218 MatZeroEntries_SeqDense, 1219 MatZeroRows_SeqDense, 1220 MatLUFactorSymbolic_SeqDense, 1221 MatLUFactorNumeric_SeqDense, 1222 MatCholeskyFactorSymbolic_SeqDense, 1223 MatCholeskyFactorNumeric_SeqDense, 1224 MatGetSize_SeqDense, 1225 MatGetSize_SeqDense, 1226 MatGetOwnershipRange_SeqDense, 1227 0, 1228 0, 1229 MatGetArray_SeqDense, 1230 MatRestoreArray_SeqDense, 1231 MatDuplicate_SeqDense, 1232 0, 1233 0, 1234 0, 1235 0, 1236 MatAXPY_SeqDense, 1237 MatGetSubMatrices_SeqDense, 1238 0, 1239 MatGetValues_SeqDense, 1240 MatCopy_SeqDense, 1241 0, 1242 MatScale_SeqDense, 1243 0, 1244 0, 1245 0, 1246 MatGetBlockSize_SeqDense, 1247 0, 1248 0, 1249 0, 1250 0, 1251 0, 1252 0, 1253 0, 1254 0, 1255 0, 1256 0, 1257 0, 1258 0, 1259 MatGetMaps_Petsc}; 1260 1261 #undef __FUNC__ 1262 #define __FUNC__ "MatCreateSeqDense" 1263 /*@C 1264 MatCreateSeqDense - Creates a sequential dense matrix that 1265 is stored in column major order (the usual Fortran 77 manner). Many 1266 of the matrix operations use the BLAS and LAPACK routines. 1267 1268 Collective on MPI_Comm 1269 1270 Input Parameters: 1271 + comm - MPI communicator, set to PETSC_COMM_SELF 1272 . m - number of rows 1273 . n - number of columns 1274 - data - optional location of matrix data. Set data=PETSC_NULL for PETSc 1275 to control all matrix memory allocation. 1276 1277 Output Parameter: 1278 . A - the matrix 1279 1280 Notes: 1281 The data input variable is intended primarily for Fortran programmers 1282 who wish to allocate their own matrix memory space. Most users should 1283 set data=PETSC_NULL. 1284 1285 .keywords: dense, matrix, LAPACK, BLAS 1286 1287 .seealso: MatCreate(), MatCreateMPIDense(), MatSetValues() 1288 @*/ 1289 int MatCreateSeqDense(MPI_Comm comm,int m,int n,Scalar *data,Mat *A) 1290 { 1291 Mat B; 1292 Mat_SeqDense *b; 1293 int ierr,flg,size; 1294 1295 PetscFunctionBegin; 1296 MPI_Comm_size(comm,&size); 1297 if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1298 1299 *A = 0; 1300 PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQDENSE,"Mat",comm,MatDestroy,MatView); 1301 PLogObjectCreate(B); 1302 b = (Mat_SeqDense *) PetscMalloc(sizeof(Mat_SeqDense)); CHKPTRQ(b); 1303 PetscMemzero(b,sizeof(Mat_SeqDense)); 1304 PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 1305 B->ops->destroy = MatDestroy_SeqDense; 1306 B->ops->view = MatView_SeqDense; 1307 B->factor = 0; 1308 B->mapping = 0; 1309 PLogObjectMemory(B,sizeof(struct _p_Mat)); 1310 B->data = (void *) b; 1311 1312 b->m = m; B->m = m; B->M = m; 1313 b->n = n; B->n = n; B->N = n; 1314 1315 ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 1316 ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 1317 1318 b->pivots = 0; 1319 b->roworiented = 1; 1320 if (data == PETSC_NULL) { 1321 b->v = (Scalar*) PetscMalloc((m*n+1)*sizeof(Scalar)); CHKPTRQ(b->v); 1322 PetscMemzero(b->v,m*n*sizeof(Scalar)); 1323 b->user_alloc = 0; 1324 PLogObjectMemory(B,n*m*sizeof(Scalar)); 1325 } else { /* user-allocated storage */ 1326 b->v = data; 1327 b->user_alloc = 1; 1328 } 1329 ierr = OptionsHasName(PETSC_NULL,"-help",&flg); CHKERRQ(ierr); 1330 if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr);} 1331 1332 *A = B; 1333 PetscFunctionReturn(0); 1334 } 1335 1336 1337 1338 1339 1340 1341