blob: 06f4ee591d487a9d7729e42ef07c0a5aec18e337 [file] [log] [blame]
Austin Schuh405fa6c2015-09-06 18:13:55 -07001/* setoper.c:
2 * A set operation library
3 * created by Komei Fukuda, Nov.14, 1993
4 * modified on December 5, 1994
5 (set_card function replaced with a better code by David Bremner)
6 * last modified on June 1, 2000
7 (set_fwrite_compl(), set_groundsize added. set_compl fixed.)
8 */
9
10#include "setoper.h"
11
12#include <limits.h>
13#define SETBITS (sizeof(long) * CHAR_BIT)
14/* (Number of chars in a long) * (number of bits in a char) */
15
16/* Definitions for optimized set_card function
17 by David Bremner bremner@cs.mcgill.ca
18*/
19
20/* Caution!!!
21 Bremner's technique depends on the assumption that CHAR_BIT == 8.
22*/
23
24#define LUTBLOCKS(set) (((set[0]-1)/SETBITS+1)*(sizeof(long)/sizeof(set_card_lut_t)))
25
26static unsigned char set_card_lut[]={
270,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
281,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
291,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
302,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
311,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
322,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
332,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
343,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};
35/* End of Definitions for optimized set_card */
36
37unsigned long set_blocks(long len)
38{
39 long blocks=1L;
40
41 if (len>0) blocks=((long)len-1)/SETBITS+2;
42 return blocks;
43}
44
45void set_initialize(set_type *setp, long length)
46/* Make a set with a given bit lengths */
47{
48 long i,forlim1,len;
49
50 if (length<=0) len=1;else len=length;
51 /* if negative length is requested, it generates the shortest length */
52
53 forlim1=set_blocks(len);
54 *setp=(unsigned long *) calloc(forlim1, sizeof i);
55 (*setp)[0]=(unsigned long) len; /* size of the ground set */
56 for (i=1; i<forlim1; i++)
57 (*setp)[i]=0U;
58}
59
60void set_free(set_type set)
61/* Free the space created with the set pointer set*/
62{
63 free(set);
64}
65
66void set_emptyset(set_type set)
67/* Set set to be the emptyset */
68{
69 long i,forlim;
70
71 forlim=set_blocks(set[0])-1;
72 for (i=1; i<=forlim; i++)
73 set[i]=0U;
74}
75
76void set_copy(set_type setcopy,set_type set)
77/* Copy the set set[] to setcopy[] with setcopy[] length */
78{
79 long i,forlim;
80
81 forlim=set_blocks(setcopy[0])-1;
82 for (i=1; i<=forlim; i++)
83 setcopy[i]=set[i];
84}
85
86void set_addelem(set_type set, long elem)
87/* add elem only if it is within the set[] range */
88{
89 long i,j;
90 unsigned long change;
91 unsigned long one=1U;
92
93 if (elem<=set[0])
94 {
95 i=(elem-1)/SETBITS+1;
96 j=(elem-1)%SETBITS;
97 change= one << j; /* put 1 in jth position */
98 set[i]=set[i] | change;
99 }
100}
101
102void set_delelem(set_type set, long elem)
103/* delete elem only if it is within the set[] range */
104{
105 long i,j;
106 unsigned long change;
107 unsigned long one=1U;
108
109 if (elem<=set[0])
110 {
111 i=(elem-1)/SETBITS+1;
112 j=(elem-1)%SETBITS;
113 change=one << j; /* put 1 in jth position */
114 set[i]=(set[i] | change) ^ change;
115 }
116}
117
118void set_int(set_type set,set_type set1,set_type set2)
119/* Set intersection, assuming set1 and set2 have the same length as set */
120{
121 long i,forlim;
122
123 forlim=set_blocks(set[0])-1;
124 for (i=1;i<=forlim;i++)
125 set[i]=(set1[i] & set2[i]);
126}
127
128void set_uni(set_type set,set_type set1,set_type set2)
129/* Set union,assuming set1 and set2 have the same length as set */
130{
131 long i,forlim;
132
133 forlim=set_blocks(set[0])-1;
134 for (i=1;i<=forlim;i++)
135 set[i]=set1[i] | set2[i];
136}
137
138void set_diff(set_type set,set_type set1,set_type set2)
139/* Set difference se1/set2, assuming set1 and set2 have the same length as set */
140{
141 long i,forlim;
142
143 forlim=set_blocks(set[0])-1;
144 for (i=1;i<=forlim;i++)
145 set[i]=set1[i] & (~set2[i]);
146}
147
148void set_compl(set_type set,set_type set1)
149/* set[] will be set to the complement of set1[] */
150{
151 long i,j,l,forlim;
152 unsigned long change;
153 unsigned long one=1U;
154
155 forlim=set_blocks(set[0])-1;
156 for (i=1;i<=forlim;i++)
157 set[i]= ~set1[i];
158
159/* the following is necessary to remove 1's in the unused bits.
160 Bremner's trick counts these bits as well. (000601KF)
161*/
162 l=(set[0]-1)%SETBITS; /* the position of the last elem in the last block */
163 for (j=l+1; j<=SETBITS-1; j++){
164 change=one << j;
165 set[forlim]=(set[forlim] | change) ^ change;
166 }
167}
168
169int set_subset(set_type set1,set_type set2)
170/* Set containment check, set1 <= set2 */
171{
172 int yes=1;
173 long i,forlim;
174
175 forlim=set_blocks(set2[0])-1;
176 for (i=1;i<=forlim && yes;i++)
177 if ((set1[i] | set2[i])!=set2[i])
178 yes=0;
179 return yes;
180}
181
182int set_member(long elem, set_type set)
183/* Set membership check, elem in set */
184{
185 int yes=0;
186 long i,j;
187 unsigned long testset;
188 unsigned long one=1U;
189
190 if (elem<=set[0])
191 {
192 i=(elem-1)/SETBITS+1;
193 j=(elem-1)%SETBITS;
194 testset=set[i] | (one<<j); /* add elem to set[i] */
195 if (testset==set[i])
196 yes=1;
197 }
198 return yes;
199}
200
201/*set cardinality, modified by David Bremner bremner@cs.mcgill.ca
202 to optimize for speed.*/
203long set_card(set_type set)
204{
205 unsigned long block;
206 long car=0;
207 set_card_lut_t *p;
208
209 p=(set_card_lut_t *)&set[1];
210 for (block=0; block< LUTBLOCKS(set);block++) {
211 car+=set_card_lut[p[block]];
212 }
213 return car;
214}
215
216/* old safe cardinality code
217long set_card(set_type set)
218{
219 long elem,car=0;
220
221 for (elem=1; elem<=set[0]; elem++) {
222 if (set_member(elem,set)) car++;
223 }
224 return car;
225}
226*/
227
228long set_groundsize(set_type set)
229{
230 return set[0];
231}
232
233void set_write(set_type set)
234{
235 long elem;
236
237 for (elem=1;elem<=set[0];elem++)
238 {
239 if (set_member(elem,set))
240 printf("%ld ",elem);
241 }
242 printf("\n");
243}
244
245void set_fwrite(FILE *f,set_type set)
246{
247 long elem;
248
249 for (elem=1;elem<=set[0];elem++)
250 {
251 if (set_member(elem,set))
252 fprintf(f,"%ld ",elem);
253 }
254 fprintf(f,"\n");
255}
256
257void set_fwrite_compl(FILE *f,set_type set)
258{
259 long elem;
260
261 for (elem=1;elem<=set[0];elem++)
262 {
263 if (!set_member(elem,set))
264 fprintf(f,"%ld ",elem);
265 }
266 fprintf(f,"\n");
267}
268
269void set_binwrite(set_type set)
270{
271 int i,j;
272 long forlim;
273 unsigned long e1,e2;
274
275 printf("max element = %ld,\n",set[0]);
276 forlim=set_blocks(set[0])-1;
277 for (i=forlim;i>=1;i--)
278 {
279 e1=e2=set[i];
280 for (j=SETBITS-1;j>=0;j--)
281 {
282 e1=(e1>>j);
283 printf("%1ld",e1);
284 e1=e2-(e1<<j);
285 e2=e1;
286 }
287 printf(" ");
288 }
289 printf("\n");
290}
291
292
293void set_fbinwrite(FILE *f,set_type set)
294{
295 int i,j;
296 long forlim;
297 long e1,e2;
298
299 printf("max element = %ld,\n",set[0]);
300 forlim=set_blocks(set[0])-1;
301 for (i=forlim;i>=1;i--)
302 {
303 e1=e2=set[i];
304 for (j=SETBITS-1;j>=0;j--)
305 {
306 e1=(e1>>j);
307 fprintf(f,"%1ld",e1);
308 e1=e2-(e1<<j);
309 e2=e1;
310 }
311 fprintf(f," ");
312 }
313 fprintf(f,"\n");
314}
315
316/* End of the library: setoper.c */