xref: /petsc/src/mat/utils/getcolv.c (revision a873a8cd69acc6fd9b12ad3d6b30ee1bf0a81da9)
10925cdddSBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/matimpl.h>  /*I   "petscmat.h"  I*/
30925cdddSBarry Smith 
40925cdddSBarry Smith /*@
582bf6240SBarry Smith    MatGetColumnVector - Gets the values from a given column of a matrix.
60925cdddSBarry Smith 
772257631SBarry Smith    Not Collective
8fee21e36SBarry Smith 
998a79cdbSBarry Smith    Input Parameters:
105ed6d96aSBarry Smith +  A - the matrix
115ed6d96aSBarry Smith .  yy - the vector
12b7e53d48SBarry Smith -  col - the column requested (in global numbering)
1398a79cdbSBarry Smith 
1415091d37SBarry Smith    Level: advanced
1515091d37SBarry Smith 
169d006df2SBarry Smith    Notes:
179a971ab9SStefano Zampini    If a Mat type does not implement the operation, each processor for which this is called
189a971ab9SStefano Zampini    gets the values for its rows using MatGetRow().
199d006df2SBarry Smith 
203d81755aSBarry Smith    The vector must have the same parallel row layout as the matrix.
213d81755aSBarry Smith 
2282bf6240SBarry Smith    Contributed by: Denis Vanderstraeten
230925cdddSBarry Smith 
249a971ab9SStefano Zampini .seealso: MatGetRow(), MatGetDiagonal(), MatMult()
2515091d37SBarry Smith 
260925cdddSBarry Smith @*/
277087cfbeSBarry Smith PetscErrorCode  MatGetColumnVector(Mat A,Vec yy,PetscInt col)
280925cdddSBarry Smith {
298aa348c1SBarry Smith   PetscScalar       *y;
30b3cc6726SBarry Smith   const PetscScalar *v;
31dfbe8321SBarry Smith   PetscErrorCode    ierr;
3238baddfdSBarry Smith   PetscInt          i,j,nz,N,Rs,Re,rs,re;
3338baddfdSBarry Smith   const PetscInt    *idx;
340925cdddSBarry Smith 
350925cdddSBarry Smith   PetscFunctionBegin;
360700a824SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
370700a824SBarry Smith   PetscValidHeaderSpecific(yy,VEC_CLASSID,2);
389a971ab9SStefano Zampini   PetscValidLogicalCollectiveInt(A,col,3);
399a971ab9SStefano Zampini   if (col < 0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Requested negative column: %D",col);
400298fd71SBarry Smith   ierr = MatGetSize(A,NULL,&N);CHKERRQ(ierr);
419a971ab9SStefano Zampini   if (col >= N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Requested column %D larger than number columns in matrix %D",col,N);
4282bf6240SBarry Smith   ierr = MatGetOwnershipRange(A,&Rs,&Re);CHKERRQ(ierr);
4382bf6240SBarry Smith   ierr = VecGetOwnershipRange(yy,&rs,&re);CHKERRQ(ierr);
44e32f2f54SBarry Smith   if (Rs != rs || Re != re) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Matrix %D %D does not have same ownership range (size) as vector %D %D",Rs,Re,rs,re);
4582bf6240SBarry Smith 
468d0534beSBarry Smith   if (A->ops->getcolumnvector) {
478d0534beSBarry Smith     ierr = (*A->ops->getcolumnvector)(A,yy,col);CHKERRQ(ierr);
488d0534beSBarry Smith   } else {
498aa348c1SBarry Smith     ierr = VecSet(yy,0.0);CHKERRQ(ierr);
5082bf6240SBarry Smith     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
519a971ab9SStefano Zampini     /* TODO for general matrices */
5282bf6240SBarry Smith     for (i=Rs; i<Re; i++) {
5382bf6240SBarry Smith       ierr = MatGetRow(A,i,&nz,&idx,&v);CHKERRQ(ierr);
5482bf6240SBarry Smith       if (nz && idx[0] <= col) {
5582bf6240SBarry Smith         /*
5682bf6240SBarry Smith           Should use faster search here
5782bf6240SBarry Smith         */
5882bf6240SBarry Smith         for (j=0; j<nz; j++) {
5982bf6240SBarry Smith           if (idx[j] >= col) {
6082bf6240SBarry Smith             if (idx[j] == col) y[i-rs] = v[j];
6182bf6240SBarry Smith             break;
620925cdddSBarry Smith           }
630925cdddSBarry Smith         }
640925cdddSBarry Smith       }
6582bf6240SBarry Smith       ierr = MatRestoreRow(A,i,&nz,&idx,&v);CHKERRQ(ierr);
660925cdddSBarry Smith     }
6782bf6240SBarry Smith     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
688d0534beSBarry Smith   }
690925cdddSBarry Smith   PetscFunctionReturn(0);
700925cdddSBarry Smith }
71242f1d38SBarry Smith 
7286819fdcSBarry Smith /*@
730716a85fSBarry Smith     MatGetColumnNorms - Gets the norms of each column of a sparse or dense matrix.
74242f1d38SBarry Smith 
75242f1d38SBarry Smith   Input Parameter:
76242f1d38SBarry Smith +  A - the matrix
77242f1d38SBarry Smith -  type - NORM_2, NORM_1 or NORM_INFINITY
78242f1d38SBarry Smith 
79242f1d38SBarry Smith   Output Parameter:
80242f1d38SBarry Smith .  norms - an array as large as the TOTAL number of columns in the matrix
81242f1d38SBarry Smith 
82f6680f47SSatish Balay    Level: intermediate
83f6680f47SSatish Balay 
8495452b02SPatrick Sanan    Notes:
8595452b02SPatrick Sanan     Each process has ALL the column norms after the call. Because of the way this is computed each process gets all the values,
8686819fdcSBarry Smith     if each process wants only some of the values it should extract the ones it wants from the array.
8786819fdcSBarry Smith 
8840b1048aSBarry Smith .seealso: NormType, MatNorm()
8986819fdcSBarry Smith 
9086819fdcSBarry Smith @*/
916b9dab40SJed Brown PetscErrorCode MatGetColumnNorms(Mat A,NormType type,PetscReal norms[])
92242f1d38SBarry Smith {
93242f1d38SBarry Smith   PetscErrorCode ierr;
94*a873a8cdSSam Reynolds   ReductionType reductiontype;
95242f1d38SBarry Smith 
96242f1d38SBarry Smith   PetscFunctionBegin;
97*a873a8cdSSam Reynolds   switch(type) {
98*a873a8cdSSam Reynolds     case NORM_2:
99*a873a8cdSSam Reynolds       reductiontype = REDUCTION_NORM_2;
100*a873a8cdSSam Reynolds       break;
101*a873a8cdSSam Reynolds     case NORM_1:
102*a873a8cdSSam Reynolds       reductiontype = REDUCTION_NORM_1;
103*a873a8cdSSam Reynolds       break;
104*a873a8cdSSam Reynolds     case NORM_FROBENIUS:
105*a873a8cdSSam Reynolds       reductiontype = REDUCTION_NORM_FROBENIUS;
106*a873a8cdSSam Reynolds       break;
107*a873a8cdSSam Reynolds     case NORM_INFINITY:
108*a873a8cdSSam Reynolds       reductiontype = REDUCTION_NORM_INFINITY;
109*a873a8cdSSam Reynolds       break;
110*a873a8cdSSam Reynolds     case NORM_1_AND_2:
111*a873a8cdSSam Reynolds       reductiontype = REDUCTION_NORM_1_AND_2;
112*a873a8cdSSam Reynolds       break;
113*a873a8cdSSam Reynolds     default:
114*a873a8cdSSam Reynolds       SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
115*a873a8cdSSam Reynolds   }
116*a873a8cdSSam Reynolds   ierr = MatGetColumnReductions(A,reductiontype,norms);CHKERRQ(ierr);
117242f1d38SBarry Smith   PetscFunctionReturn(0);
118242f1d38SBarry Smith }
119242f1d38SBarry Smith 
120*a873a8cdSSam Reynolds /*@
121*a873a8cdSSam Reynolds     MatGetColumnReductions - Gets the reductions of each column of a sparse or dense matrix.
122*a873a8cdSSam Reynolds 
123*a873a8cdSSam Reynolds   Input Parameter:
124*a873a8cdSSam Reynolds +  A - the matrix
125*a873a8cdSSam Reynolds -  type - NORM_2, NORM_1, NORM_INFINITY, SUM, MEAN
126*a873a8cdSSam Reynolds 
127*a873a8cdSSam Reynolds   Output Parameter:
128*a873a8cdSSam Reynolds .  reductions - an array as large as the TOTAL number of columns in the matrix
129*a873a8cdSSam Reynolds 
130*a873a8cdSSam Reynolds    Level: intermediate
131*a873a8cdSSam Reynolds 
132*a873a8cdSSam Reynolds    Notes:
133*a873a8cdSSam Reynolds     Each process has ALL the column reductions after the call. Because of the way this is computed each process gets all the values,
134*a873a8cdSSam Reynolds     if each process wants only some of the values it should extract the ones it wants from the array.
135*a873a8cdSSam Reynolds 
136*a873a8cdSSam Reynolds   Developer Note:
137*a873a8cdSSam Reynolds     MatGetColumnNorms() is now implemented using this routine.
138*a873a8cdSSam Reynolds 
139*a873a8cdSSam Reynolds .seealso: NormType, MatGetColumnNorms()
140*a873a8cdSSam Reynolds 
141*a873a8cdSSam Reynolds @*/
142*a873a8cdSSam Reynolds PetscErrorCode MatGetColumnReductions(Mat A,ReductionType type,PetscReal reductions[])
143*a873a8cdSSam Reynolds {
144*a873a8cdSSam Reynolds   PetscErrorCode ierr;
145*a873a8cdSSam Reynolds 
146*a873a8cdSSam Reynolds   PetscFunctionBegin;
147*a873a8cdSSam Reynolds   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
148*a873a8cdSSam Reynolds   if (A->ops->getcolumnreductions) {
149*a873a8cdSSam Reynolds     ierr = (*A->ops->getcolumnreductions)(A,type,reductions);CHKERRQ(ierr);
150*a873a8cdSSam Reynolds   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
151*a873a8cdSSam Reynolds   PetscFunctionReturn(0);
152*a873a8cdSSam Reynolds }
153