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: }