1*ceb9aaf7SBarry Smith #define PETSCMAT_DLL 2*ceb9aaf7SBarry Smith 3*ceb9aaf7SBarry Smith #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 4*ceb9aaf7SBarry Smith 5*ceb9aaf7SBarry Smith typedef struct { 6*ceb9aaf7SBarry Smith Mat A; 7*ceb9aaf7SBarry Smith Vec w; 8*ceb9aaf7SBarry Smith } Mat_Normal; 9*ceb9aaf7SBarry Smith 10*ceb9aaf7SBarry Smith #undef __FUNCT__ 11*ceb9aaf7SBarry Smith #define __FUNCT__ "MatMult_Normal" 12*ceb9aaf7SBarry Smith PetscErrorCode MatMult_Normal(Mat N,Vec x,Vec y) 13*ceb9aaf7SBarry Smith { 14*ceb9aaf7SBarry Smith Mat_Normal *Na = (Mat_Normal*)N->data; 15*ceb9aaf7SBarry Smith PetscErrorCode ierr; 16*ceb9aaf7SBarry Smith 17*ceb9aaf7SBarry Smith PetscFunctionBegin; 18*ceb9aaf7SBarry Smith ierr = MatMult(Na->A,x,Na->w);CHKERRQ(ierr); 19*ceb9aaf7SBarry Smith ierr = MatMultTranspose(Na->A,Na->w,y);CHKERRQ(ierr); 20*ceb9aaf7SBarry Smith PetscFunctionReturn(0); 21*ceb9aaf7SBarry Smith } 22*ceb9aaf7SBarry Smith 23*ceb9aaf7SBarry Smith #undef __FUNCT__ 24*ceb9aaf7SBarry Smith #define __FUNCT__ "MatDestroy_Normal" 25*ceb9aaf7SBarry Smith PetscErrorCode MatDestroy_Normal(Mat N) 26*ceb9aaf7SBarry Smith { 27*ceb9aaf7SBarry Smith Mat_Normal *Na = (Mat_Normal*)N->data; 28*ceb9aaf7SBarry Smith PetscErrorCode ierr; 29*ceb9aaf7SBarry Smith 30*ceb9aaf7SBarry Smith PetscFunctionBegin; 31*ceb9aaf7SBarry Smith ierr = PetscObjectDereference((PetscObject)Na->A);CHKERRQ(ierr); 32*ceb9aaf7SBarry Smith ierr = VecDestroy(Na->w);CHKERRQ(ierr); 33*ceb9aaf7SBarry Smith ierr = PetscFree(Na);CHKERRQ(ierr); 34*ceb9aaf7SBarry Smith PetscFunctionReturn(0); 35*ceb9aaf7SBarry Smith } 36*ceb9aaf7SBarry Smith 37*ceb9aaf7SBarry Smith /* 38*ceb9aaf7SBarry Smith Slow, nonscalable version 39*ceb9aaf7SBarry Smith */ 40*ceb9aaf7SBarry Smith #undef __FUNCT__ 41*ceb9aaf7SBarry Smith #define __FUNCT__ "MatGetDiagonal_Normal" 42*ceb9aaf7SBarry Smith PetscErrorCode MatGetDiagonal_Normal(Mat N,Vec v) 43*ceb9aaf7SBarry Smith { 44*ceb9aaf7SBarry Smith Mat_Normal *Na = (Mat_Normal*)N->data; 45*ceb9aaf7SBarry Smith Mat A = Na->A; 46*ceb9aaf7SBarry Smith PetscErrorCode ierr; 47*ceb9aaf7SBarry Smith PetscInt i,j,rstart,rend,nnz; 48*ceb9aaf7SBarry Smith const PetscInt *cols; 49*ceb9aaf7SBarry Smith PetscScalar *diag,*work,*values; 50*ceb9aaf7SBarry Smith const PetscScalar *mvalues; 51*ceb9aaf7SBarry Smith PetscMap cmap; 52*ceb9aaf7SBarry Smith 53*ceb9aaf7SBarry Smith PetscFunctionBegin; 54*ceb9aaf7SBarry Smith ierr = PetscMalloc(2*A->N*sizeof(PetscScalar),&diag);CHKERRQ(ierr); 55*ceb9aaf7SBarry Smith work = diag + A->N; 56*ceb9aaf7SBarry Smith ierr = PetscMemzero(work,A->N*sizeof(PetscScalar));CHKERRQ(ierr); 57*ceb9aaf7SBarry Smith ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 58*ceb9aaf7SBarry Smith for (i=rstart; i<rend; i++) { 59*ceb9aaf7SBarry Smith ierr = MatGetRow(A,i,&nnz,&cols,&mvalues);CHKERRQ(ierr); 60*ceb9aaf7SBarry Smith for (j=0; j<nnz; j++) { 61*ceb9aaf7SBarry Smith work[cols[j]] += mvalues[j]*mvalues[j]; 62*ceb9aaf7SBarry Smith } 63*ceb9aaf7SBarry Smith ierr = MatRestoreRow(A,i,&nnz,&cols,&mvalues);CHKERRQ(ierr); 64*ceb9aaf7SBarry Smith } 65*ceb9aaf7SBarry Smith ierr = MPI_Allreduce(work,diag,A->N,MPIU_SCALAR,MPI_SUM,N->comm);CHKERRQ(ierr); 66*ceb9aaf7SBarry Smith ierr = MatGetPetscMaps(A,PETSC_NULL,&cmap);CHKERRQ(ierr); 67*ceb9aaf7SBarry Smith ierr = PetscMapGetLocalRange(cmap,&rstart,&rend);CHKERRQ(ierr); 68*ceb9aaf7SBarry Smith ierr = VecGetArray(v,&values);CHKERRQ(ierr); 69*ceb9aaf7SBarry Smith ierr = PetscMemcpy(values,diag+rstart,(rend-rstart)*sizeof(PetscScalar));CHKERRQ(ierr); 70*ceb9aaf7SBarry Smith ierr = VecRestoreArray(v,&values);CHKERRQ(ierr); 71*ceb9aaf7SBarry Smith ierr = PetscFree(diag);CHKERRQ(ierr); 72*ceb9aaf7SBarry Smith PetscFunctionReturn(0); 73*ceb9aaf7SBarry Smith } 74*ceb9aaf7SBarry Smith 75*ceb9aaf7SBarry Smith #undef __FUNCT__ 76*ceb9aaf7SBarry Smith #define __FUNCT__ "MatCreateNormal" 77*ceb9aaf7SBarry Smith /*@ 78*ceb9aaf7SBarry Smith MatCreateNormal - Creates a new matrix object that behaves like A'*A. 79*ceb9aaf7SBarry Smith 80*ceb9aaf7SBarry Smith Collective on Mat 81*ceb9aaf7SBarry Smith 82*ceb9aaf7SBarry Smith Input Parameter: 83*ceb9aaf7SBarry Smith . A - the (possibly rectangular) matrix 84*ceb9aaf7SBarry Smith 85*ceb9aaf7SBarry Smith Output Parameter: 86*ceb9aaf7SBarry Smith . N - the matrix that represents A'*A 87*ceb9aaf7SBarry Smith 88*ceb9aaf7SBarry Smith Level: intermediate 89*ceb9aaf7SBarry Smith 90*ceb9aaf7SBarry Smith Notes: The product A'*A is NOT actually formed! Rather the new matrix 91*ceb9aaf7SBarry Smith object performs the matrix-vector product by first multiplying by 92*ceb9aaf7SBarry Smith A and then A' 93*ceb9aaf7SBarry Smith @*/ 94*ceb9aaf7SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreateNormal(Mat A,Mat *N) 95*ceb9aaf7SBarry Smith { 96*ceb9aaf7SBarry Smith PetscErrorCode ierr; 97*ceb9aaf7SBarry Smith PetscInt m,n; 98*ceb9aaf7SBarry Smith Mat_Normal *Na; 99*ceb9aaf7SBarry Smith 100*ceb9aaf7SBarry Smith PetscFunctionBegin; 101*ceb9aaf7SBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 102*ceb9aaf7SBarry Smith ierr = MatCreate(A->comm,N);CHKERRQ(ierr); 103*ceb9aaf7SBarry Smith ierr = MatSetSizes(*N,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 104*ceb9aaf7SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)*N,MATNORMAL);CHKERRQ(ierr); 105*ceb9aaf7SBarry Smith 106*ceb9aaf7SBarry Smith ierr = PetscNew(Mat_Normal,&Na);CHKERRQ(ierr); 107*ceb9aaf7SBarry Smith Na->A = A; 108*ceb9aaf7SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 109*ceb9aaf7SBarry Smith (*N)->data = (void*) Na; 110*ceb9aaf7SBarry Smith 111*ceb9aaf7SBarry Smith ierr = VecCreateMPI(A->comm,m,PETSC_DECIDE,&Na->w);CHKERRQ(ierr); 112*ceb9aaf7SBarry Smith (*N)->ops->destroy = MatDestroy_Normal; 113*ceb9aaf7SBarry Smith (*N)->ops->mult = MatMult_Normal; 114*ceb9aaf7SBarry Smith (*N)->ops->getdiagonal = MatGetDiagonal_Normal; 115*ceb9aaf7SBarry Smith (*N)->assembled = PETSC_TRUE; 116*ceb9aaf7SBarry Smith (*N)->N = A->N; 117*ceb9aaf7SBarry Smith (*N)->M = A->N; 118*ceb9aaf7SBarry Smith (*N)->n = A->n; 119*ceb9aaf7SBarry Smith (*N)->m = A->n; 120*ceb9aaf7SBarry Smith PetscFunctionReturn(0); 121*ceb9aaf7SBarry Smith } 122*ceb9aaf7SBarry Smith 123