Actual source code: normm.c
1: /*$Id: bvec2.c,v 1.202 2001/09/12 03:26:24 bsmith Exp $*/
3: #include src/mat/matimpl.h
5: typedef struct {
6: Mat A;
7: Vec w;
8: } Mat_Normal;
12: int MatMult_Normal(Mat N,Vec x,Vec y)
13: {
14: Mat_Normal *Na = (Mat_Normal*)N->data;
15: int ierr;
18: MatMult(Na->A,x,Na->w);
19: MatMultTranspose(Na->A,Na->w,y);
20: return(0);
21: }
25: int MatDestroy_Normal(Mat N)
26: {
27: Mat_Normal *Na = (Mat_Normal*)N->data;
28: int ierr;
31: PetscObjectDereference((PetscObject)Na->A);
32: VecDestroy(Na->w);
33: PetscFree(Na);
34: return(0);
35: }
36:
37: /*
38: Slow, nonscalable version
39: */
42: int MatGetDiagonal_Normal(Mat N,Vec v)
43: {
44: Mat_Normal *Na = (Mat_Normal*)N->data;
45: Mat A = Na->A;
46: int ierr,i,j,rstart,rend,nnz,*cols;
47: PetscScalar *diag,*work,*values;
48: PetscMap cmap;
51: PetscMalloc(2*A->N*sizeof(PetscScalar),&diag);
52: work = diag + A->N;
53: PetscMemzero(work,A->N*sizeof(PetscScalar));
54: MatGetOwnershipRange(A,&rstart,&rend);
55: for (i=rstart; i<rend; i++) {
56: MatGetRow(A,i,&nnz,&cols,&values);
57: for (j=0; j<nnz; j++) {
58: work[cols[j]] += values[j]*values[j];
59: }
60: MatRestoreRow(A,i,&nnz,&cols,&values);
61: }
62: MPI_Allreduce(work,diag,A->N,MPIU_SCALAR,MPI_SUM,N->comm);
63: MatGetPetscMaps(A,PETSC_NULL,&cmap);
64: PetscMapGetLocalRange(cmap,&rstart,&rend);
65: VecGetArray(v,&values);
66: PetscMemcpy(values,diag+rstart,(rend-rstart)*sizeof(PetscScalar));
67: VecRestoreArray(v,&values);
68: PetscFree(diag);
69: return(0);
70: }
74: /*@
75: MatCreateNormal - Creates a new matrix object that behaves like A'*A.
77: Collective on Mat
79: Input Parameter:
80: . A - the (possibly rectangular) matrix
82: Output Parameter:
83: . N - the matrix that represents A'*A
85: Notes: The product A'*A is NOT actually formed! Rather the new matrix
86: object performs the matrix-vector product by first multiplying by
87: A and then A'
88: @*/
89: int MatCreateNormal(Mat A,Mat *N)
90: {
91: int ierr,m,n;
92: Mat_Normal *Na;
95: MatGetLocalSize(A,&m,&n);
96: MatCreate(A->comm,n,n,PETSC_DECIDE,PETSC_DECIDE,N);
97: PetscObjectChangeTypeName((PetscObject)*N,MATNORMAL);
98:
99: PetscNew(Mat_Normal,&Na);
100: Na->A = A;
101: PetscObjectReference((PetscObject)A);
102: (*N)->data = (void*) Na;
104: VecCreateMPI(A->comm,m,PETSC_DECIDE,&Na->w);
105: (*N)->ops->destroy = MatDestroy_Normal;
106: (*N)->ops->mult = MatMult_Normal;
107: (*N)->ops->getdiagonal = MatGetDiagonal_Normal;
108: (*N)->assembled = PETSC_TRUE;
109: (*N)->N = A->N;
110: (*N)->M = A->N;
111: (*N)->n = A->n;
112: (*N)->m = A->n;
113: return(0);
114: }