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: #undef __FUNCT__  
  8: /*@
  9:    ISDifference - Computes the difference between two index sets.

 11:    Collective on IS

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

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

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

 25:    Level: intermediate

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

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

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


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

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

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

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

 95: #undef __FUNCT__  
 97: /*@
 98:    ISSum - Computes the sum (union) of two index sets.

100:    Collective on IS

102:    Input Parameter:
103: +  is1 - first index set
104: -  is2 - index values to be added

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

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

114:    Level: intermediate

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

118:    Concepts: index sets^difference
119:    Concepts: IS^difference

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


133:   ISGetIndices(is1,&i1);
134:   ISGetLocalSize(is1,&n1);
135:   ISGetIndices(is2,&i2);
136:   ISGetLocalSize(is2,&n2);

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

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

180:   PetscBTDestroy(mask);
181:   return(0);
182: }