1 #ifdef PETSC_RCS_HEADER 2 static char vcid[] = "$Id: dense.c,v 1.170 1999/05/12 03:28:59 bsmith Exp balay $"; 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; 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 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 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 (indexn[j] < 0) {v += m; continue;} 488 #if defined(PETSC_USE_BOPT_g) 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 (indexm[i] < 0) {v++; continue;} 493 #if defined(PETSC_USE_BOPT_g) 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 (indexn[j] < 0) {v += m; continue;} 502 #if defined(PETSC_USE_BOPT_g) 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 (indexm[i] < 0) {v++; continue;} 507 #if defined(PETSC_USE_BOPT_g) 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 (indexm[i] < 0) { v += n; continue;} 518 #if defined(PETSC_USE_BOPT_g) 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 (indexn[j] < 0) { v++; continue;} 523 #if defined(PETSC_USE_BOPT_g) 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 (indexm[i] < 0) { v += n; continue;} 532 #if defined(PETSC_USE_BOPT_g) 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 (indexn[j] < 0) { v++; continue;} 537 #if defined(PETSC_USE_BOPT_g) 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 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 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);CHKERRQ(ierr); 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(PETSC_USE_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(PETSC_USE_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(PETSC_USE_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,SOCKET_VIEWER)) { 781 ierr = ViewerSocketPutScalar_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(PETSC_USE_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, ierr; 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 ierr = PetscMemcpy(v,w,m*n*sizeof(Scalar));CHKERRQ(ierr); 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 Mat tmat; 856 Mat_SeqDense *tmatd; 857 Scalar *v2; 858 ierr = MatCreateSeqDense(A->comm,mat->n,mat->m,PETSC_NULL,&tmat);CHKERRQ(ierr); 859 tmatd = (Mat_SeqDense *) tmat->data; 860 v = mat->v; v2 = tmatd->v; 861 for ( j=0; j<n; j++ ) { 862 for ( k=0; k<m; k++ ) v2[j + k*n] = v[k + j*m]; 863 } 864 ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 865 ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 866 *matout = tmat; 867 } 868 PetscFunctionReturn(0); 869 } 870 871 #undef __FUNC__ 872 #define __FUNC__ "MatEqual_SeqDense" 873 int MatEqual_SeqDense(Mat A1,Mat A2, PetscTruth *flg) 874 { 875 Mat_SeqDense *mat1 = (Mat_SeqDense *) A1->data; 876 Mat_SeqDense *mat2 = (Mat_SeqDense *) A2->data; 877 int i; 878 Scalar *v1 = mat1->v, *v2 = mat2->v; 879 880 PetscFunctionBegin; 881 if (A2->type != MATSEQDENSE) SETERRQ(PETSC_ERR_SUP,0,"Matrices should be of type MATSEQDENSE"); 882 if (mat1->m != mat2->m) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 883 if (mat1->n != mat2->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 884 for ( i=0; i<mat1->m*mat1->n; i++ ) { 885 if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 886 v1++; v2++; 887 } 888 *flg = PETSC_TRUE; 889 PetscFunctionReturn(0); 890 } 891 892 #undef __FUNC__ 893 #define __FUNC__ "MatGetDiagonal_SeqDense" 894 int MatGetDiagonal_SeqDense(Mat A,Vec v) 895 { 896 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 897 int ierr,i, n, len; 898 Scalar *x, zero = 0.0; 899 900 PetscFunctionBegin; 901 ierr = VecSet(&zero,v);CHKERRQ(ierr); 902 ierr = VecGetSize(v,&n);CHKERRQ(ierr); 903 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 904 len = PetscMin(mat->m,mat->n); 905 if (n != mat->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming mat and vec"); 906 for ( i=0; i<len; i++ ) { 907 x[i] = mat->v[i*mat->m + i]; 908 } 909 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 910 PetscFunctionReturn(0); 911 } 912 913 #undef __FUNC__ 914 #define __FUNC__ "MatDiagonalScale_SeqDense" 915 int MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr) 916 { 917 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 918 Scalar *l,*r,x,*v; 919 int ierr,i,j,m = mat->m, n = mat->n; 920 921 PetscFunctionBegin; 922 if (ll) { 923 ierr = VecGetSize(ll,&m);CHKERRQ(ierr); 924 ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 925 if (m != mat->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vec wrong size"); 926 for ( i=0; i<m; i++ ) { 927 x = l[i]; 928 v = mat->v + i; 929 for ( j=0; j<n; j++ ) { (*v) *= x; v+= m;} 930 } 931 ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 932 PLogFlops(n*m); 933 } 934 if (rr) { 935 ierr = VecGetSize(rr,&n);CHKERRQ(ierr); 936 ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 937 if (n != mat->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vec wrong size"); 938 for ( i=0; i<n; i++ ) { 939 x = r[i]; 940 v = mat->v + i*m; 941 for ( j=0; j<m; j++ ) { (*v++) *= x;} 942 } 943 ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 944 PLogFlops(n*m); 945 } 946 PetscFunctionReturn(0); 947 } 948 949 #undef __FUNC__ 950 #define __FUNC__ "MatNorm_SeqDense" 951 int MatNorm_SeqDense(Mat A,NormType type,double *norm) 952 { 953 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 954 Scalar *v = mat->v; 955 double sum = 0.0; 956 int i, j; 957 958 PetscFunctionBegin; 959 if (type == NORM_FROBENIUS) { 960 for (i=0; i<mat->n*mat->m; i++ ) { 961 #if defined(PETSC_USE_COMPLEX) 962 sum += PetscReal(PetscConj(*v)*(*v)); v++; 963 #else 964 sum += (*v)*(*v); v++; 965 #endif 966 } 967 *norm = sqrt(sum); 968 PLogFlops(2*mat->n*mat->m); 969 } else if (type == NORM_1) { 970 *norm = 0.0; 971 for ( j=0; j<mat->n; j++ ) { 972 sum = 0.0; 973 for ( i=0; i<mat->m; i++ ) { 974 sum += PetscAbsScalar(*v); v++; 975 } 976 if (sum > *norm) *norm = sum; 977 } 978 PLogFlops(mat->n*mat->m); 979 } else if (type == NORM_INFINITY) { 980 *norm = 0.0; 981 for ( j=0; j<mat->m; j++ ) { 982 v = mat->v + j; 983 sum = 0.0; 984 for ( i=0; i<mat->n; i++ ) { 985 sum += PetscAbsScalar(*v); v += mat->m; 986 } 987 if (sum > *norm) *norm = sum; 988 } 989 PLogFlops(mat->n*mat->m); 990 } else { 991 SETERRQ(PETSC_ERR_SUP,0,"No two norm"); 992 } 993 PetscFunctionReturn(0); 994 } 995 996 #undef __FUNC__ 997 #define __FUNC__ "MatSetOption_SeqDense" 998 int MatSetOption_SeqDense(Mat A,MatOption op) 999 { 1000 Mat_SeqDense *aij = (Mat_SeqDense *) A->data; 1001 1002 PetscFunctionBegin; 1003 if (op == MAT_ROW_ORIENTED) aij->roworiented = 1; 1004 else if (op == MAT_COLUMN_ORIENTED) aij->roworiented = 0; 1005 else if (op == MAT_ROWS_SORTED || 1006 op == MAT_ROWS_UNSORTED || 1007 op == MAT_COLUMNS_SORTED || 1008 op == MAT_COLUMNS_UNSORTED || 1009 op == MAT_SYMMETRIC || 1010 op == MAT_STRUCTURALLY_SYMMETRIC || 1011 op == MAT_NO_NEW_NONZERO_LOCATIONS || 1012 op == MAT_YES_NEW_NONZERO_LOCATIONS || 1013 op == MAT_NEW_NONZERO_LOCATION_ERR || 1014 op == MAT_NO_NEW_DIAGONALS || 1015 op == MAT_YES_NEW_DIAGONALS || 1016 op == MAT_IGNORE_OFF_PROC_ENTRIES || 1017 op == MAT_USE_HASH_TABLE) 1018 PLogInfo(A,"MatSetOption_SeqDense:Option ignored\n"); 1019 else { 1020 SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1021 } 1022 PetscFunctionReturn(0); 1023 } 1024 1025 #undef __FUNC__ 1026 #define __FUNC__ "MatZeroEntries_SeqDense" 1027 int MatZeroEntries_SeqDense(Mat A) 1028 { 1029 Mat_SeqDense *l = (Mat_SeqDense *) A->data; 1030 int ierr; 1031 1032 PetscFunctionBegin; 1033 ierr = PetscMemzero(l->v,l->m*l->n*sizeof(Scalar));CHKERRQ(ierr); 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 *array = 0; /* user cannot accidently use the array later */ 1110 PetscFunctionReturn(0); 1111 } 1112 1113 #undef __FUNC__ 1114 #define __FUNC__ "MatGetSubMatrix_SeqDense" 1115 static int MatGetSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,int cs,MatReuse scall,Mat *B) 1116 { 1117 Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 1118 int i, j, ierr, m = mat->m, *irow, *icol, nrows, ncols; 1119 Scalar *av, *bv, *v = mat->v; 1120 Mat newmat; 1121 1122 PetscFunctionBegin; 1123 ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1124 ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1125 ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr); 1126 ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr); 1127 1128 /* Check submatrixcall */ 1129 if (scall == MAT_REUSE_MATRIX) { 1130 int n_cols,n_rows; 1131 ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1132 if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1133 newmat = *B; 1134 } else { 1135 /* Create and fill new matrix */ 1136 ierr = MatCreateSeqDense(A->comm,nrows,ncols,PETSC_NULL,&newmat);CHKERRQ(ierr); 1137 } 1138 1139 /* Now extract the data pointers and do the copy, column at a time */ 1140 bv = ((Mat_SeqDense*)newmat->data)->v; 1141 1142 for ( i=0; i<ncols; i++ ) { 1143 av = v + m*icol[i]; 1144 for (j=0; j<nrows; j++ ) { 1145 *bv++ = av[irow[j]]; 1146 } 1147 } 1148 1149 /* Assemble the matrices so that the correct flags are set */ 1150 ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1151 ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1152 1153 /* Free work space */ 1154 ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1155 ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1156 *B = newmat; 1157 PetscFunctionReturn(0); 1158 } 1159 1160 #undef __FUNC__ 1161 #define __FUNC__ "MatGetSubMatrices_SeqDense" 1162 int MatGetSubMatrices_SeqDense(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B) 1163 { 1164 int ierr,i; 1165 1166 PetscFunctionBegin; 1167 if (scall == MAT_INITIAL_MATRIX) { 1168 *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) );CHKPTRQ(*B); 1169 } 1170 1171 for ( i=0; i<n; i++ ) { 1172 ierr = MatGetSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1173 } 1174 PetscFunctionReturn(0); 1175 } 1176 1177 #undef __FUNC__ 1178 #define __FUNC__ "MatCopy_SeqDense" 1179 int MatCopy_SeqDense(Mat A, Mat B,MatStructure str) 1180 { 1181 Mat_SeqDense *a = (Mat_SeqDense *) A->data, *b = (Mat_SeqDense *)B->data; 1182 int ierr; 1183 1184 PetscFunctionBegin; 1185 if (B->type != MATSEQDENSE) { 1186 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1187 PetscFunctionReturn(0); 1188 } 1189 if (a->m != b->m || a->n != b->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"size(B) != size(A)"); 1190 ierr = PetscMemcpy(b->v,a->v,a->m*a->n*sizeof(Scalar));CHKERRQ(ierr); 1191 PetscFunctionReturn(0); 1192 } 1193 1194 /* -------------------------------------------------------------------*/ 1195 static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 1196 MatGetRow_SeqDense, 1197 MatRestoreRow_SeqDense, 1198 MatMult_SeqDense, 1199 MatMultAdd_SeqDense, 1200 MatMultTrans_SeqDense, 1201 MatMultTransAdd_SeqDense, 1202 MatSolve_SeqDense, 1203 MatSolveAdd_SeqDense, 1204 MatSolveTrans_SeqDense, 1205 MatSolveTransAdd_SeqDense, 1206 MatLUFactor_SeqDense, 1207 MatCholeskyFactor_SeqDense, 1208 MatRelax_SeqDense, 1209 MatTranspose_SeqDense, 1210 MatGetInfo_SeqDense, 1211 MatEqual_SeqDense, 1212 MatGetDiagonal_SeqDense, 1213 MatDiagonalScale_SeqDense, 1214 MatNorm_SeqDense, 1215 0, 1216 0, 1217 0, 1218 MatSetOption_SeqDense, 1219 MatZeroEntries_SeqDense, 1220 MatZeroRows_SeqDense, 1221 MatLUFactorSymbolic_SeqDense, 1222 MatLUFactorNumeric_SeqDense, 1223 MatCholeskyFactorSymbolic_SeqDense, 1224 MatCholeskyFactorNumeric_SeqDense, 1225 MatGetSize_SeqDense, 1226 MatGetSize_SeqDense, 1227 MatGetOwnershipRange_SeqDense, 1228 0, 1229 0, 1230 MatGetArray_SeqDense, 1231 MatRestoreArray_SeqDense, 1232 MatDuplicate_SeqDense, 1233 0, 1234 0, 1235 0, 1236 0, 1237 MatAXPY_SeqDense, 1238 MatGetSubMatrices_SeqDense, 1239 0, 1240 MatGetValues_SeqDense, 1241 MatCopy_SeqDense, 1242 0, 1243 MatScale_SeqDense, 1244 0, 1245 0, 1246 0, 1247 MatGetBlockSize_SeqDense, 1248 0, 1249 0, 1250 0, 1251 0, 1252 0, 1253 0, 1254 0, 1255 0, 1256 0, 1257 0, 1258 0, 1259 0, 1260 MatGetMaps_Petsc}; 1261 1262 #undef __FUNC__ 1263 #define __FUNC__ "MatCreateSeqDense" 1264 /*@C 1265 MatCreateSeqDense - Creates a sequential dense matrix that 1266 is stored in column major order (the usual Fortran 77 manner). Many 1267 of the matrix operations use the BLAS and LAPACK routines. 1268 1269 Collective on MPI_Comm 1270 1271 Input Parameters: 1272 + comm - MPI communicator, set to PETSC_COMM_SELF 1273 . m - number of rows 1274 . n - number of columns 1275 - data - optional location of matrix data. Set data=PETSC_NULL for PETSc 1276 to control all matrix memory allocation. 1277 1278 Output Parameter: 1279 . A - the matrix 1280 1281 Notes: 1282 The data input variable is intended primarily for Fortran programmers 1283 who wish to allocate their own matrix memory space. Most users should 1284 set data=PETSC_NULL. 1285 1286 Level: intermediate 1287 1288 .keywords: dense, matrix, LAPACK, BLAS 1289 1290 .seealso: MatCreate(), MatCreateMPIDense(), MatSetValues() 1291 @*/ 1292 int MatCreateSeqDense(MPI_Comm comm,int m,int n,Scalar *data,Mat *A) 1293 { 1294 Mat B; 1295 Mat_SeqDense *b; 1296 int ierr,flg,size; 1297 1298 PetscFunctionBegin; 1299 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1300 if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1301 1302 *A = 0; 1303 PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQDENSE,"Mat",comm,MatDestroy,MatView); 1304 PLogObjectCreate(B); 1305 b = (Mat_SeqDense *) PetscMalloc(sizeof(Mat_SeqDense));CHKPTRQ(b); 1306 ierr = PetscMemzero(b,sizeof(Mat_SeqDense));CHKERRQ(ierr); 1307 ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 1308 B->ops->destroy = MatDestroy_SeqDense; 1309 B->ops->view = MatView_SeqDense; 1310 B->factor = 0; 1311 B->mapping = 0; 1312 PLogObjectMemory(B,sizeof(struct _p_Mat)); 1313 B->data = (void *) b; 1314 1315 b->m = m; B->m = m; B->M = m; 1316 b->n = n; B->n = n; B->N = n; 1317 1318 ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 1319 ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 1320 1321 b->pivots = 0; 1322 b->roworiented = 1; 1323 if (data == PETSC_NULL) { 1324 b->v = (Scalar*) PetscMalloc((m*n+1)*sizeof(Scalar));CHKPTRQ(b->v); 1325 ierr = PetscMemzero(b->v,m*n*sizeof(Scalar));CHKERRQ(ierr); 1326 b->user_alloc = 0; 1327 PLogObjectMemory(B,n*m*sizeof(Scalar)); 1328 } else { /* user-allocated storage */ 1329 b->v = data; 1330 b->user_alloc = 1; 1331 } 1332 ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 1333 if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr);} 1334 1335 *A = B; 1336 PetscFunctionReturn(0); 1337 } 1338 1339 1340 1341 1342 1343 1344