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 petscbt.h

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

  9:    Collective on IS

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

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

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

 23:    Level: intermediate

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

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

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


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

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

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

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

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

 96:    Collective on IS

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

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

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

110:    Level: intermediate

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

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

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


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

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

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

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