Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/misc/bitset.pyx
4045 views
1
"""
2
Bitsets
3
4
A Python interface to the fast bitsets in Sage. Bitsets are fast
5
binary sets that store elements by toggling bits in an array of
6
numbers. A bitset can store values between `0` and ``capacity-1``
7
(where ``capacity`` is finite, but arbitrary). The storage cost is
8
linear in ``capacity``.
9
10
.. warning::
11
12
This class is most likely to be useful as a way to store Cython
13
bitsets in Python datastructures, acting on them using the Cython
14
inline functions. If you want to use these classes for a Python
15
set type, the Python ``set`` or ``frozenset`` data types may be
16
faster.
17
"""
18
#*****************************************************************************
19
# Copyright (C) 2009 Jason Grout <[email protected]>
20
#
21
# Distributed under the terms of the GNU General Public License (GPL)
22
#
23
# This code is distributed in the hope that it will be useful,
24
# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26
# General Public License for more details.
27
#
28
# The full text of the GPL is available at:
29
#
30
# http://www.gnu.org/licenses/
31
#*****************************************************************************
32
33
include 'bitset.pxi'
34
35
cdef class FrozenBitset:
36
"""
37
A frozen bitset class which leverages inline Cython functions for creating
38
and manipulating bitsets.
39
40
A bitset can be thought of in two ways. First, as a set of
41
elements from the universe of the `n` natural numbers `0`, `1`,
42
..., `n-1` (where `n`, the capacity, can be specified), with
43
typical set operations (intersection, union, symmetric difference,
44
etc.). Secondly, a bitset can be thought of as a binary vector
45
with typical binary operations (i.e., ``and``, ``or``, ``xor``,
46
etc.). This class supports both interfaces.
47
48
The interface in this class mirrors the interface in the
49
``frozenset`` datatype of Python.
50
51
.. warning::
52
53
This class is most likely to be useful as a way to store
54
Cython bitsets in Python datastructures, acting on them using
55
the Cython inline functions. If you want to use this class
56
for a Python set type, the Python ``frozenset`` data type may
57
be faster.
58
59
EXAMPLES::
60
61
sage: a=FrozenBitset('1101')
62
sage: loads(dumps(a))==a
63
True
64
65
sage: a=FrozenBitset('1101'*64)
66
sage: loads(dumps(a))==a
67
True
68
"""
69
70
def __cinit__(self, iter=None, capacity=None):
71
"""
72
Allocate the bitset.
73
74
EXAMPLES::
75
76
sage: FrozenBitset('1101')
77
1101
78
sage: FrozenBitset('1101'*32)
79
11011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101
80
"""
81
if capacity is None:
82
bitset_init(self._bitset, 1)
83
else:
84
bitset_init(self._bitset, capacity)
85
86
def __dealloc__(self):
87
"""
88
Deallocate the C bitset data structure.
89
90
EXAMPLES::
91
92
sage: a=FrozenBitset('11010')
93
sage: del a
94
sage: b=FrozenBitset('11010'*64)
95
sage: del b
96
"""
97
bitset_free(self._bitset)
98
99
def __init__(self, iter=None, capacity=None):
100
"""
101
Initialize a bitset.
102
103
INPUTS:
104
105
- ``iter`` - initialization parameter. If this is a Bitset, then
106
it is copied. If it is None, then the bitset is set to the
107
empty set. If it is a string, then the bitset is initialized
108
by including an element if the index of the string is '1'. If
109
it is an iterable, then it is assumed to contain a list of
110
integers, and those integers are placed in the set.
111
112
- ``capacity`` - The maximum capacity of the bitset. If this is not
113
specified, then it is automatically calculated from the passed
114
iterable. It must be at least one.
115
116
EXAMPLES::
117
118
sage: FrozenBitset(capacity=3)
119
000
120
sage: FrozenBitset('11011')
121
11011
122
sage: FrozenBitset('110'*32)
123
110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110
124
sage: FrozenBitset([0,3,2])
125
1011
126
sage: FrozenBitset(set([0,3,2]))
127
1011
128
sage: FrozenBitset(FrozenBitset('11011'))
129
11011
130
sage: FrozenBitset([0,3,2], capacity=10)
131
1011000000
132
sage: FrozenBitset([i for i in range(100) if i%2==0])
133
101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
134
135
TESTS:
136
137
The capacity must be at least one::
138
139
sage: FrozenBitset()
140
0
141
142
If capacity is specified, it must match up with the
143
initialization items::
144
145
sage: FrozenBitset('10', capacity=3)
146
Traceback (most recent call last):
147
...
148
ValueError: bitset capacity does not match passed string
149
sage: FrozenBitset([0,3,2], capacity=2)
150
Traceback (most recent call last):
151
...
152
ValueError: bitset capacity does not allow storing the passed iterable
153
sage: FrozenBitset(FrozenBitset('1101'), capacity=2)
154
Traceback (most recent call last):
155
...
156
ValueError: bitset capacity does not match passed bitset
157
sage: FrozenBitset(FrozenBitset('1101'), capacity=5)
158
Traceback (most recent call last):
159
...
160
ValueError: bitset capacity does not match passed bitset
161
"""
162
cdef unsigned long n
163
cdef FrozenBitset b
164
if iter is not None and not isinstance(iter, (str,tuple,list,FrozenBitset,Bitset)):
165
iter = list(iter)
166
167
if iter is None:
168
bitset_clear(self._bitset)
169
elif isinstance(iter, (FrozenBitset, Bitset)):
170
b = iter
171
if capacity is None:
172
bitset_realloc(self._bitset, b._bitset.size)
173
elif self._bitset.size != b._bitset.size:
174
raise ValueError, "bitset capacity does not match passed bitset"
175
bitset_copy(self._bitset, b._bitset)
176
elif isinstance(iter, str):
177
if capacity is None:
178
bitset_realloc(self._bitset, len(iter))
179
elif self._bitset.size != len(iter):
180
raise ValueError, "bitset capacity does not match passed string"
181
bitset_from_str(self._bitset, iter)
182
else: # an iterable
183
iter = list(iter)
184
if len(iter)>0:
185
need_capacity = max(iter)+1
186
else:
187
need_capacity=1
188
if capacity is None:
189
bitset_realloc(self._bitset, need_capacity)
190
elif self._bitset.size < need_capacity:
191
raise ValueError, "bitset capacity does not allow storing the passed iterable"
192
bitset_clear(self._bitset)
193
for n in iter:
194
bitset_add(self._bitset, n)
195
196
cdef FrozenBitset _new(self,long int capacity):
197
"""
198
Return an object of the same type as self, initialized with a bitset of capacity ``capacity``.
199
200
"""
201
cdef FrozenBitset b
202
b = FrozenBitset.__new__(FrozenBitset,None, capacity)
203
return b
204
205
def __getstate__(self):
206
"""
207
Return the current state of the object as a string.
208
209
EXAMPLES::
210
211
sage: FrozenBitset('1101').__getstate__()
212
'1101'
213
sage: FrozenBitset('110'*32).__getstate__()
214
'110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110'
215
216
"""
217
return str(self)
218
219
def __setstate__(self,state):
220
"""
221
Set the state of the object from the string state.
222
223
EXAMPLES::
224
225
sage: a=FrozenBitset()
226
sage: a.__setstate__('1101')
227
sage: a
228
1101
229
sage: a.__setstate__('110'*32)
230
sage: a
231
110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110
232
"""
233
bitset_realloc(self._bitset, len(state))
234
bitset_from_str(self._bitset, state)
235
236
def __iter__(self):
237
"""
238
Return an iterator over self.
239
240
EXAMPLES::
241
242
sage: list(FrozenBitset('11011'))
243
[0, 1, 3, 4]
244
sage: list(FrozenBitset('00001'*20))
245
[4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79, 84, 89, 94, 99]
246
sage: set(FrozenBitset('11011'))
247
set([0, 1, 3, 4])
248
"""
249
return iter(bitset_list(self._bitset))
250
251
252
253
254
cpdef FrozenBitset _larger_capacity_(self, long capacity):
255
"""
256
Return a copy of self where the bitset has the maximum of the
257
current capacity and the capacity passed. If no resizing is needed,
258
return self.
259
260
This function is mainly used to satisfy the assumption of the
261
underlying bitset functions that all bitsets are of the same
262
capacity.
263
264
INPUTS:
265
266
- ``capacity`` - the underlying bitset of the returned bitset
267
will have this capacity if it is bigger than the current
268
capacity.
269
270
271
EXAMPLES::
272
273
sage: a=FrozenBitset('11010')
274
sage: a.capacity()
275
5
276
sage: a._larger_capacity_(4) is a
277
True
278
sage: a._larger_capacity_(5) is a
279
True
280
sage: b=a._larger_capacity_(6)
281
sage: b
282
110100
283
sage: b is a
284
False
285
sage: b.capacity()
286
6
287
sage: c=a._larger_capacity_(98)
288
sage: c
289
11010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
290
sage: c.capacity()
291
98
292
"""
293
cdef FrozenBitset temp
294
if self._bitset.size >= capacity:
295
return self
296
else:
297
temp = self._new(self._bitset.size)
298
bitset_copy(temp._bitset, self._bitset)
299
bitset_realloc(temp._bitset, capacity)
300
return temp
301
302
cpdef long capacity(self):
303
"""
304
Return the size of the underlying bitset. The maximum value
305
that can be stored in the current underlying bitset is
306
``self.capacity()-1``.
307
308
EXAMPLES::
309
310
sage: FrozenBitset('11000').capacity()
311
5
312
sage: FrozenBitset('110'*32).capacity()
313
96
314
sage: FrozenBitset(range(20),capacity=450).capacity()
315
450
316
"""
317
return self._bitset.size
318
319
def __hash__(self):
320
"""
321
Return a hash value for a bitset
322
323
EXAMPLES::
324
325
sage: hash(FrozenBitset(capacity=5))
326
0
327
sage: hash(FrozenBitset('10110'))
328
13
329
sage: hash(FrozenBitset('10110'+'0'*120,capacity=125))
330
13
331
"""
332
cdef long hash
333
hash = bitset_hash(self._bitset)
334
if hash == -1:
335
return 0
336
else:
337
return hash
338
339
cpdef bint isempty(self):
340
"""
341
Return True if the bitset is empty; False otherwise.
342
343
EXAMPLES::
344
345
sage: FrozenBitset().isempty()
346
True
347
sage: FrozenBitset([1]).isempty()
348
False
349
sage: FrozenBitset([],capacity=110).isempty()
350
True
351
sage: FrozenBitset(range(99)).isempty()
352
False
353
"""
354
return bitset_isempty(self._bitset)
355
356
def __richcmp__(FrozenBitset self, FrozenBitset other not None, int op):
357
"""
358
Implement comparisons, using the Cython richcmp convention.
359
Comparison is done by inclusion (a set is less than another if
360
it is a subset).
361
362
EXAMPLES::
363
364
sage: FrozenBitset('11') < FrozenBitset('101')
365
False
366
sage: FrozenBitset('11') <= FrozenBitset('110')
367
True
368
sage: FrozenBitset('11') != FrozenBitset('10')
369
True
370
sage: FrozenBitset('11') == FrozenBitset('10')
371
False
372
sage: FrozenBitset('11') == FrozenBitset('110')
373
True
374
sage: FrozenBitset('11') > FrozenBitset('10')
375
True
376
sage: FrozenBitset('11') >= FrozenBitset('10')
377
True
378
sage: FrozenBitset('11') < FrozenBitset('110'*32)
379
True
380
"""
381
cdef FrozenBitset left, right
382
383
if self._bitset.size == other._bitset.size:
384
left = self
385
right = other
386
elif self._bitset.size < other._bitset.size:
387
left = self._larger_capacity_(other._bitset.size)
388
right = other
389
else:
390
left = self
391
right = other._larger_capacity_(self._bitset.size)
392
393
if op == 2: # ==
394
return bitset_eq(left._bitset, right._bitset)
395
elif op == 3: # !=
396
return not bitset_eq(left._bitset, right._bitset)
397
elif op == 0: # <
398
return bitset_issubset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
399
elif op == 1: # <=
400
return bitset_issubset(left._bitset, right._bitset)
401
elif op == 4: # >
402
return bitset_issuperset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
403
elif op == 5: # >=
404
return bitset_issuperset(left._bitset, right._bitset)
405
406
cpdef bint issubset(self, FrozenBitset other):
407
"""
408
Test to see if the self is a subset of other.
409
410
EXAMPLES::
411
412
sage: FrozenBitset('11').issubset(FrozenBitset('01'))
413
False
414
sage: FrozenBitset('01').issubset(FrozenBitset('11'))
415
True
416
sage: FrozenBitset('01').issubset(FrozenBitset('01'*45))
417
True
418
"""
419
if other is None:
420
raise ValueError, "other can not be None"
421
cdef FrozenBitset left, right
422
if self._bitset.size == other._bitset.size:
423
left = self
424
right = other
425
elif self._bitset.size < other._bitset.size:
426
left = self._larger_capacity_(other._bitset.size)
427
right = other
428
else:
429
left = self
430
right = other._larger_capacity_(self._bitset.size)
431
432
return bitset_issubset(left._bitset, right._bitset)
433
434
cpdef bint issuperset(self, FrozenBitset other):
435
"""
436
Test to see if the self is a superset of other.
437
438
EXAMPLES::
439
440
sage: FrozenBitset('11').issuperset(FrozenBitset('01'))
441
True
442
sage: FrozenBitset('01').issuperset(FrozenBitset('11'))
443
False
444
sage: FrozenBitset('01').issuperset(FrozenBitset('10'*45))
445
False
446
"""
447
if other is None:
448
raise ValueError, "other can not be None"
449
cdef FrozenBitset left, right
450
if self._bitset.size == other._bitset.size:
451
left = self
452
right = other
453
elif self._bitset.size < other._bitset.size:
454
left = self._larger_capacity_(other._bitset.size)
455
right = other
456
else:
457
left = self
458
right = other._larger_capacity_(self._bitset.size)
459
460
return bitset_issuperset(left._bitset, right._bitset)
461
462
cpdef bint isdisjoint(self, FrozenBitset other):
463
"""
464
Test to see if the self is disjoint from other.
465
466
EXAMPLES::
467
468
sage: FrozenBitset('11').isdisjoint(FrozenBitset('01'))
469
False
470
sage: FrozenBitset('01').isdisjoint(FrozenBitset('001'))
471
True
472
sage: FrozenBitset('00101').isdisjoint(FrozenBitset('110'*35))
473
False
474
"""
475
cdef bint retval
476
if other is None:
477
raise ValueError, "other can not be None"
478
cdef FrozenBitset smaller, larger
479
cdef bitset_t temp
480
if self._bitset.size == other._bitset.size:
481
bitset_init(temp, self._bitset.size)
482
bitset_intersection(temp, self._bitset, other._bitset)
483
retval = bitset_isempty(temp)
484
bitset_free(temp)
485
return retval
486
elif self._bitset.size < other._bitset.size:
487
smaller = self
488
larger = other
489
else:
490
smaller = other
491
larger = self
492
493
bitset_init(temp, smaller._bitset.size)
494
bitset_copy(temp, smaller._bitset)
495
bitset_realloc(temp, larger._bitset.size)
496
bitset_intersection(temp, temp, larger._bitset)
497
retval = bitset_isempty(temp)
498
bitset_free(temp)
499
return retval
500
501
def __contains__(self, unsigned long n):
502
"""
503
Test to see if the `n` is in self.
504
505
EXAMPLES::
506
507
sage: 0 in FrozenBitset([0,1])
508
True
509
sage: 0 in FrozenBitset([1,2])
510
False
511
sage: 10 in FrozenBitset([0,1])
512
False
513
sage: 121 in FrozenBitset('110'*50)
514
True
515
sage: 122 in FrozenBitset('110'*50)
516
False
517
"""
518
if n < self._bitset.size:
519
return bitset_in(self._bitset, n)
520
else:
521
return False
522
523
def __len__(self):
524
"""
525
Return the number of elements in the bitset (which may be
526
different from the capacity of the bitset).
527
528
EXAMPLES::
529
530
sage: len(FrozenBitset([0,1],capacity=10))
531
2
532
sage: len(FrozenBitset(range(98)))
533
98
534
"""
535
return bitset_len(self._bitset)
536
537
def __str__(self):
538
"""
539
Return a string representing the bitset as a binary vector.
540
541
EXAMPLES::
542
543
sage: a=FrozenBitset('10110')
544
sage: str(a)
545
'10110'
546
sage: str(FrozenBitset('110'*32))
547
'110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110'
548
"""
549
return bitset_string(self._bitset)
550
551
def __repr__(self):
552
"""
553
Return a string representing the bitset as a binary vector.
554
555
EXAMPLES::
556
557
sage: a=FrozenBitset('10110')
558
sage: repr(a)
559
'10110'
560
sage: repr(FrozenBitset('110'*32))
561
'110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110'
562
"""
563
return self.__str__()
564
565
cpdef _union(self, FrozenBitset other):
566
"""
567
Return the union of self and other.
568
569
In order to get a Cython "union" function, we have to use the
570
underscore since "union" is a C keyword.
571
572
EXAMPLES::
573
574
sage: FrozenBitset('10101')._union(FrozenBitset('11100'))
575
11101
576
sage: FrozenBitset('10101'*10)._union(FrozenBitset('01010'*10))
577
11111111111111111111111111111111111111111111111111
578
579
TESTS::
580
581
sage: set(FrozenBitset('10101'*10)._union(FrozenBitset('01010'*10)))==set(FrozenBitset('10101'*10)).union(FrozenBitset('01010'*10))
582
True
583
sage: set(FrozenBitset('10101')._union(FrozenBitset('01010'*20)))==set(FrozenBitset('10101')).union(FrozenBitset('01010'*20))
584
True
585
sage: set(FrozenBitset('10101'*20)._union(FrozenBitset('01010')))==set(FrozenBitset('10101'*20)).union(FrozenBitset('01010'))
586
True
587
"""
588
if other is None:
589
raise ValueError, "other can not be None"
590
cdef FrozenBitset temp, smaller, larger
591
if self._bitset.size <= other._bitset.size:
592
smaller = self
593
larger = other
594
else:
595
smaller = other
596
larger = self
597
598
temp = self._new(smaller._bitset.size)
599
bitset_copy(temp._bitset, smaller._bitset)
600
bitset_realloc(temp._bitset, larger._bitset.size)
601
bitset_union(temp._bitset, temp._bitset, larger._bitset)
602
return temp
603
604
def union(self, FrozenBitset other):
605
"""
606
Return the union of self and other.
607
608
EXAMPLES::
609
610
sage: FrozenBitset('10101').union(FrozenBitset('11100'))
611
11101
612
sage: FrozenBitset('10101'*10).union(FrozenBitset('01010'*10))
613
11111111111111111111111111111111111111111111111111
614
615
TESTS::
616
617
sage: set(FrozenBitset('10101'*10).union(FrozenBitset('01010'*10)))==set(FrozenBitset('10101'*10)).union(FrozenBitset('01010'*10))
618
True
619
sage: set(FrozenBitset('10101').union(FrozenBitset('01010'*20)))==set(FrozenBitset('10101')).union(FrozenBitset('01010'*20))
620
True
621
sage: set(FrozenBitset('10101'*20).union(FrozenBitset('01010')))==set(FrozenBitset('10101'*20)).union(FrozenBitset('01010'))
622
True
623
"""
624
return self._union(other)
625
626
def __or__(self, FrozenBitset other not None):
627
"""
628
Return the union of self and other.
629
630
EXAMPLES::
631
632
sage: FrozenBitset('10101') | FrozenBitset('11100')
633
11101
634
sage: FrozenBitset('10101'*10) | FrozenBitset('01010'*10)
635
11111111111111111111111111111111111111111111111111
636
637
TESTS::
638
639
sage: set(FrozenBitset('10101'*10) | FrozenBitset('01010'*10))==set(FrozenBitset('10101'*10)) | set(FrozenBitset('01010'*10))
640
True
641
sage: set(FrozenBitset('10101') | FrozenBitset('01010'*20))==set(FrozenBitset('10101')) | set(FrozenBitset('01010'*20))
642
True
643
sage: set(FrozenBitset('10101'*20) | FrozenBitset('01010'))==set(FrozenBitset('10101'*20)) | set(FrozenBitset('01010'))
644
True
645
"""
646
return self._union(other)
647
648
cpdef intersection(self, FrozenBitset other):
649
"""
650
Return the intersection of self and other.
651
652
EXAMPLES::
653
654
sage: FrozenBitset('10101').intersection(FrozenBitset('11100'))
655
10100
656
sage: FrozenBitset('11111'*10).intersection(FrozenBitset('010101'*10))
657
010101010101010101010101010101010101010101010101010000000000
658
659
TESTS::
660
661
sage: set(FrozenBitset('11111'*10).intersection(FrozenBitset('010101'*10)))==set(FrozenBitset('11111'*10)).intersection(FrozenBitset('010101'*10))
662
True
663
sage: set(FrozenBitset('1'*5).intersection(FrozenBitset('01010'*20)))==set(FrozenBitset('1'*5)).intersection(FrozenBitset('01010'*20))
664
True
665
sage: set(FrozenBitset('10101'*20).intersection(FrozenBitset('1'*5)))==set(FrozenBitset('10101'*20)).intersection(FrozenBitset('1'*5))
666
True
667
"""
668
if other is None:
669
raise ValueError, "other can not be None"
670
cdef FrozenBitset temp, smaller, larger
671
if self._bitset.size <= other._bitset.size:
672
smaller = self
673
larger = other
674
else:
675
smaller = other
676
larger = self
677
678
temp = self._new(smaller._bitset.size)
679
bitset_copy(temp._bitset, smaller._bitset)
680
bitset_realloc(temp._bitset, larger._bitset.size)
681
bitset_intersection(temp._bitset, temp._bitset, larger._bitset)
682
return temp
683
684
def __and__(self, FrozenBitset other not None):
685
"""
686
Return the intersection of self and other.
687
688
EXAMPLES::
689
690
sage: FrozenBitset('10101') & FrozenBitset('11100')
691
10100
692
sage: FrozenBitset('11111'*10) & FrozenBitset('010101'*10)
693
010101010101010101010101010101010101010101010101010000000000
694
695
TESTS::
696
697
sage: set(FrozenBitset('11111'*10) & FrozenBitset('010101'*10))==set(FrozenBitset('11111'*10)) & set(FrozenBitset('010101'*10))
698
True
699
sage: set(FrozenBitset('1'*5) & FrozenBitset('01010'*20))==set(FrozenBitset('1'*5)) & set(FrozenBitset('01010'*20))
700
True
701
sage: set(FrozenBitset('10101'*20) & FrozenBitset('1'*5))==set(FrozenBitset('10101'*20)) & set(FrozenBitset('1'*5))
702
True
703
"""
704
return self.intersection(other)
705
706
cpdef difference(self, FrozenBitset other):
707
"""
708
Return the difference of self and other.
709
710
EXAMPLES::
711
712
sage: FrozenBitset('10101').difference(FrozenBitset('11100'))
713
00001
714
sage: FrozenBitset('11111'*10).difference(FrozenBitset('010101'*10))
715
101010101010101010101010101010101010101010101010100000000000
716
717
TESTS::
718
719
sage: set(FrozenBitset('11111'*10).difference(FrozenBitset('010101'*10)))==set(FrozenBitset('11111'*10)).difference(FrozenBitset('010101'*10))
720
True
721
sage: set(FrozenBitset('1'*5).difference(FrozenBitset('01010'*20)))==set(FrozenBitset('1'*5)).difference(FrozenBitset('01010'*20))
722
True
723
sage: set(FrozenBitset('10101'*20).difference(FrozenBitset('1'*5)))==set(FrozenBitset('10101'*20)).difference(FrozenBitset('1'*5))
724
True
725
"""
726
if other is None:
727
raise ValueError, "other can not be None"
728
cdef FrozenBitset temp = self._new(self._bitset.size)
729
bitset_copy(temp._bitset, self._bitset)
730
731
if temp._bitset.size == other._bitset.size:
732
bitset_difference(temp._bitset, temp._bitset, other._bitset)
733
elif temp._bitset.size < other._bitset.size:
734
bitset_realloc(temp._bitset, other._bitset.size)
735
bitset_difference(temp._bitset, temp._bitset, other._bitset)
736
else:
737
bitset_difference(temp._bitset, temp._bitset, other._larger_capacity_(temp._bitset.size)._bitset)
738
739
return temp
740
741
def __sub__(self, FrozenBitset other not None):
742
"""
743
Return the difference of self and other.
744
745
EXAMPLES::
746
747
sage: FrozenBitset('10101') - FrozenBitset('11100')
748
00001
749
sage: FrozenBitset('11111'*10)-FrozenBitset('010101'*10)
750
101010101010101010101010101010101010101010101010100000000000
751
752
TESTS::
753
754
sage: set(FrozenBitset('11111'*10)-FrozenBitset('010101'*10))==set(FrozenBitset('11111'*10))-set(FrozenBitset('010101'*10))
755
True
756
sage: set(FrozenBitset('1'*5)-FrozenBitset('01010'*20))==set(FrozenBitset('1'*5))-set(FrozenBitset('01010'*20))
757
True
758
sage: set(FrozenBitset('10101'*20)-FrozenBitset('1'*5))==set(FrozenBitset('10101'*20))-set(FrozenBitset('1'*5))
759
True
760
"""
761
return self.difference(other)
762
763
cpdef symmetric_difference(self, FrozenBitset other):
764
"""
765
Return the symmetric difference of self and other.
766
767
EXAMPLES::
768
769
sage: FrozenBitset('10101').symmetric_difference(FrozenBitset('11100'))
770
01001
771
sage: FrozenBitset('11111'*10).symmetric_difference(FrozenBitset('010101'*10))
772
101010101010101010101010101010101010101010101010100101010101
773
774
TESTS::
775
776
sage: set(FrozenBitset('11111'*10).symmetric_difference(FrozenBitset('010101'*10)))==set(FrozenBitset('11111'*10)).symmetric_difference(FrozenBitset('010101'*10))
777
True
778
sage: set(FrozenBitset('1'*5).symmetric_difference(FrozenBitset('01010'*20)))==set(FrozenBitset('1'*5)).symmetric_difference(FrozenBitset('01010'*20))
779
True
780
sage: set(FrozenBitset('10101'*20).symmetric_difference(FrozenBitset('1'*5)))==set(FrozenBitset('10101'*20)).symmetric_difference(FrozenBitset('1'*5))
781
True
782
"""
783
if other is None:
784
raise ValueError, "other can not be None"
785
cdef FrozenBitset temp, smaller, larger
786
if self._bitset.size <= other._bitset.size:
787
smaller = self
788
larger = other
789
else:
790
smaller = other
791
larger = self
792
793
temp = self._new(smaller._bitset.size)
794
bitset_copy(temp._bitset, smaller._bitset)
795
bitset_realloc(temp._bitset, larger._bitset.size)
796
bitset_symmetric_difference(temp._bitset, temp._bitset, larger._bitset)
797
return temp
798
799
def __xor__(self, FrozenBitset other not None):
800
"""
801
Return the symmetric difference of self and other.
802
803
Note that because of the Sage preprocessor, in Sage, ``^^`` is the exclusive or, rather than ``^``.
804
805
EXAMPLES::
806
807
sage: FrozenBitset('10101') ^^ FrozenBitset('11100')
808
01001
809
sage: FrozenBitset('11111'*10) ^^ FrozenBitset('010101'*10)
810
101010101010101010101010101010101010101010101010100101010101
811
812
TESTS::
813
814
sage: set(FrozenBitset('11111'*10) ^^ FrozenBitset('010101'*10))==set(FrozenBitset('11111'*10)) ^^ set(FrozenBitset('010101'*10))
815
True
816
sage: set(FrozenBitset('1'*5) ^^ FrozenBitset('01010'*20))==set(FrozenBitset('1'*5)) ^^ set(FrozenBitset('01010'*20))
817
True
818
sage: set(FrozenBitset('10101'*20) ^^ FrozenBitset('1'*5))==set(FrozenBitset('10101'*20)) ^^ set(FrozenBitset('1'*5))
819
True
820
"""
821
return self.symmetric_difference(other)
822
823
cpdef __copy__(self):
824
"""
825
Return self (since self is immutable).
826
827
EXAMPLES::
828
829
sage: a=FrozenBitset('10101')
830
sage: from copy import copy
831
sage: b=copy(a)
832
sage: b is a
833
True
834
sage: c=FrozenBitset('1010'*32)
835
sage: d=copy(c)
836
sage: d is c
837
True
838
"""
839
return self
840
841
cdef class Bitset(FrozenBitset):
842
"""
843
A bitset class which leverages inline Cython functions for creating
844
and manipulating bitsets.
845
846
A bitset can be thought of in two ways. First, as a set of
847
elements from the universe of the `n` natural numbers `0`, `1`,
848
..., `n-1` (where `n`, the capacity, can be specified), with
849
typical set operations (intersection, union, symmetric difference,
850
etc.). Secondly, a bitset can be thought of as a binary vector
851
with typical binary operations (i.e., ``and``, ``or``, ``xor``,
852
etc.). This class supports both interfaces.
853
854
The interface in this class mirrors the interface in the ``set``
855
datatype of Python.
856
857
.. warning::
858
859
This class is most likely to be useful as a way to store
860
Cython bitsets in Python datastructures, acting on them using
861
the Cython inline functions. If you want to use this class
862
for a Python set type, the Python ``set`` data type may be
863
faster.
864
865
866
EXAMPLES::
867
868
sage: a=Bitset('1101')
869
sage: loads(dumps(a))==a
870
True
871
sage: a=Bitset('1101'*32)
872
sage: loads(dumps(a))==a
873
True
874
"""
875
876
cpdef __copy__(self):
877
"""
878
Return a copy of self.
879
880
EXAMPLES::
881
882
sage: a=Bitset('10101')
883
sage: from copy import copy
884
sage: b=copy(a)
885
sage: b is a
886
False
887
sage: b==a
888
True
889
sage: c=Bitset('1010'*32)
890
sage: d=copy(c)
891
sage: d is c
892
False
893
sage: d==c
894
True
895
896
"""
897
cdef FrozenBitset temp = self._new(self._bitset.size)
898
bitset_copy(temp._bitset, self._bitset)
899
return temp
900
901
def __hash__(self):
902
"""
903
Raise an error, since mutable Bitsets are not hashable.
904
905
EXAMPLE::
906
907
sage: hash(Bitset('110'))
908
Traceback (most recent call last):
909
...
910
TypeError: Bitset objects are unhashable; use FrozenBitset
911
912
"""
913
raise TypeError, "Bitset objects are unhashable; use FrozenBitset"
914
915
916
def __richcmp__(FrozenBitset self, FrozenBitset other not None, int op):
917
"""
918
Implement comparisons, using the Cython richcmp convention.
919
Comparison is done by inclusion (a set is less than another if
920
it is a subset).
921
922
EXAMPLES::
923
924
sage: Bitset('11') < Bitset('101')
925
False
926
sage: Bitset('11') <= Bitset('110')
927
True
928
sage: Bitset('11') != Bitset('10')
929
True
930
sage: Bitset('11') == Bitset('10')
931
False
932
sage: Bitset('11') == Bitset('110')
933
True
934
sage: Bitset('11') > Bitset('10')
935
True
936
sage: Bitset('11') >= Bitset('10')
937
True
938
sage: FrozenBitset('11') < FrozenBitset('110'*32)
939
True
940
"""
941
cdef FrozenBitset left, right
942
943
if self._bitset.size == other._bitset.size:
944
left = self
945
right = other
946
elif self._bitset.size < other._bitset.size:
947
left = self._larger_capacity_(other._bitset.size)
948
right = other
949
else:
950
left = self
951
right = other._larger_capacity_(self._bitset.size)
952
953
if op == 2: # ==
954
return bitset_eq(left._bitset, right._bitset)
955
elif op == 3: # !=
956
return not bitset_eq(left._bitset, right._bitset)
957
elif op == 0: # <
958
return bitset_issubset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
959
elif op == 1: # <=
960
return bitset_issubset(left._bitset, right._bitset)
961
elif op == 4: # >
962
return bitset_issuperset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
963
elif op == 5: # >=
964
return bitset_issuperset(left._bitset, right._bitset)
965
966
967
cdef FrozenBitset _new(self,long int capacity):
968
"""
969
Return an object of the same type as self, initialized with a bitset of capacity ``capacity``.
970
971
"""
972
cdef Bitset b
973
b = Bitset.__new__(Bitset,None, capacity)
974
return b
975
976
977
cpdef update(self, FrozenBitset other):
978
"""
979
Update the bitset to include items in other.
980
981
EXAMPLES::
982
983
sage: a = Bitset('110')
984
sage: a.update(Bitset('0101'))
985
sage: a
986
1101
987
sage: a_set = set(a)
988
sage: a.update(Bitset('00011'*25))
989
sage: a
990
11011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011
991
sage: a_set.update(Bitset('00011'*25))
992
sage: set(a)==a_set
993
True
994
"""
995
if other is None:
996
raise TypeError, "other can not be None"
997
cdef bitset_t temp
998
if self._bitset.size == other._bitset.size:
999
bitset_union(self._bitset, self._bitset, other._bitset)
1000
elif self._bitset.size < other._bitset.size:
1001
bitset_realloc(self._bitset, other._bitset.size)
1002
bitset_union(self._bitset, self._bitset, other._bitset)
1003
else:
1004
bitset_init(temp, other._bitset.size)
1005
bitset_copy(temp, other._bitset)
1006
bitset_realloc(temp, self._bitset.size)
1007
bitset_union(self._bitset, self._bitset, temp)
1008
bitset_free(temp)
1009
1010
def __ior__(self, FrozenBitset other not None):
1011
"""
1012
Update the bitset to include items in other.
1013
1014
EXAMPLES::
1015
1016
sage: a = Bitset('110')
1017
sage: a |= Bitset('0101')
1018
sage: a
1019
1101
1020
sage: a_set = set(a)
1021
sage: a |= Bitset('00011'*25)
1022
sage: a
1023
11011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011
1024
sage: a_set |= set(Bitset('00011'*25))
1025
sage: set(a)==a_set
1026
True
1027
"""
1028
self.update(other)
1029
return self
1030
1031
cpdef intersection_update(self, FrozenBitset other):
1032
"""
1033
Update the bitset to the intersection of self and other.
1034
1035
EXAMPLES::
1036
1037
sage: a = Bitset('110')
1038
sage: a.intersection_update(Bitset('0101'))
1039
sage: a
1040
0100
1041
sage: a_set = set(a)
1042
sage: a.intersection_update(Bitset('0110'*25))
1043
sage: a
1044
0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1045
sage: a_set.intersection_update(Bitset('0110'*25))
1046
sage: set(a)==a_set
1047
True
1048
"""
1049
if other is None:
1050
raise TypeError, "other can not be None"
1051
cdef bitset_t temp
1052
if self._bitset.size == other._bitset.size:
1053
bitset_intersection(self._bitset, self._bitset, other._bitset)
1054
elif self._bitset.size < other._bitset.size:
1055
bitset_realloc(self._bitset, other._bitset.size)
1056
bitset_intersection(self._bitset, self._bitset, other._bitset)
1057
else:
1058
bitset_init(temp, other._bitset.size)
1059
bitset_copy(temp, other._bitset)
1060
bitset_realloc(temp, self._bitset.size)
1061
bitset_intersection(self._bitset, self._bitset, temp)
1062
bitset_free(temp)
1063
1064
def __iand__(self, FrozenBitset other not None):
1065
"""
1066
Update the bitset to the intersection of self and other.
1067
1068
EXAMPLES::
1069
1070
sage: a = Bitset('110')
1071
sage: a &= Bitset('0101')
1072
sage: a
1073
0100
1074
sage: a_set = set(a)
1075
sage: a &= Bitset('0110'*25)
1076
sage: a
1077
0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1078
sage: a_set &= set(Bitset('0110'*25))
1079
sage: a_set==set(a)
1080
True
1081
"""
1082
self.intersection_update(other)
1083
return self
1084
1085
cpdef difference_update(self, FrozenBitset other):
1086
"""
1087
Update the bitset to the difference of self and other.
1088
1089
EXAMPLES::
1090
1091
sage: a = Bitset('110')
1092
sage: a.difference_update(Bitset('0101'))
1093
sage: a
1094
1000
1095
sage: a_set=set(a)
1096
sage: a.difference_update(FrozenBitset('010101'*10)); a
1097
100000000000000000000000000000000000000000000000000000000000
1098
sage: a_set.difference_update(FrozenBitset('010101'*10))
1099
sage: a_set==set(a)
1100
True
1101
sage: a.difference_update(FrozenBitset('110'))
1102
sage: a_set.difference_update(FrozenBitset('110'))
1103
sage: a_set==set(a)
1104
True
1105
sage: a.difference_update(FrozenBitset('01010'*20)); a
1106
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1107
sage: a_set.difference_update(FrozenBitset('01010'*20))
1108
sage: a_set==set(a)
1109
True
1110
sage: b=Bitset('10101'*20)
1111
sage: b_set=set(b)
1112
sage: b.difference_update(FrozenBitset('1'*5)); b
1113
0000010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1114
sage: b_set.difference_update(FrozenBitset('1'*5))
1115
sage: b_set==set(b)
1116
True
1117
"""
1118
if other is None:
1119
raise TypeError, "other can not be None"
1120
cdef bitset_t temp
1121
if self._bitset.size == other._bitset.size:
1122
bitset_difference(self._bitset, self._bitset, other._bitset)
1123
elif self._bitset.size < other._bitset.size:
1124
bitset_realloc(self._bitset, other._bitset.size)
1125
bitset_difference(self._bitset, self._bitset, other._bitset)
1126
else:
1127
bitset_init(temp, other._bitset.size)
1128
bitset_copy(temp, other._bitset)
1129
bitset_realloc(temp, self._bitset.size)
1130
bitset_difference(self._bitset, self._bitset, temp)
1131
bitset_free(temp)
1132
1133
def __isub__(self, FrozenBitset other not None):
1134
"""
1135
Update the bitset to the difference of self and other.
1136
1137
EXAMPLES::
1138
1139
sage: a = Bitset('110')
1140
sage: a -= Bitset('0101')
1141
sage: a
1142
1000
1143
sage: a_set=set(a)
1144
sage: a-=FrozenBitset('010101'*10); a
1145
100000000000000000000000000000000000000000000000000000000000
1146
sage: a_set-=set(FrozenBitset('010101'*10))
1147
sage: a_set==set(a)
1148
True
1149
sage: a=Bitset('110')
1150
sage: a_set=set(a)
1151
sage: a-=FrozenBitset('01010'*20); a
1152
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1153
sage: a_set-=set(FrozenBitset('01010'*20))
1154
sage: a_set==set(a)
1155
True
1156
sage: b=FrozenBitset('10101'*20)
1157
sage: b_set = set(b)
1158
sage: b -= FrozenBitset('1'*5); b
1159
0000010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1160
sage: b_set -= FrozenBitset('1'*5)
1161
sage: b_set==set(b)
1162
True
1163
"""
1164
self.difference_update(other)
1165
return self
1166
1167
cpdef symmetric_difference_update(self, FrozenBitset other):
1168
"""
1169
Update the bitset to the symmetric difference of self and other.
1170
1171
EXAMPLES::
1172
1173
sage: a = Bitset('110')
1174
sage: a.symmetric_difference_update(Bitset('0101'))
1175
sage: a
1176
1001
1177
sage: a_set=set(a)
1178
sage: a.symmetric_difference_update(FrozenBitset('010101'*10)); a
1179
110001010101010101010101010101010101010101010101010101010101
1180
sage: a_set.symmetric_difference_update(FrozenBitset('010101'*10))
1181
sage: a_set==set(a)
1182
True
1183
sage: a.symmetric_difference_update(FrozenBitset('01010'*20)); a
1184
1001011111000001111100000111110000011111000001111100000111110101001010010100101001010010100101001010
1185
sage: a_set.symmetric_difference_update(FrozenBitset('01010'*20))
1186
sage: a_set==set(a)
1187
True
1188
sage: b=Bitset('10101'*20)
1189
sage: b_set=set(b)
1190
sage: b.symmetric_difference_update( FrozenBitset('1'*5)); b
1191
0101010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1192
sage: b_set.symmetric_difference_update( FrozenBitset('1'*5))
1193
sage: b_set==set(b)
1194
True
1195
"""
1196
if other is None:
1197
raise TypeError, "other can not be None"
1198
cdef bitset_t temp
1199
if self._bitset.size == other._bitset.size:
1200
bitset_symmetric_difference(self._bitset, self._bitset, other._bitset)
1201
elif self._bitset.size < other._bitset.size:
1202
bitset_realloc(self._bitset, other._bitset.size)
1203
bitset_symmetric_difference(self._bitset, self._bitset, other._bitset)
1204
else:
1205
bitset_init(temp, other._bitset.size)
1206
bitset_copy(temp, other._bitset)
1207
bitset_realloc(temp, self._bitset.size)
1208
bitset_symmetric_difference(self._bitset, self._bitset, temp)
1209
bitset_free(temp)
1210
1211
def __ixor__(self, FrozenBitset other not None):
1212
"""
1213
Update the bitset to the symmetric difference of self and other.
1214
1215
EXAMPLES::
1216
1217
sage: a = Bitset('110')
1218
sage: a ^^=Bitset('0101')
1219
sage: a
1220
1001
1221
sage: a_set=set(a)
1222
sage: a ^^=FrozenBitset('010101'*10); a
1223
110001010101010101010101010101010101010101010101010101010101
1224
sage: a_set ^^=set(FrozenBitset('010101'*10))
1225
sage: a_set==set(a)
1226
True
1227
sage: a ^^=FrozenBitset('01010'*20); a
1228
1001011111000001111100000111110000011111000001111100000111110101001010010100101001010010100101001010
1229
sage: a_set ^^=set(FrozenBitset('01010'*20))
1230
sage: a_set==set(a)
1231
True
1232
sage: b=Bitset('10101'*20)
1233
sage: b_set=set(b)
1234
sage: b ^^=FrozenBitset('1'*5); b
1235
0101010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1236
sage: b_set ^^=set(FrozenBitset('1'*5))
1237
sage: b_set==set(b)
1238
True
1239
"""
1240
self.symmetric_difference_update(other)
1241
return self
1242
1243
cpdef add(self, unsigned long n):
1244
"""
1245
Update the bitset by adding `n`.
1246
1247
EXAMPLES::
1248
1249
sage: a = Bitset('110')
1250
sage: a.add(5)
1251
sage: a
1252
110001
1253
sage: a.add(100)
1254
sage: sorted(list(a))
1255
[0, 1, 5, 100]
1256
sage: a.capacity()
1257
101
1258
"""
1259
if n >= self._bitset.size:
1260
bitset_realloc(self._bitset, n+1)
1261
bitset_add(self._bitset, n)
1262
1263
cpdef remove(self, unsigned long n):
1264
"""
1265
Update the bitset by removing `n`. Raises KeyError if `n` is
1266
not contained in the bitset.
1267
1268
EXAMPLES::
1269
1270
sage: a = Bitset('110')
1271
sage: a.remove(1)
1272
sage: a
1273
100
1274
sage: a.remove(2)
1275
Traceback (most recent call last):
1276
...
1277
KeyError: 2L
1278
sage: a.remove(4)
1279
Traceback (most recent call last):
1280
...
1281
KeyError: 4L
1282
sage: a
1283
100
1284
sage: a=Bitset('000001'*15); sorted(list(a))
1285
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89]
1286
sage: a.remove(83); sorted(list(a))
1287
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 89]
1288
"""
1289
if n >= self._bitset.size:
1290
raise KeyError, n
1291
else:
1292
bitset_remove(self._bitset, n)
1293
1294
cpdef discard(self, unsigned long n):
1295
"""
1296
Update the bitset by removing `n`.
1297
1298
EXAMPLES::
1299
1300
sage: a = Bitset('110')
1301
sage: a.discard(1)
1302
sage: a
1303
100
1304
sage: a.discard(2)
1305
sage: a.discard(4)
1306
sage: a
1307
100
1308
sage: a=Bitset('000001'*15); sorted(list(a))
1309
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89]
1310
sage: a.discard(83); sorted(list(a))
1311
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 89]
1312
sage: a.discard(82); sorted(list(a))
1313
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 89]
1314
"""
1315
if n < self._bitset.size:
1316
bitset_discard(self._bitset, n)
1317
1318
1319
cpdef pop(self):
1320
"""
1321
Remove and return an arbitrary element from the set. Raises
1322
KeyError if the set is empty.
1323
1324
EXAMPLES::
1325
1326
sage: a = Bitset('011')
1327
sage: a.pop()
1328
1
1329
sage: a
1330
001
1331
sage: a.pop()
1332
2
1333
sage: a
1334
000
1335
sage: a.pop()
1336
Traceback (most recent call last):
1337
...
1338
KeyError: 'pop from an empty set'
1339
sage: a = Bitset('0001'*32)
1340
sage: a.pop()
1341
3
1342
sage: [a.pop() for _ in range(20)]
1343
[7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71, 75, 79, 83]
1344
"""
1345
return bitset_pop(self._bitset)
1346
1347
1348
cpdef clear(self):
1349
"""
1350
Removes all elements from the set
1351
1352
EXAMPLES::
1353
1354
sage: a = Bitset('011')
1355
sage: a.clear()
1356
sage: a
1357
000
1358
sage: a = Bitset('011'*32)
1359
sage: a.clear()
1360
sage: set(a)
1361
set([])
1362
"""
1363
bitset_clear(self._bitset)
1364
1365