Actual source code: isdiff.c

  1: /*$Id: isdiff.c,v 1.24 2001/03/23 23:21:16 balay Exp $*/

 3:  #include petscis.h
 4:  #include petsc.h
 5:  #include petscbt.h

  7: /*@
  8:    ISDifference - Computes the difference between two index sets.

 10:    Collective on IS

 12:    Input Parameter:
 13: +  is1 - first index, to have items removed from it
 14: -  is2 - index values to be removed

 16:    Output Parameters:
 17: .  isout - is1 - is2

 19:    Notes:
 20:    Negative values are removed from the lists. is2 may have values
 21:    that are not in is1. This requires O(imax-imin) memory and O(imax-imin)
 22:    work, where imin and imax are the bounds on the indices in is1.

 24:    Level: intermediate

 26:    Concepts: index sets^difference
 27:    Concepts: IS^difference

 29: .seealso: ISDestroy(), ISView(), ISSum()

 31: @*/
 32: int ISDifference(IS is1,IS is2,IS *isout)
 33: {
 34:   int      i,ierr,*i1,*i2,n1,n2,imin,imax,nout,*iout;
 35:   PetscBT  mask;
 36:   MPI_Comm comm;


 43:   ISGetIndices(is1,&i1);
 44:   ISGetLocalSize(is1,&n1);

 46:   /* Create a bit mask array to contain required values */
 47:   if (n1) {
 48:     imin = PETSC_MAX_INT;
 49:     imax = 0;
 50:     for (i=0; i<n1; i++) {
 51:       if (i1[i] < 0) continue;
 52:       imin = PetscMin(imin,i1[i]);
 53:       imax = PetscMax(imax,i1[i]);
 54:     }
 55:   } else {
 56:     imin = imax = 0;
 57:   }
 58:   PetscBTCreate(imax-imin,mask);
 59:   /* Put the values from is1 */
 60:   for (i=0; i<n1; i++) {
 61:     if (i1[i] < 0) continue;
 62:     PetscBTSet(mask,i1[i] - imin);
 63:   }
 64:   ISRestoreIndices(is1,&i1);
 65:   /* Remove the values from is2 */
 66:   ISGetIndices(is2,&i2);
 67:   ISGetLocalSize(is2,&n2);
 68:   for (i=0; i<n2; i++) {
 69:     if (i2[i] < imin || i2[i] > imax) continue;
 70:     PetscBTClear(mask,i2[i] - imin);
 71:   }
 72:   ISRestoreIndices(is2,&i2);
 73: 
 74:   /* Count the number in the difference */
 75:   nout = 0;
 76:   for (i=0; i<imax-imin+1; i++) {
 77:     if (PetscBTLookup(mask,i)) nout++;
 78:   }

 80:   /* create the new IS containing the difference */
 81:   PetscMalloc((nout+1)*sizeof(int),&iout);
 82:   nout = 0;
 83:   for (i=0; i<imax-imin+1; i++) {
 84:     if (PetscBTLookup(mask,i)) iout[nout++] = i + imin;
 85:   }
 86:   PetscObjectGetComm((PetscObject)is1,&comm);
 87:   ISCreateGeneral(comm,nout,iout,isout);
 88:   PetscFree(iout);

 90:   PetscBTDestroy(mask);
 91:   return(0);
 92: }

 94: /*@
 95:    ISSum - Computes the sum (union) of two index sets.

 97:    Collective on IS

 99:    Input Parameter:
100: +  is1 - first index set
101: -  is2 - index values to be added

103:    Output Parameters:
104: .  isout - is1 + is2 The index set is2 is appended to is1 removing duplicates

106:    Notes:
107:    Negative values are removed from the lists. This requires O(imax-imin) 
108:    memory and O(imax-imin) work, where imin and imax are the bounds on the 
109:    indices in is1 and is2.

111:    Level: intermediate

113: .seealso: ISDestroy(), ISView(), ISDifference()

115:    Concepts: index sets^difference
116:    Concepts: IS^difference

118: @*/
119: int ISSum(IS is1,IS is2,IS *isout)
120: {
121:   int      i,ierr,*i1,*i2,n1,n2,imin,imax,nout,*iout;
122:   PetscBT  mask;
123:   MPI_Comm comm;


130:   ISGetIndices(is1,&i1);
131:   ISGetLocalSize(is1,&n1);
132:   ISGetIndices(is2,&i2);
133:   ISGetLocalSize(is2,&n2);

135:   /* Create a bit mask array to contain required values */
136:   if (n1 || n2) {
137:     imin = PETSC_MAX_INT;
138:     imax = 0;
139:     for (i=0; i<n1; i++) {
140:       if (i1[i] < 0) continue;
141:       imin = PetscMin(imin,i1[i]);
142:       imax = PetscMax(imax,i1[i]);
143:     }
144:     for (i=0; i<n2; i++) {
145:       if (i2[i] < 0) continue;
146:       imin = PetscMin(imin,i2[i]);
147:       imax = PetscMax(imax,i2[i]);
148:     }
149:   } else {
150:     imin = imax = 0;
151:   }
152:   PetscMalloc((n1+n2+1)*sizeof(int),&iout);
153:   nout = 0;
154:   PetscBTCreate(imax-imin,mask);
155:   /* Put the values from is1 */
156:   for (i=0; i<n1; i++) {
157:     if (i1[i] < 0) continue;
158:     if (!PetscBTLookupSet(mask,i1[i] - imin)) {
159:       iout[nout++] = i1[i];
160:     }
161:   }
162:   ISRestoreIndices(is1,&i1);
163:   /* Put the values from is2 */
164:   for (i=0; i<n2; i++) {
165:     if (i2[i] < 0) continue;
166:     if (!PetscBTLookupSet(mask,i2[i] - imin)) {
167:       iout[nout++] = i2[i];
168:     }
169:   }
170:   ISRestoreIndices(is2,&i2);

172:   /* create the new IS containing the sum */
173:   PetscObjectGetComm((PetscObject)is1,&comm);
174:   ISCreateGeneral(comm,nout,iout,isout);
175:   PetscFree(iout);

177:   PetscBTDestroy(mask);
178:   return(0);
179: }