xref: /petsc/src/mat/utils/getcolv.c (revision 95452b02e12c0ee11232c7ff2b24b568a8e07e43)
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
125ed6d96aSBarry Smith -  c - the column requested (in global numbering)
1398a79cdbSBarry Smith 
1415091d37SBarry Smith    Level: advanced
1515091d37SBarry Smith 
169d006df2SBarry Smith    Notes:
179d006df2SBarry Smith    Each processor for which this is called gets the values for its rows.
189d006df2SBarry Smith 
199d006df2SBarry Smith    Since PETSc matrices are usually stored in compressed row format, this routine
209d006df2SBarry Smith    will generally be slow.
219d006df2SBarry Smith 
223d81755aSBarry Smith    The vector must have the same parallel row layout as the matrix.
233d81755aSBarry Smith 
2482bf6240SBarry Smith    Contributed by: Denis Vanderstraeten
250925cdddSBarry Smith 
2682bf6240SBarry Smith .keywords: matrix, column, get
270925cdddSBarry Smith 
2815091d37SBarry Smith .seealso: MatGetRow(), MatGetDiagonal()
2915091d37SBarry Smith 
300925cdddSBarry Smith @*/
317087cfbeSBarry Smith PetscErrorCode  MatGetColumnVector(Mat A,Vec yy,PetscInt col)
320925cdddSBarry Smith {
338aa348c1SBarry Smith   PetscScalar       *y;
34b3cc6726SBarry Smith   const PetscScalar *v;
35dfbe8321SBarry Smith   PetscErrorCode    ierr;
3638baddfdSBarry Smith   PetscInt          i,j,nz,N,Rs,Re,rs,re;
3738baddfdSBarry Smith   const PetscInt    *idx;
380925cdddSBarry Smith 
390925cdddSBarry Smith   PetscFunctionBegin;
400700a824SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
410700a824SBarry Smith   PetscValidHeaderSpecific(yy,VEC_CLASSID,2);
42e32f2f54SBarry Smith   if (col < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requested negative column: %D",col);
430298fd71SBarry Smith   ierr = MatGetSize(A,NULL,&N);CHKERRQ(ierr);
44e32f2f54SBarry Smith   if (col >= N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requested column %D larger than number columns in matrix %D",col,N);
4582bf6240SBarry Smith   ierr = MatGetOwnershipRange(A,&Rs,&Re);CHKERRQ(ierr);
4682bf6240SBarry Smith   ierr = VecGetOwnershipRange(yy,&rs,&re);CHKERRQ(ierr);
47e32f2f54SBarry 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);
4882bf6240SBarry Smith 
498d0534beSBarry Smith   if (A->ops->getcolumnvector) {
508d0534beSBarry Smith     ierr = (*A->ops->getcolumnvector)(A,yy,col);CHKERRQ(ierr);
518d0534beSBarry Smith   } else {
528aa348c1SBarry Smith     ierr = VecSet(yy,0.0);CHKERRQ(ierr);
5382bf6240SBarry Smith     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
5482bf6240SBarry Smith 
5582bf6240SBarry Smith     for (i=Rs; i<Re; i++) {
5682bf6240SBarry Smith       ierr = MatGetRow(A,i,&nz,&idx,&v);CHKERRQ(ierr);
5782bf6240SBarry Smith       if (nz && idx[0] <= col) {
5882bf6240SBarry Smith         /*
5982bf6240SBarry Smith           Should use faster search here
6082bf6240SBarry Smith         */
6182bf6240SBarry Smith         for (j=0; j<nz; j++) {
6282bf6240SBarry Smith           if (idx[j] >= col) {
6382bf6240SBarry Smith             if (idx[j] == col) y[i-rs] = v[j];
6482bf6240SBarry Smith             break;
650925cdddSBarry Smith           }
660925cdddSBarry Smith         }
670925cdddSBarry Smith       }
6882bf6240SBarry Smith       ierr = MatRestoreRow(A,i,&nz,&idx,&v);CHKERRQ(ierr);
690925cdddSBarry Smith     }
7082bf6240SBarry Smith     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
718d0534beSBarry Smith   }
720925cdddSBarry Smith   PetscFunctionReturn(0);
730925cdddSBarry Smith }
74242f1d38SBarry Smith 
75242f1d38SBarry Smith 
76242f1d38SBarry Smith 
77242f1d38SBarry Smith 
7886819fdcSBarry Smith /*@
790716a85fSBarry Smith     MatGetColumnNorms - Gets the norms of each column of a sparse or dense matrix.
80242f1d38SBarry Smith 
81242f1d38SBarry Smith   Input Parameter:
82242f1d38SBarry Smith +  A - the matrix
83242f1d38SBarry Smith -  type - NORM_2, NORM_1 or NORM_INFINITY
84242f1d38SBarry Smith 
85242f1d38SBarry Smith   Output Parameter:
86242f1d38SBarry Smith .  norms - an array as large as the TOTAL number of columns in the matrix
87242f1d38SBarry Smith 
88f6680f47SSatish Balay    Level: intermediate
89f6680f47SSatish Balay 
90*95452b02SPatrick Sanan    Notes:
91*95452b02SPatrick Sanan     Each process has ALL the column norms after the call. Because of the way this is computed each process gets all the values,
9286819fdcSBarry Smith     if each process wants only some of the values it should extract the ones it wants from the array.
9386819fdcSBarry Smith 
9440b1048aSBarry Smith .seealso: NormType, MatNorm()
9586819fdcSBarry Smith 
9686819fdcSBarry Smith @*/
976b9dab40SJed Brown PetscErrorCode MatGetColumnNorms(Mat A,NormType type,PetscReal norms[])
98242f1d38SBarry Smith {
99242f1d38SBarry Smith   PetscErrorCode ierr;
100242f1d38SBarry Smith 
101242f1d38SBarry Smith   PetscFunctionBegin;
1020716a85fSBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1030716a85fSBarry Smith   if (A->ops->getcolumnnorms) {
1040716a85fSBarry Smith     ierr = (*A->ops->getcolumnnorms)(A,type,norms);CHKERRQ(ierr);
105ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
106242f1d38SBarry Smith   PetscFunctionReturn(0);
107242f1d38SBarry Smith }
108242f1d38SBarry Smith 
109