xref: /petsc/src/mat/impls/normal/normm.c (revision db090513750e512db36c746fd2b7b9368f9e7cc5)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
2c8a8475eSBarry Smith 
3c8a8475eSBarry Smith #include "src/mat/matimpl.h"          /*I "petscmat.h" I*/
4c8a8475eSBarry Smith 
5c8a8475eSBarry Smith typedef struct {
6c8a8475eSBarry Smith   Mat A;
7c8a8475eSBarry Smith   Vec w;
8c8a8475eSBarry Smith } Mat_Normal;
9c8a8475eSBarry Smith 
10c8a8475eSBarry Smith #undef __FUNCT__
11c8a8475eSBarry Smith #define __FUNCT__ "MatMult_Normal"
12dfbe8321SBarry Smith PetscErrorCode MatMult_Normal(Mat N,Vec x,Vec y)
13c8a8475eSBarry Smith {
14c8a8475eSBarry Smith   Mat_Normal     *Na = (Mat_Normal*)N->data;
15dfbe8321SBarry Smith   PetscErrorCode ierr;
16c8a8475eSBarry Smith 
17c8a8475eSBarry Smith   PetscFunctionBegin;
18c8a8475eSBarry Smith   ierr = MatMult(Na->A,x,Na->w);CHKERRQ(ierr);
19c8a8475eSBarry Smith   ierr = MatMultTranspose(Na->A,Na->w,y);CHKERRQ(ierr);
20c8a8475eSBarry Smith   PetscFunctionReturn(0);
21c8a8475eSBarry Smith }
22c8a8475eSBarry Smith 
23c8a8475eSBarry Smith #undef __FUNCT__
24*db090513SMatthew Knepley #define __FUNCT__ "MatMultAdd_Normal"
25*db090513SMatthew Knepley PetscErrorCode MatMultAdd_Normal(Mat N,Vec v1,Vec v2,Vec v3)
26*db090513SMatthew Knepley {
27*db090513SMatthew Knepley   Mat_Normal     *Na = (Mat_Normal*)N->data;
28*db090513SMatthew Knepley   PetscErrorCode ierr;
29*db090513SMatthew Knepley 
30*db090513SMatthew Knepley   PetscFunctionBegin;
31*db090513SMatthew Knepley   ierr = MatMult(Na->A,v1,Na->w);CHKERRQ(ierr);
32*db090513SMatthew Knepley   ierr = MatMultTransposeAdd(Na->A,Na->w,v2,v3);CHKERRQ(ierr);
33*db090513SMatthew Knepley   PetscFunctionReturn(0);
34*db090513SMatthew Knepley }
35*db090513SMatthew Knepley 
36*db090513SMatthew Knepley #undef __FUNCT__
37c8a8475eSBarry Smith #define __FUNCT__ "MatDestroy_Normal"
38dfbe8321SBarry Smith PetscErrorCode MatDestroy_Normal(Mat N)
39c8a8475eSBarry Smith {
40c8a8475eSBarry Smith   Mat_Normal     *Na = (Mat_Normal*)N->data;
41dfbe8321SBarry Smith   PetscErrorCode ierr;
42c8a8475eSBarry Smith 
43c8a8475eSBarry Smith   PetscFunctionBegin;
44c8a8475eSBarry Smith   ierr = PetscObjectDereference((PetscObject)Na->A);CHKERRQ(ierr);
45c8a8475eSBarry Smith   ierr = VecDestroy(Na->w);CHKERRQ(ierr);
46c8a8475eSBarry Smith   ierr = PetscFree(Na);CHKERRQ(ierr);
47c8a8475eSBarry Smith   PetscFunctionReturn(0);
48c8a8475eSBarry Smith }
49c8a8475eSBarry Smith 
5017a6fd94SBarry Smith /*
5117a6fd94SBarry Smith       Slow, nonscalable version
5217a6fd94SBarry Smith */
5317a6fd94SBarry Smith #undef __FUNCT__
5417a6fd94SBarry Smith #define __FUNCT__ "MatGetDiagonal_Normal"
55dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_Normal(Mat N,Vec v)
5617a6fd94SBarry Smith {
5717a6fd94SBarry Smith   Mat_Normal        *Na = (Mat_Normal*)N->data;
5817a6fd94SBarry Smith   Mat               A = Na->A;
59dfbe8321SBarry Smith   PetscErrorCode    ierr;
60b24ad042SBarry Smith   PetscInt          i,j,rstart,rend,nnz;
61b24ad042SBarry Smith   const PetscInt    *cols;
6217a6fd94SBarry Smith   PetscScalar       *diag,*work,*values;
63b3cc6726SBarry Smith   const PetscScalar *mvalues;
6417a6fd94SBarry Smith   PetscMap          cmap;
6517a6fd94SBarry Smith 
6617a6fd94SBarry Smith   PetscFunctionBegin;
6717a6fd94SBarry Smith   ierr = PetscMalloc(2*A->N*sizeof(PetscScalar),&diag);CHKERRQ(ierr);
6817a6fd94SBarry Smith   work = diag + A->N;
6917a6fd94SBarry Smith   ierr = PetscMemzero(work,A->N*sizeof(PetscScalar));CHKERRQ(ierr);
7017a6fd94SBarry Smith   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
7117a6fd94SBarry Smith   for (i=rstart; i<rend; i++) {
72b3cc6726SBarry Smith     ierr = MatGetRow(A,i,&nnz,&cols,&mvalues);CHKERRQ(ierr);
7317a6fd94SBarry Smith     for (j=0; j<nnz; j++) {
74b3cc6726SBarry Smith       work[cols[j]] += mvalues[j]*mvalues[j];
7517a6fd94SBarry Smith     }
76b3cc6726SBarry Smith     ierr = MatRestoreRow(A,i,&nnz,&cols,&mvalues);CHKERRQ(ierr);
7717a6fd94SBarry Smith   }
7817a6fd94SBarry Smith   ierr = MPI_Allreduce(work,diag,A->N,MPIU_SCALAR,MPI_SUM,N->comm);CHKERRQ(ierr);
7917a6fd94SBarry Smith   ierr = MatGetPetscMaps(A,PETSC_NULL,&cmap);CHKERRQ(ierr);
8017a6fd94SBarry Smith   ierr = PetscMapGetLocalRange(cmap,&rstart,&rend);CHKERRQ(ierr);
8117a6fd94SBarry Smith   ierr = VecGetArray(v,&values);CHKERRQ(ierr);
8217a6fd94SBarry Smith   ierr = PetscMemcpy(values,diag+rstart,(rend-rstart)*sizeof(PetscScalar));CHKERRQ(ierr);
8317a6fd94SBarry Smith   ierr = VecRestoreArray(v,&values);CHKERRQ(ierr);
8417a6fd94SBarry Smith   ierr = PetscFree(diag);CHKERRQ(ierr);
8517a6fd94SBarry Smith   PetscFunctionReturn(0);
8617a6fd94SBarry Smith }
87c8a8475eSBarry Smith 
88c8a8475eSBarry Smith #undef __FUNCT__
89c8a8475eSBarry Smith #define __FUNCT__ "MatCreateNormal"
90c8a8475eSBarry Smith /*@
91c8a8475eSBarry Smith       MatCreateNormal - Creates a new matrix object that behaves like A'*A.
92c8a8475eSBarry Smith 
93c8a8475eSBarry Smith    Collective on Mat
94c8a8475eSBarry Smith 
95c8a8475eSBarry Smith    Input Parameter:
96c8a8475eSBarry Smith .   A  - the (possibly rectangular) matrix
97c8a8475eSBarry Smith 
98c8a8475eSBarry Smith    Output Parameter:
99c8a8475eSBarry Smith .   N - the matrix that represents A'*A
100c8a8475eSBarry Smith 
101c30e7cdbSSatish Balay    Level: intermediate
102c30e7cdbSSatish Balay 
103c8a8475eSBarry Smith    Notes: The product A'*A is NOT actually formed! Rather the new matrix
104c8a8475eSBarry Smith           object performs the matrix-vector product by first multiplying by
105c8a8475eSBarry Smith           A and then A'
106c8a8475eSBarry Smith @*/
107be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateNormal(Mat A,Mat *N)
108c8a8475eSBarry Smith {
109dfbe8321SBarry Smith   PetscErrorCode ierr;
110b24ad042SBarry Smith   PetscInt       m,n;
111c8a8475eSBarry Smith   Mat_Normal     *Na;
112c8a8475eSBarry Smith 
113c8a8475eSBarry Smith   PetscFunctionBegin;
114c8a8475eSBarry Smith   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
115f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,N);CHKERRQ(ierr);
116f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*N,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr);
117c8a8475eSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)*N,MATNORMAL);CHKERRQ(ierr);
118c8a8475eSBarry Smith 
119c8a8475eSBarry Smith   ierr      = PetscNew(Mat_Normal,&Na);CHKERRQ(ierr);
120c8a8475eSBarry Smith   Na->A     = A;
121c8a8475eSBarry Smith   ierr      = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
122c8a8475eSBarry Smith   (*N)->data = (void*) Na;
123c8a8475eSBarry Smith 
124c8a8475eSBarry Smith   ierr    = VecCreateMPI(A->comm,m,PETSC_DECIDE,&Na->w);CHKERRQ(ierr);
125c8a8475eSBarry Smith   (*N)->ops->destroy     = MatDestroy_Normal;
126c8a8475eSBarry Smith   (*N)->ops->mult        = MatMult_Normal;
127*db090513SMatthew Knepley   (*N)->ops->multadd     = MatMultAdd_Normal;
12817a6fd94SBarry Smith   (*N)->ops->getdiagonal = MatGetDiagonal_Normal;
129c8a8475eSBarry Smith   (*N)->assembled        = PETSC_TRUE;
130c8a8475eSBarry Smith   (*N)->N                = A->N;
131c8a8475eSBarry Smith   (*N)->M                = A->N;
132c8a8475eSBarry Smith   (*N)->n                = A->n;
133c8a8475eSBarry Smith   (*N)->m                = A->n;
134c8a8475eSBarry Smith   PetscFunctionReturn(0);
135c8a8475eSBarry Smith }
136c8a8475eSBarry Smith 
137